How should I add css classes to Flask wtform "labels" - flask-wtforms

I am experimenting with Flask and flask-user. The Registration template calls render_field() on a few items, one is email. for example, in my editied copy of registration.html there is:
{% if user_manager.USER_ENABLE_EMAIL %}
{{ render_field(form.email, tabindex=220) }}
{% endif %}
This yields:
<div class="form-group ">
<label for="email" class="control-label">Email</label>
<input class="form-control" id="email" name="email" required="" tabindex="220" type="text" value="">
</div>
How can I add classes to the label tag only?
I've looked at the wtforms code but if there is an answer in there it's not jumping out at me. I see what appears to be the kwargs passed to render_field being added to the input tag but I am not seeing anything touching the label.

I found this. I was looking for render_field in *.py files. I now see that it is defined in the _macros.html file in the flask_user/templates dir.

Related

How to style mixed django form better

I have theese two forms:
class InitialForm(Form):
trn = IntegerField(widget=NumberInput, required = False)
klient = ChoiceField(choices=KLIENTS, required = False)
class SecondForm(Form):
faktura = CharField(max_length = 200, required=False)
In the form I'm mixing django forms and pure html select (because I needed to pull out some data from a database)
<form method="POST" novalidate>
{% csrf_token %}
<label for="{{ form.klient.id_for_label }}">Klient: </label>
{{ form.klient }}
<br><br>
<label for="programs">Program: </label>
<select id="programselect" name="programs">
{% for option in options %}
<option value="{{ option.0}}">{{ option.1 }}</option>
{% endfor %}
</select>
<br><br>
<label for="{{ form.trn.id_for_label }}">Trn: </label>
{{ form.trn }}
<br><br>
<label for="{{ form2.faktura.id_for_label }}">Faktura: </label>
{{ form2.faktura }}
<br>
<button type="submit" class="btn btn-secondary">Search</button>
</form>
So far, I tried it with &nbsp& to have the inputs above each other.
How would you style it better with CSS?
Assuming you're using the crispy template pack for styling, you could create a model form class and give the programs field initial "options" from the database, using a query from whatever model you're storing the "options" on. Here's an example, using some assumptions about your database schema:
class ProgramForm(forms.ModelForm):
class Meta:
fields = ['program']
model = MyRecord
def __init__(self, *args, **kwargs):
super(ProgramForm, self).__init__(*args, **kwargs)
self.fields['program'].queryset = Option.objects.filter(some_field=True).order_by("option_name")
Using this kind of solution, you're using your backend model form class to handle passing the "option" data, and doing all your styling in the html with crispy. Note that if you're using two separate forms, pass them to your template with different names, like:
{{form.klient|as_crispy_field}}
{{program_form.program|as_crispy_field}}
Additionally, you can use Django's widgets to add functionality to your options selector, for example if you wanted checkboxes instead of a dropdown select (ForeignKey vs M2M, let's say).
If you can do none of that and must use this HTML structure and backend approach, you can still target the form with CSS, for example something like:
<style>
#this-label span {
margin-right: 100px;
}
</style>
<label for="{{ form.trn.id_for_label }}" id="this-label"> <span>Trn:</span> </label>
...will add space to the right of "Trn:". This is just one way of doing that, but you could add a class to the span element and target multiple such tags.

Split data from database column & view as string using Laravel

I have inserted multiple string in a column as an array in my database. They are separated by coma(,).
In the view page for route no 1 there are 3 stoppage points. Now I want to show them separately into different input fields. But they are shown into same filed as an array. So what should I do...?
<div class="col-md-4">
<div class="group">
<label>Stoppage Point</label>
<input type="text" value="{{ $allroute->stoppagePoint }}" name="stoppagePoint" class="input1 removeDis {{ $errors->has('stoppagePoint') ? ' is-invalid' : '' }}" disabled required>
#if ($errors->has('stoppagePoint'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('totalStoppage') }}</strong>
</span>
#endif
</div>
</div>
Do you want to execute it inside the blade template or do the logic in the controller
But i think the best way is to use the controller
You can use explode php function
$stoppages = explode(',',$points->stoppagePoints);
then this creates an array then you can append it to the view
#foreach (explode(',', $allroute->stoppagePoint) as $stoppagePoint)
<input type="text" value="{{ trim($stoppagePoint) }}" ...
#endforeach

Customize Django Form Style

how can i customize Django forms and set class for them ? for example i have a text box with bootstrap class and custom font :
<input type="text" class="form-control myfont" value="{{ model1.field1 }}"/>
but original form field " {{ form1.form_field1 }} " is a simple textbox with no style . i try to use this code :
<input type="text" class="form-control myfont" value="{{ form1.form_field1 }}"/>
this code didn't work . do you have suggestions ??
You can add extra attributes to widgets in form's __init__ method. If you many such forms, then you can have one super class form:
class BootstrapForm(forms.Form):
def __init__(self, *args, **kwargs):
super(BootstrapForm, self).__init__(*args, **kwargs)
for field_name in self.fields:
field = self.fields.get(field_name)
if field:
field.widget.attrs.update({
'class': "form-control myfont"
})
And then have your other forms extend this one.
If you want to inject extra attributes with the least resistance you can use django-tweaks.
Installation
$ pip install django-widget-tweaks
Then add ‘widget_tweaks’ to INSTALLED_APPS.
https://pypi.python.org/pypi/django-widget-tweaks
template.html
{% load widget_tweaks %}
{% render_field form1.form_field1 class="form-control myfont" %}

Add a css class to a field in wtform

