Django-crispy-forms change radio button error rendering - django

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

Django Boostrap TimePicker/Forms not working

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

Django selected value using manual render form in django

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>

Django - how to modify crispy forms?

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?

crispy-form's Helper doesn't take effect

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.

field alignments in django crispy forms and bootstrap 3?

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;
}