I want to render the options for a ModelChoiceField:
{% for value, label in form.fields.event_type.choices %}
<option value="{{ value }}"
{% if form.fields.event_type.value == value %}selected="selected"{% endif %}>
{{ label }} -- {{ form.event_type.value }} .. {{ value }}
</option>
{% endfor %}
But this does not work: selected="selected" is not set.
The output:
<option value="">
--------- -- 2 ..
</option>
<option value="1">
OptionOne -- 2 .. 1
</option>
<option value="2">
OptionTwo -- 2 .. 2
</option>
This is strange, since the output "2 .. 2" did not trigger the "if" to include selected.
How to solve this?
I found the solution. The "if" was comparing an integer to a string, which is not equal.
This works:
{% for value, label in form.fields.event_type.choices %}
<option value="{{ value }}"
{% if form.event_type.value == value|stringformat:"i" %}selected="selected"{% endif %}>
{{ label }} -- {{ form.event_type.value }} .. {{ value }}
</option>
{% endfor %}
Related
Hi I have a dropdown like this
<select name="category" data-placeholder="select Category here" multiple
class="chosen-select" tabindex="8" required>
<option value=""></option>
<option>Transport</option>
<option>Accommodation</option>
<option>Ware House</option>
<option>Readymade</option>
</select>
And I am getting selected element of this dropdown from database Filter query like this
categories=Categories.objects.filter(vendor=uid)
when I for loop like this
{% for category in categories %}
<option value=""></option>
<option value="{{ category.category }}"{% if category.category == 'Transport' %}selected{% endif %}>Transport</option>
<option value="{{ category.category }}"{% if category.category == 'Accommodation' %}selected{% endif %}>Accommodation</option>
<option value="{{ category.category }}"{% if category.category == 'Activity' %}selected{% endif %} >Activity</option>
<option value="{{ category.category }}"{% if category.category == 'Readymade' %}selected{% endif %}>Pre Packaged Plan</option>
</option>
{% endfor %}
In this case For example If I have 2 options selected in database then it prints Options two time but seleted result is correct. Any help would be highly appreciated thanks.
If categories is a list of the categories you want to be selected, then you can make that a list (category_names = [category.category for category in categories]), and in your HTML, do not iterate over the categories (that would result in N times the categories), but rather check if each option was in the selected list:
<select ...>
<option value=""></option>
<option value="Transport" {% if 'Transport' in category_names %}selected{% endif %}>Transport</option>
<option value="Accommodation" {% if 'Accommodation' in category_names %}selected{% endif %}>Accommodation</option>
...etc
</select>
Now, if you need to populate this <select> with category names dynamically, that's another issue but it's not how I interpreted this question.
Here is my template code
<div class="form-group row">
<label for="{{ form.diagnosis.id_for_label }}" class="col-sm-4 col-form-label col-form-label-sm">{{ form.diagnosis.label }}</label>
<div class="col-sm-8">
<input type="text" class="form-control form-control-sm{% if form.diagnosis.errors %} is-invalid{% endif %}" id="{{ form.diagnosis.id_for_label }}" name="{{ form.diagnosis.html_name }}" value="{{ form.diagnosis.value }}" required>
{% if form.diagnosis.errors %}
<div class="invalid-feedback">
{% for error in form.diagnosis.errors %}
{{ error }}
{% endfor %}
</div>
{% elif form.diagnosis.help_text %}
<small class="form-text text-muted">
{{ form.diagnosis.help_text }}
</small>
{% endif %}
</div>
</div>
<div class="form-group row">
<label for="{{ form.assigned_employee.id_for_label }}" class="col-sm-4 col-form-label col-form-label-sm">{{ form.assigned_employee.label }}</label>
<div class="col-sm-8">
<select class="custom-select custom-select-sm{% if form.assigned_employee.errors %} is-invalid{% endif %}" id="{{ form.assigned_employee.id_for_label }}" name="{{ form.assigned_employee.html_name }}">
{% for id, name in form.fields.assigned_employee.choices %}
<option value="{{ id }}"{% if form.assigned_employee.value == id %} selected{% endif %}>{{ name }}</option>
{% endfor %}
</select>
{% if form.assigned_employee.errors %}
<div class="invalid-feedback">
{% for error in form.assigned_employee.errors %}
{{ error }}
{% endfor %}
</div>
{% elif form.assigned_employee.help_text %}
<small class="form-text text-muted">
{{ form.assigned_employee.help_text }}
</small>
{% endif %}
</div>
</div>
As you can see, I have created the form template manually and would like to keep it that way.
I can set the values of previously submitted fields using {{ form.field.value }}. But I can't do the same for the <select> fields.
I have tried to do so using the following
{% for id, name in form.fields.assigned_employee.choices %}
<option value="{{ id }}"{% if form.assigned_employee.value == id %} selected{% endif %}>{{ name }}</option>
{% endfor %}
. But it doesn't work except for when I set an initial value for the field like form = SomeForm(initial={'assigned_employee': 20180011})
The interesting thing is form.assigned_employee.value returns a value after submission. I have checked it using console.log({{ form.assigned_employee.value }}).
But the evaluation of the following condition {% if form.assigned_employee.value == id %} selected{% endif %} is always false.
Does anyone have a clue what's going on?
But the evaluation of the following condition {% if form.assigned_employee.value == id %} selected{% endif %} is always false.
That's because you forget to put fields; You should use {% if form.fields.assigned_employee.value == id %} not {% if form.assigned_employee.value == id %}:
{% for id, name in form.fields.assigned_employee.choices %}
<option value="{{ id }}"{% if form.fields.assigned_employee.value == id %} selected{% endif %}>{{ name }}</option>
{% endfor %}
Edit
As mentioned in the comments by #Daniel Roseman, if you want to convert int to string in the template, you can use:
{% for id, name in form.fields.assigned_employee.choices %}
<option value="{{ id }}"{% if form.assigned_employee.value == id|stringformat:"i" %} selected{% endif %}>{{ name }}</option>
{% endfor %}
I am having problem to get the selected data from a form. Here is my form
<form action="#" method="GET">
{% csrf_token %}
<select name="country" id="selectcountries" class="custom-select">
<option>Select country</option>
{% for item in countries %}
<option val="{{ item.name }}"> {{ item.name }} </option>
{% endfor %}
</select>
<select name ="city" id="selectcities" class="custom-select">
<option>Select city</option>
</select>
<select class="custom-select" name="option" >
<option selected> Tourist Spot </option>
<option> Hotel </option>
<option> Restaurent </option>
</select>
<button type="submit" class="btn tour-btn"><i class="fa fa-search pr-2" aria-hidden="true"></i> Search </button>
</form>
And my views.py is
def advanceSearch(request):
country = request.GET.get('country')
city = request.GET.get('city')
option = request.GET.get('option')
if request.method == "GET" :
if country:
message = 'q= %s' % country
else:
message = 'Empty'
else:
message = 'oops'
return HttpResponse(message)
HTTPResponse always give me empty message even after with passing values by the form. I want to get the data from this form but i cant.
I tried to replicate the scenario with the provided code, and I think your search view is not getting executed. You have provided {% url 'advanceSearch' %} in the anchor tag inside button. It should be in the action attribute of the form.
<form action="{% url 'advanceSearch' %}" method="GET">
{% csrf_token %}
<select name="country" id="selectcountries" class="custom-select">
<option>Select country</option>
{% for item in countries %}
<option val="{{ item.name }}"> {{ item.name }} </option>
{% endfor %}
</select>
<select name ="city" id="selectcities" class="custom-select">
<option>Select city</option>
</select>
<select class="custom-select" name="option" >
<option selected> Tourist Spot </option>
<option> Hotel </option>
<option> Restaurent </option>
</select>
<button type="submit" class="btn tour-btn"><i class="fa fa-search pr-2" aria-hidden="true"></i>Search</button>
</form>
How to access "value" in if condition? Or it's not possible in django tamplates?
Here is my example what I would like to be possible in django, but it doesn't work.
So I have problem with this row "{% if field.data == value %}" How to pass "value" from "for cycle" to if condition?
What is best solution for this?
template file
{% for field in form1 %}
<div class="row pad-col i-l">
{{ field.errors }}
<div class="col-sm-5 text-right">
<label for="{{ field.id_for_label }}">
{{ field.label }}
</label>
</div>
{% if field|field_type == 'Select' %}
<div class="col-sm-7 a-select">
<div class="a-m">
<select class="selectpicker add-i" id="{{ field.id_for_label }}" data-live-search="true" name="{{ field.name }}" tabindex="-98">
{% for value, key in field.field.choices %}
{% if field.data == value %}
<option value="{{ value }}" selected>{{ key }}</option>
{% else %}
<option value="{{ value }}">{{ key }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
{% else %}
<div class="col-sm-7">
{{ field }}
</div>
{% endif %}
</div>
{% endfor %}
views.py file
def add_item(request):
form1 = AddForm()
if request.method == 'POST':
form1 = AddForm(data=request.POST)
if form1.is_valid():
form1.save()
return HttpResponse('good')
return render(request, 'add_item.html', {'form1': form1})
Sorry guys. I just solved by myself. It was really stupid idea to customize that way forms when you can just add "widget=forms.Select(attrs={'class': 'selectpicker add-i', 'data-live-search': 'true'})" to your form field in forms.py file and all validation is working.
And than instead of this:
<select class="selectpicker add-i" id="{{ field.id_for_label }}" data-live-search="true" name="{{ field.name }}" tabindex="-98">
{% for value, key in field.field.choices %}
{% if field.data == value %}
<option value="{{ value }}" selected>{{ key }}</option>
{% else %}
<option value="{{ value }}">{{ key }}</option>
{% endif %}
{% endfor %}
</select>
you just write this:
{{ field }}
I think you should assign just one controlling var to the iteration, and then call the fields on it (assuming "value" and "key" are part of the field choices), like this:
{% for vfield in field.field.choices %}
{% if field.data == value %}
<option value="{{ vfield.value }}" selected>{{ vfield.key }}</option>
{% else %}
<option value="{{ vfield.value }}">{{ vfield.key }}</option>
{% endif %}
{% endfor %}
I have a select field in the form and now I need to iterate over options in this field.
{{ form.myselect }} gives me this:
<select name="myselect" id="id_myselect">
<option value="" selected="selected">---------</option>
<option value="2">Item 1</option>
<option value="3">Item 2</option>
...
</select>
Now I need to add some attributes to the options and because of that what I need is:
<select name="myselect" id="id_myselect">
{% for x in form.myselect %}
<option value="{{ x.id }}">{{ x.name }}</option>
{% endfor %}
</select>
but there is an error:
Caught TypeError while rendering: 'BoundField' object is not iterable
I tried form.myselect.all, form.myselect.option_set but it gives nothing
I've been struggling with this problem today and found the solution. Yes, you can iterate over options of the select tag directly in template. Here's how to do it in template:
<select id="id_customer" name="customer">
{% for x, y in form.fields.customer.choices %}
<option value="{{ x }}"{% if form.fields.customer.value == x %} selected{% endif %}>{{ y }}</option>
{% endfor %}
</select>
In this case I have a customer field in the form which has choices set up as follows:
class SomeForm(forms.Form):
customer = forms.ChoiceField(label=u'Customer')
def __init__(self, *args, **kwargs):
super(SomeForm, self).__init__(*args, **kwargs)
self.fields['customer'].choices = [(e.id, e.customer) for e in Customers.objects.all()]
Got it to work with:
<select name="myselect" class="i-can-add-my-own-attrs-now" id="id_myselect">
{% for id, name in form.myselect.field.choices %}
<option value="{{ id }}">{{ name }}</option>
{% endfor %}
</select>
BUT REALLY, a better way to do this is with django-widget-tweaks:
{% load widget_tweaks %}
{{ form.myselect|add_class:"i-can-haz-custom-classes-easily" }}
Doing it with django-widget-tweaks will also set the default 'selected="selected"' for you, which is super nice!
I do this way:
<select id="id_construction_type" name="construction_type" class="form-control input-md">
{% for value, key in form_urban.fields.construction_type.choices %}
<option value="{{ value }}"{% if form_urban.initial.construction_type == value %} selected {% endif %}>
{{ key }}
</option>
{% endfor %}
</select>
This is a cleaner solution, you can set the attributes using a custom Widget. This way you don't have to render the field manually:
class CustomSelectWidget(forms.Select):
def create_option(self, name, value, *args, **kwargs):
option = super().create_option(name, value, *args, **kwargs)
if value:
instance = self.choices.queryset.get(pk=value) # get instance
option['attrs']['custom_attr'] = instance.field_name # set option attribute
return option
class SomeForm(forms.ModelForm):
some_field = forms.ModelChoiceField(
queryset=SomeModel.objects.all(),
widget=CustomSelectWidget
)
With radio buttons in your template use.
<table>
{% for x,y in form.fields.Customer.choices %}
<tr>
<td><input id="id_Customer_{{x}}" {% if form.fields.Customer.value == x %}checked="checked"{% endif %} name="Customer" type="radio" value="{{x}}" /></td>
<td>{{ y }}</td>
</tr>
{% endfor %}
</table>