Is there a way to specify the css for an individual field and input in django crispy forms? I am using bootstrap4 and would like to use a horizontal form for a few fields in my form.
I know you can use a self.helper to set label.class and field.class but I presume that applies to all field. I only want to change the label and field class on a few of my fields.
EDIT:
I need to add css to the label that is different from the input
I'm trying to get a horizontal field inside a form like the amount field below
<div id="div_id_amount" class="row">
<label for="id_amount" class="col-form-label col-2 requiredField">
Amount<span class="asteriskField">*</span>
</label>
<div class="">
<input type="number" name="amount" step="0.01" class="numberinput form-control col-md" required="" id="id_amount">
</div>
</div>
One solution is given here:
You add the class attributes for the input field via the widget, as also explained in the django docs
You explicitly add the <label> tags with the correct class in your HTML.
Or, for the label, you can also create the following template filter:
#register.filter(is_safe=True)
def label_with_classes(field, css):
return field.label_tag(attrs={'class': css})
which you can use like this in your template after you've loaded it with {% load my_filters %}: {{ form.name|label_with_classes:"col-sm-6 col-lg-3" }}
I don't know of an easy way with crispy-forms.
You can add this in your Layout:
Field('password', id="password-field", css_class="passwordfields", title="Explanation")
You can find more details here
Related
I am wanting to create a bootstrap themed togglebox with crispy forms, but the toggle box displays with a checkbox inside it.
In order to find out why I opened the page in Chrome and using inspect, deleted the class from the label tag (custom-control-label below) which removed the inner checkbox leaving just the bootstrap togglebox as I wanted.
So my question is how can I remove a class from a cripsy forms field?
forms.py
completed = forms.BooleanField(label='Have you completed it?', required=False, widget=forms.CheckboxInput(attrs={}))
generated html:
<div class="form-group">
<div id="div_id_completed" class="custom-control custom-checkbox">
<input type="checkbox" name="completed" class="checkboxinput custom-control-input"
id="id_completed" checked="">
<label for="id_completed" class="custom-control-label">
Have you completed it
</label>
</div>
</div>
Thank you.
I am trying to do the following with django widget tweaks:
{{ form.gender.0.tag|attr:"class:radio_1" }}
I get the error:
'SafeText' object has no attribute 'as_widget'
What am I doing wrong?
Initialize your RadioButton like this:
CHOICES=[('option1','option1'),
('option2','option2')]
radio = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect(attrs={'class': 'radio_1'}))
and the generated HTML-Code will look like this:
<input type="radio" class="radio_1" ... />
You may have figured out already how to apply CSS to radio buttons in Django template but in case someone is in the same situation, here's a code straight from the docs:
<fieldset>
<legend>{{ myform.beatles.label }}</legend>
{% for radio in myform.beatles %}
<div class="myradio">
{{ radio }}
</div>
{% endfor %}
</fieldset>
This code assumes you have a form myform with a field beatles that uses a RadioSelect as its widget.
As you can see, looping through the field beatles can allow you to add necessary classes (here class="myradio") for each radio button; hence, make your CSS styling possible and easier.
In your case, you might want to also loop through your gender field and then apply the appropriate classes.
I'm using django-crispy-forms with Bootstrap and I'm wanting to add some extra HTML inside the HTML rendered for the a single field.
For example if my form contains,
recipients = forms.CharField(label='To',widget=forms.TextInput(
attrs={'placeholder': 'Enter phone number, contact or group (add as many as you like)'}))
Then the normal rendering (using the Bootstrap templates) is,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
</div>
What I want to do is have some extra HTML appear just before the final closing div. So it would look like,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
<div class="controls-aside">
<button type="button" class="btn">Address Book</button>
<button type="button" class="btn">Add Contact</button>
</div>
</div>
I know that I can replace the existing template for this field with a custom template but I want to be able to re-use their template without doing a copy/paste since that makes it not very maintainable.
So what is the best way to implement this? I also want to add an extra class to the label if anyone can suggest how to do it?
For completeness, but not for your case: even after layout creation, Layout.wrap('recipients', Div) will work if one only needs to wrap a control into an additional Div.
About adding HTML inside the layout. Last hour I needed a very custom HTML, so did this:
(formatting)
i = self.helper.layout.fields.index('guest_email')
self.helper.layout.insert(
i+1,
HTML('{}'.format(
reverse_lazy('invite_guests'),
_('Invite to a party'))
))
I came here googling for a HTMLWrapper class example for Crispy Forms, so that I could do a prettier thing instead:
self.helper['guest_email'].wrap(HTMLWrapper(
'guest_email',
before='',
after='{}'.format(href, title))
If I end up creating one, I'll get back and post it.
For me it worked that way:
from crispy_forms.layout import Field, HTML
self.helper["some_field_name"].wrap(Field, HTML("<p>Example</p>"))
The benefit of using HTML is that it also gives you the possibility to use context variables.
I am using crispy_forms and FormHelper. I have a model field declared as:
active = models.BooleanField(default=True)
And in my ModelForm, I have tried both the following in my Layout:
self.helper.layout = Layout(
...
InlineCheckboxes('active'),
Field('active'),
...
which both not providing the desired result:
Please see image link
While using InlineCheckboxes, I do not see the checkbox and using only Field, it's not formatted correctly.
Please help
Here is the link to the "Bootstrap Layout objects" section of Crispy Forms docs.
InlineCheckboxes: It renders a Django forms.MultipleChoiceField field using inline checkboxes
InlineCheckboxes isn't appropriate for your model's field-type.
A hacky way to achieve what you're looking for is to use PrependedText with an empty string for the text argument.
...
PrependedText('active', ''),
...
Examining the source it appears that a boolean field by default renders the <input> tag inside the <label> tag. Using the hack above, 'Active' stays in the <label> and the <input> is put where you'd expect: in a <div> with "control" css class. Compare the following:
PrependedText('active', ''):
<div id="div_id_active" class="form-group">
<label for="id_active" class="control-label">Active</label>
<div class="controls">
<div class="input-group">
<input type="checkbox" name="active" class="checkboxinput" id="id_active" />
</div>
</div>
</div>
Field('active'):
<div class="form-group">
<div id="div_id_active" class="checkbox">
<div class="controls">
<label for="id_active" class=""><input type="checkbox" name="active" class=
"checkboxinput checkbox" id="id_active" /> Active</label>
</div>
</div>
</div>
Update
I've confirmed that this is fixed in the dev branch of django-crispy-forms.
Reference this commit: 5c3a268
And this github issue: #267
This is standard checkbox from model forms:
In my HTML I have: {{form}}
In website source:
<div class="id_accept-control-group control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" name="accept" id="id_accept" /> <span>Accept</span>
</label>
</div>
</div>
How to add custom attribute: disabled="disabled" checked="checked" (to input)?
Check out this question to point you in the right direction Django: How do I add arbitrary html attributes to input fields on a form?
Also take a look at the model forms django doc https://docs.djangoproject.com/en/dev/topics/forms/modelforms/