How to use Bootstrap tooltips with the Python WTForms library? - python

I'm building a website using the (awesome) Flask framework and the WTForms plugin. I now want to use show a Bootstrap tooltip on focus of an input field (working fiddle here), but for this I have to give the input tag the data-toggle and title attribute as follows:
<input data-toggle="tooltip" title="tooltip on focus!" type="text" placeholder="Focus me!" name="thename"/>
So I simply added them to the expression:
{{ form.plotting_value(title='tooltip on focus!', data-toggle='tooltip', class='form-control') }}
The title attribute is no problem, but the data-toggle causes a
TemplateSyntaxError: invalid syntax for function call expression
Does anybody know how I can add the data-toggle to the input field using WTForms?

Python doesn't like the hyphens, you can either give it a dictionary:
{{ form.example(**{'data-toggle': 'tooltip'}) }}
or, wtform's will helpfully decode an underscore to a hyphen:
{{ form.example(data_toggle: 'tooltip') }}

Related

How can I use Django intcomma in integerfield

I'd like to separate numerical values in the form with a comma in my Django project.
Then I found the documentation below:
https://docs.djangoproject.com/en/2.0/ref/contrib/humanize/
I thought that I can use 'intcomma' for my purpose. So I added "django.contrib.humanize" to my INSTALLED_APPS setting. And put {% load humanize %} in a template.
When I use 'intcomma' like below, it worked.
{{ 999999|intcomma }} # 999,999
But It did not work for integer form like below:
{{ form.numbers|intcomma }} # did not work.
A code was displayed to html instead of numbers like this:
<input type="number" name="int_sample" value="100000" id="id_int_sample"
My Django version is 2.0.1.
Formatting the value of an IntegerField
You access the value of an IntegerField with the .value attribute, so:
{{ form.numbers.value|intcomma }}
Note that this is the value set to the Form when you construct it. For example through initial={..} or the value that corresponds to the instance=... you pass to the field. If you for example in th form change the value, the content will not change.
Generating an <input> with number formatting
In case we want the <input> element itself to format the number separated with comma's, we will need some HTML/JavaScript. Since Django basically only renders a webpage. How the webpage behaves in the browser is not really the responsibility of Django.
We can for example use the following approach:
<script language="JavaScript">
function commas(input){
input.value = Number(input.value).toLocaleString();
}
</script>
{{ form.numbers }}
And the Form should then make sure the commas function is invoked:
SomeForm(forms.Form):
numbers = forms.IntegerField(
widget=forms.TextInput(attrs={'onclick':'commas(self)'})
)

Python Flask - What is the best way to conditionally display WTF fields based on prior responses?

