When an error is rendered for a non-radio button, I see this:
<div id="div_id_field_a" class="control-group error">
<label for="id_field_a" class="control-label ">Field A</label>
<div class="controls">
<select class="select" id="id_field_a" name="field_a">
<option value="" selected="selected"></option>
<option value="0">0</option>
<option value="1">1</option>
</select>
<span id="error_1_id_field_a" class="help-inline"><strong>Select one</strong></span>
</div>
</div>
When an error is rendered for a radio button, I see this:
<div id="div_id_field_b" class="control-group error">
<label for="id_field_b_0" class="control-label ">Field b</label>
<div class="controls">
<p id="error_1_id_field_b" class="help-block"><strong>Enter a value</strong></p>
<label class="radio"><input type="radio" name="field_b" id="id_field_b_1" value="True">Yes</label>
<label class="radio"> <input type="radio" name="field_b" id="id_field_b_2" value="False">No</label>
</div>
</div>
How can I get the error message to appear after the radio button controls, which is what happens when a combo box used? Or at least not render the error inside a p tag and instead a span tag?
Here's how I render the form:
{% load crispy_forms_tags %}
<form id='main-form'>
{% csrf_token %}
{% crispy form form.helper %}
</form>
and the form:
class MyForm(ReoBaseForm):
field_b = forms.ChoiceField(required=False, choices=((True, 'Yes'), (False, 'No')),
label='Field b', widget=forms.RadioSelect())
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
Related
I am working on a project and have ran into an issue with my forms. In particular, I want the form to use Bootstrap4 (from CDN) elements, yet when I try to use the widgets feature of ModelForm, it isn't working quite right
forms.py:
class Meta(object):
model = ScheduleItem
fields = (
'name',
'time_start',
'time_end',
'day',
)
widgets = {
'name': forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': 'test'
}
),
'time_start': forms.TimeInput(
attrs={
'class': "form-control"
}
)
}
def __init__(self, *args, **kwargs):
super(ScheduleItemForm, self).__init__(*args, **kwargs)
self.fields['name'].label = ""
self.fields['time_start'].label = ""
self.fields['time_end'].label = ""
self.fields['day'].label = ""
html page: (The first two are ones using the form and the latter are not using it)
<form action="" method="POST">
{% csrf_token %}
<div class="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">Description</label>
{{schedule_item_form.name|as_crispy_field}}
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">Start Time</label>
{{schedule_item_form.time_start|as_crispy_field}}
{% comment %} <input type="time" class="form-control" aria-label="Username" name="start_time" required> {% endcomment %}
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">End Time</label>
<input type="time" class="form-control" aria-label="Username" name="end_time" required>
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">Day of the Week</label>
<select class="form-select" id="inputGroupSelect01">
<option selected>Choose...</option>
<option value="0">Monday</option>
<option value="1">Tuesday</option>
<option value="2">Wednesday</option>
<option value="3">Thursday</option>
<option value="4">Friday</option>
<option value="5">Saturday</option>
<option value="6">Sunday</option>
</select>
</div>
<button type="submit" class="btn btn-primary mb-2 mt-2">Add item to schedule</button>
</form>
Output:
HTML Output
Preferably, I would like all the inputs to look akin to the bottom two. Why does my form look so wacky? Thank you!
What I did to fix this was remove the {{|as_crispy_field}} as it was clashing with the 'form-control' tag in the widgets in my form
I'm trying to implement CRUD operations in django, however, I'm stuck in the edit operation.
After passing the data to edit template I need to show the selected values of operating system dropdown list, how can I achieve that?
I utilized the manual rendering of django form with the following code in the template:
<div class="form-group row">
<label class="col-sm-3 col-form-label">Operating System</label>
<div class="col-sm-9">
<select class="form-control" name="os_id" id="os_id" required>
<option value="">--Select--</option>
{% for os in os %}
<option value="{{ os.id}}">{{ os.key_name}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Title</label>
<div class="col-sm-9">
<textarea class="form-control" id="title" name="title" rows="3" required>{{ servicedesk.title }}</textarea>
</div>
</div>
here's the view code:
def edit(request, id):
servicedesk=Servicedesk.objects.get(id=id)
softwares=Software.objects.all
os=OperatingSystem.objects.all
context = {'servicedesk':servicedesk, "softwares":softwares, "os":os}
return render(request, 'servicedesks/edit.html', context)
and the model:
class OperatingSystem(models.Model):
key_name = models.CharField(max_length=100,null=True)
key_description = models.CharField(max_length=255,null=True)
class Meta:
db_table = "operating_systems"
def __str__(self):
return self.key_name
class Software(models.Model):
key_name = models.CharField(max_length=100,null=True)
key_description = models.CharField(max_length=255,null=True)
class Meta:
db_table = "softwares"
def __str__(self):
return self.key_name
class Servicedesk(models.Model):
os_id=models.ForeignKey(OperatingSystem, on_delete=models.SET(0))
software_id = models.ForeignKey(Software, on_delete=models.SET(0))
title = models.CharField(max_length=255,null=True)
I tried this but it's not working:
<div class="form-group row">
<label class="col-sm-3 col-form-label">Operating System {{os_id}}</label>
<div class="col-sm-9">
<select class="form-control" name="os_id" id="os_id" required>
<option value="">--Select--</option>
{% for os in os %}
{% if os.id == servicedesk.os_id %}
<option value="{{os.id}}" selected>{{os.key_name}}</option>
{% endif %}
<option value="{{ os.id}}">{{ os.key_name}}</option>
{% endfor %}
</select>
</div>
</div>
First, I want to generate a page that looks like this:
There are three things that makes it difficult.
1. Label + Input field set should line up horizontally
2. Some of the fields have checkbox
3. Date Field has a special Bootstrap plugin.
Here are the html source code for each types:
generic type:
<div class="col-lg-2 col-md-2 col-sm-4 col-xs-6" style="margin-bottom: 5px">
<label class="input-upper-title">Drill String Name</label>
<input type="text" id="" class="form-control input-field-height-vertical" name="" required="">
</div>
has checkbox:
<div class="col-lg-2 col-md-2 col-sm-4 col-xs-6" style="margin-bottom: 5px">
<label class="input-upper-title">String Length (ft)</label>
<div class="has-checkbox">
<input type="checkbox"><input disabled="disabled" type="text" id="" class="form-control input-field-height-vertical input-calculated" name="" data-parsley-trigger="" required="">
</div>
</div>
has date plugin:
<div class="col-lg-2 col-md-2 col-sm-4 col-xs-6" style="margin-bottom: 5px">
<label class="input-upper-title">Date Run</label>
<div class="form-group">
<div class="input-group date" id="datetimepicker7" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input input-field-height-vertical" data-target="#datetimepicker7"/>
<div class="input-group-append" data-target="#datetimepicker7" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
And here is my forms.py:
class BHA_overall_Form(forms.ModelForm):
prefix = 'bha_overall'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
class Meta():
model = BHA_overall
fields = '__all__'
How should I modify my forms.py, using crispy_forms to get the same effect as my html source code does?
It seems the FormHelper simply doesn't anything. Here's my Form:
class PerguntarForm(forms.Form):
title = forms.CharField(label='Título', max_length=200)
categoria = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label=None)
orcamento = forms.FloatField(label='Preço máximo')
def __init__(self, *args, **kwargs):
super(PerguntarForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.layout.append(Submit('save', 'save'))
self.helper.layout = Layout(
PrependedText('orcamento', ',00', active=True),
)
However, PrependedText isn't applied to the 'orcamento' field when rendered. The layout append doesn't either, which I placed just to see if something happened.
Here's the output:
<div id="div_id_title" class="form-group"><label for="id_title" class="control-label requiredField">
Título<span class="asteriskField">*</span></label><div class="controls "><input class="textinput textInput form-control" id="id_title" maxlength="200" name="title" type="text" /> </div></div><div id="div_id_categoria" class="form-group"><label for="id_categoria" class="control-label requiredField">
Categoria<span class="asteriskField">*</span></label><div class="controls "><select class="select form-control" id="id_categoria" name="categoria"><option value="4">Celular</option><option value="5">TV</option><option value="6">Computador</option></select></div></div><div id="div_id_orcamento" class="form-group"><label for="id_orcamento" class="control-label requiredField">
Preço máximo<span class="asteriskField">*</span></label><div class="controls "><input class="numberinput form-control" id="id_orcamento" name="orcamento" step="any" type="number" /> </div></div>
<input type="submit" value="Enviar" />
</form>
</div>
Make sure you are using the crispy form tag, not the crispy form filter.
{% load crispy_forms_tags %}
{% crispy form %}
Where form is the name of the form in the template.
I am using django-crispy-forms and Bootstrap 3 in my template rendering.
Here is how my form looks like:
As you can notice, the fields are not aligned correctly. I want them to be inline. please provide suggestions on how to fix this:
My crispy form code is below:
class SortFieldsForm(forms.Form):
latest_year=forms.BooleanField(label="latest year")
newest_entry=forms.BooleanField(label="newest post")
price_order=forms.ChoiceField(
widget=forms.RadioSelect,
label="price order",
choices=(('lowest_price','lowest '),('highest_price','highest'),),
initial="lowest_price",
)
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_class = 'form-inline'
self.helper.field_template='bootstrap3/layout/inline_field.html'
self.helper.form_method = 'post'
self.helper.form_action = '.'
super(SortFieldsForm, self).__init__(*args, **kwargs)
self.helper.layout = Layout(
InlineRadios('price_order'),
'newest_entry',
'latest_year',
Submit('submit', 'Submit', css_class='button white'),
)
And the generated HTML code:
<form action="." id="id-exampleForm" class="form-inline" method="post" >
<div id="div_id_price_order" class="form-group">
<label for="id_price_order" class="control-label requiredField">
price order
<span class="asteriskField">*</span>
</label>
<div class="controls ">
<label class="radio-inline">
<input type="radio" checked="checked" name="price_order" id="id_price_order_1" value="lowest_price" >lowest</label>
<label class="radio-inline">
<input type="radio" name="price_order" id="id_price_order_2" value="highest_price" >highest</label>
</div>
</div>
<div id="div_id_newest_entry" class="checkbox">
<label for="id_newest_entry" class=" requiredField">
<input class="checkboxinput checkbox" id="id_newest_entry" name="newest_entry" type="checkbox" />
newest post
</label>
</div>
<div id="div_id_latest_year" class="checkbox">
<label for="id_latest_year" class=" requiredField">
<input class="checkboxinput checkbox" id="id_latest_year" name="latest_year" type="checkbox" />
latest year
</label>
</div>
<input type="submit" name="submit" value="Submit" class="btn btn-primary button white" id="submit-id-submit"/>
</form>
This has nothing to do with crispy-forms itself, but rather that you have a label on the radio inputs that is pushing the actual inputs down. You need to add a margin-top style to div_id_newest_entry, submit-id-submit, and div_id_latest_year. For example (your use case may vary a bit), in your CSS file:
#div_id_newest_entry,
#div_id_latest_year,
#submit-id-submit {
margin-top: 25px;
}