I'm generating a dynamic form using wtforms (and flask). I'd like to add some custom css classes to the fields I'm generating, but so far I've been unable to do so. Using the answer I found here, I've attempted to use a custom widget to add this functionality. It is implemented in almost the exact same way as the answer on that question:
class ClassedWidgetMixin(object):
"""Adds the field's name as a class.
(when subclassed with any WTForms Field type).
"""
def __init__(self, *args, **kwargs):
print 'got to classed widget'
super(ClassedWidgetMixin, self).__init__(*args, **kwargs)
def __call__(self, field, **kwargs):
print 'got to call'
c = kwargs.pop('class', '') or kwargs.pop('class_', '')
# kwargs['class'] = u'%s %s' % (field.name, c)
kwargs['class'] = u'%s %s' % ('testclass', c)
return super(ClassedWidgetMixin, self).__call__(field, **kwargs)
class ClassedTextField(TextField, ClassedWidgetMixin):
print 'got to classed text field'
In the View, I do this to create the field (ClassedTextField is imported from forms, and f is an instance of the base form):
f.test_field = forms.ClassedTextField('Test Name')
The rest of the form is created correctly, but this jinja:
{{f.test_field}}
produces this output (no class):
<input id="test_field" name="test_field" type="text" value="">
Any tips would be great, thanks.
You actually don't need to go to the widget level to attach an HTML class attribute to the rendering of the field. You can simply specify it using the class_ parameter in the jinja template.
e.g.
{{ form.email(class_="form-control") }}
will result in the following HTML::
<input class="form-control" id="email" name="email" type="text" value="">
to do this dynamically, say, using the name of the form as the value of the HTML class attribute, you can do the following:
Jinja:
{{ form.email(class_="form-style-"+form.email.name) }}
Output:
<input class="form-style-email" id="email" name="email" type="text" value="">
For more information about injecting HTML attributes, check out the official documentation.
If you would like to programatically include the css class (or indeed, any other attributes) to the form field, then you can use the render_kw argument.
eg:
r_field = RadioField(
'Label',
choices=[(1,'Enabled'),(0,'Disabled')],
render_kw={'class':'myclass','style':'font-size:150%'}
)
will render as:
<ul class="myclass" id="r_field" style="font-size:150%">
<li><input id="r_field-0" name="r_field" type="radio" value="1"> <label for="r_field-0">Enabled</label></li>
<li><input id="r_field-1" name="r_field" type="radio" value="0"> <label for="r_field-1">Disabled</label></li>
</ul>
In WTForms 2.1 I using extra_classes, like the line bellow:
1. The first way
{{ f.render_form_field(form.email, extra_classes='ourClasses') }}
We can also use #John Go-Soco answers to use render_kw attribute on our form field, like this way.
2. The second way
style={'class': 'ourClasses', 'style': 'width:50%;'}
email = EmailField('Email',
validators=[InputRequired(), Length(1, 64), Email()],
render_kw=style)
But I would like more prefer to use the first way.
Pretty late though, but here is what I found. While rendering a template you can pass any key-value pairs inside the parenthesis, and it just puts those key values while rendering.
For example, if you had to put a class along with some placeholder text you can do it like below:
{{ form.email(class='custom-class' placeholder='email here') }}
will actually render like below:
<input class="custom-class" id="email" name="email" placeholder="email here" type="text" value="">
Basically, you can even try experimenting by adding some non-existent HTML attribute with some value and it gets rendered.
To make it a less of pain its good to have helper functions as macros and render them instead of actual fields directly.
Let's say you have common classes and error-classes.
You can have a helper macro like this:
{% macro render_field(field,cls,errcls) %}
{% if field.errors %}
<div class="form-group">
<label for="{{ field.id}}">{{ field.label.text }}</label>
{{ field(class = cls + " " + errcls,**kwargs) | safe}}
<div class="invalid-feedback">
{% for error in field.errors %}
<span> {{error}}</span>
{% endfor %}
</div>
</div>
{% else %}
<div class="form-group">
<label for="{{ field.id}}">{{ field.label.text }}</label>
{{ field(class = cls,**kwargs) | safe}}
</div>
{% endif %}
{% endmacro %}
Now while rendering a field you can call like this with additional attributes like this in the template:
{{render_field(form.email,cls="formcontrol",errcls="isinvalid",placeholder="Your Email") }}
Here I have used bootstrap classes, just modify the helper function to your needs!
Hope that helps! Happy coding!

Adding a CSS class to fields in django.contrib.auth.views.login

I'm still fairly new to django, and have come across Django forms for the first time through my use of the django.contrib.auth.views.login view, used when Django needs a user to authenticate.
I cannot however figure out how to add a CSS class to the username and password fields and the documentation doesn't specify how I can achieve it. Ideally I'd like to simply add the additional info to the template tag, such as {{ form.username | class="usernameclass" }} or whatever, or even write the field out manually, such as <input type="{{ form.password.type }}" name="{{ form.password.name }}" class="form-field-password"/>, but if I need to add a custom view to achieve this I can try that way.
The files related to this are below:
templates/login.html:
{% load url from future %}
...
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<span class="heading">{{ form.username.label_tag }}</span><br/>
{{ form.username }}<br/>
<span class="heading">{{ form.password.label_tag }}</span><br/>
{{ form.password }}<br/>
<div id="login-button">
<input type="submit" value="Log In" />
<input type="hidden" name="next" value="{{ next }}" />
</div>
</form>
...
settings.py:
...
LOGIN_URL = '/login/'
...
urls.py
...
urlpatterns = patterns('',
url(r'^$', 'portal.views.home', name='home'),
url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
url(r'^logout/$', 'django.contrib.auth.views.logout'),
...
)
Any advice is much appreciated!
This app will do exactly what you need.

Resources