I have a WTF form with several fields where I only want to display certain fields based on the responses to previous fields without refreshing the page. For example, say I have a field:
URLInd = BooleanField(u'Do you have a website?',validators=[DataRequired())
Which if checked, I want to display:
URL = TextField(u'Please enter your web address',validators=[DataRequired(), URL()])
So "URLInd" can be shown at the initial page load, but I only want "URL" shown if URLInd == True.
HTML:
<form class="form form-horizontal" method="post" role="form" enctype=multipart/form-data action>
{{ form.hidden_tag() }}
{{ wtf.form_errors(form, hiddens="only") }}
{{ wtf.form_field(form.URLInd) }}
{{ wtf.form_field(form.URL) }}
<button type="submit" class="btn btn-primary btn-lg btn-block">Submit</button>
</form>
Based on my research, I suspect I need to use Javascript and AJAX, but I have no experience using either and I haven't been able to apply any of the examples I've found to this problem. Thanks in advance for your help.
Field have arg message for replace default error message in defaults validators. For replace use kwargs message="u error message for view invalid this field"
Simple example
URLInd = BooleanField(u'Do you have a website?',validators=[URL(message="I want MY MESSAGE ERROR THIS FIELD")])

How can I include a "* required field." message in all forms with required fields?

I'm using django-crispy-forms with CRISPY_TEMPLATE_PACK = 'bootstrap3'. My templates looks like this (this is an example of the sign up form, but I have a lot of forms in my templates):
{% load crispy_forms_tags %}
<h1>Sign up</h1>
<form action="/accounts/signup/" method="POST" role="form">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Sing up</button>
</form>
In the rendered pages, the required fields appear correctly with an * near it to indicate that they are required, but no message appears explaining what an * means.
In my case, I'm dealing with users that are sometimes not very tech-firendly, so they might not know what an * means. I would like to show a * required field. message in the top of all forms with required fields.
I could put a <p>* required field.</p> line in the beginning of each form, but I would like to know if there is a more elegant and DRY way to do it.
Thank you!
You can override the uni_form.html template with a custom one.
https://github.com/maraujop/django-crispy-forms/blob/dev/crispy_forms/templates/bootstrap3/uni_form.html
According to the django crispy forms documentation:
https://django-crispy-forms.readthedocs.org/en/latest/crispy_tag_forms.html#change-required-fields
You will need to override the field template, that is your only option, unless you use a css hack (maybe something :before and :after for the asterisk element).
Your other option is to use the HTML crispy forms element, to make a notice at the top of your form:
HTML('<strong>Fields marked with * are required</strong>')
One solution would be to either add <p class="req_legend" style="display: none;">* required field.</p> to every form and add a js which changes its display property if required fields are found.
Here is a jquery example:
$(document).ready(function() {
if ($('.requiredField').length > 0) {
$('p.req_legend').show();
}
});
Or go full javascript and add <p> element to your only if you find a requiredField, you can than do this in a javascript that you add to the Media class of your forms

Django template question: how to output just the text if the variable has html in it?

I have a lot of variables that has html in them. For example the value of a variable called {{object.name}} is the following:
Play this hot game and see how <b>fun</b> it is!
Is there a filter that can be applied on the variable that will give me just the text:
Play this hot game and see how fun it is!
Without the text being linked or the html being replaced by htmlentities. Just the text?
striptags filter removes all html
{{object.name|striptags}}
You have 3 options to strip the html code:
Using "safe" filter in your template:
{{ object.name|safe }}
Using "autoescape" tag in your template:
{% autoescape off %}
{{ object.name }}
{% endautoescape %}
or declaring it as "safe" in your python code:
from django.utils.safestring import mark_safe
name = mark_safe(name)

WTForms... html, autofocus?

Is it possible to have some of the new attribute only attributes used in HTML5, inside of WTForms?
Eg, say you want to create a TextField with placeholder="foo", required, and autofocus attributes. How would this be done in WTForms?
In html it would look like this: <input maxlength="256" name="q" value="" placeholder="foo" autofocus required>
Note that placeholder="foo" is easily done in WTForms. autofocus and required, because they have no value, are .. well, as far as i've seen, not supported in WTForms.
Can WTForms support this?
In WTForms 1.0, released yesterday, HTML5 compact syntax is now the default. Now you can do (in jinja):
{{ form.field(autofocus=true, required=true, placeholder="foo") }}
Note that in Jinja, the literal is true instead of True but if you were to try this in the python console you will need to use the python literal True for this to work.
In WTForms 0.6.x, which used XHTML as the default output, you could do e.g.
{{ form.field(autofocus="autofocus", required="required", placeholder="foo" }}
This is the recommended way for representing boolean attributes in XHTML, and this happens to still be 100% valid HTML5 and completely equivalent, though the HTML generated is a bit more verbose.
I'm new with WTForms but it seems to me that the solution could be improved instead of using :
{{ form.field(autofocus=true, required=true, placeholder="foo") }}
use :
{% if field.flags.required %}
{{ field(autofocus=true, required=field.flags.required, placeholder="foo") }}
{% else %}
{{ field(autofocus=true, placeholder="foo") }}
{% endif %}
WTForms seems not to handle correctly required=false for 100% HTML5 and sets in the HTML an attr required="False" instead of removing the attr. Could this be improved in next version of WTForms?
You'll probably need to create a custom widget.
Check out the docs on custom widgets.

Categories

Resources