Set value of a select input to the value of last request in Django form template - django

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

Related

Django templates Could not parse the remainder

I have this template, I am looping through all choices in a question, and I want to default check the question user previously selected. selected_choice variable is coming from my view and I got have it ok in my template.
{% extends 'base.html' %}
{% block content %}
<div id="detail" class="">
<form hx-post="{% url 'main:vote' question.id %}" hx-trigger="submit" hx-target="#detail" hx-swap="outerHTML">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p>
<strong>{{ error_message }}</strong>
</p>
{% endif %}
{% for choice in question.choices.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" {% if selected_choice and choice.id==selected_choice %}checked{% endif %}>
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
</fieldset>
<button type="submit">Submit</button>
</form>
</div>
{% endblock content %}
I get this error
Could not parse the remainder: '==selected_choice' from 'choice.id==selected_choice'

Change signup field error message and field color

we are currently implementing a membership page. I hope the color of the field will be red if there is an error, but I don't know what to do. What should I add to my code so that it's possible?
<form method="post" class="post-form">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<input name="{{field.html_name }}" id="{{ field.id_for_lable }}" class="form-control" type="{{ field.field.widget.input_type }}" value="{{ field.value|default_if_none:'' }}"
placeholder="{{field.label}}">
{% for error in field.errors %}
<label class="control-label" for="{{ field.id_for_lable }}" style="color: #c13b2a;"><b>{{ error }}</b></label>
{% endfor %}
</div>
{% endfor %}
</div>
<div class="bbb" style="text-align: center">
<button type="submit">가입하기</button><br>
</div>
You can add stye if condition
<input ... {% if field.errors %} style={"color":"red"} {% endif %}>
or add a class if condition
<input ... class =".. {% if field.errors %} text-red {% endif %}">

How to add title without losing option selected in form select multiple ( django )

Done.
My implementation on edit:
<select name="course" required id="id_course" multiple>
{% for id, value in form.course.field.choices %}
<option title="{{value}}" value="{{ id }}" {% if id in form.course.value %} selected {% endif %}{% if id|slugify in form.course.value %} selected {% endif %}>{{ value }}</option>
{% endfor %}
</select>
and implementation on create new object:
<select name="course" required id="id_course" multiple>
{% for id, value in form.course.field.choices %}
<option title="{{value}}" value="{{ id }}" {% if id|slugify in form.course.value %} selected {% endif %}>{{ value }}</option>
{% endfor %}
</select>
*look type In the case of editing c form.course.value comes ['3', '4',] and when creating an object comes [3,4,]. id is always a number
Here are my models.py:
class Student(models.Model):
course = models.ManyToManyField(
CourseInstance)
Here are my views.py:
class StudentUpdate(UpdateView):
model = Student
fields = '__all__'
student_form.html:
<form action="" method="post" id = "group-form">
{% csrf_token %}
<table>
{% for field in form %}
<div class="row">
<div class="col-md-2">
{{ field.label_tag }}
{% if 'курсы:' in field.label_tag|lower %}
<div>
Добавить
</div>
{% endif %}
{{ field.errors }}
</div>
<div class="col-md-10 pull-left">
{% if 'курсы:' in field.label_tag|lower %}
{% comment %} {% load widget_tweaks %}
{% render_field field class="help-title-on" %} {% endcomment %}
<select name="course" required id="id_course" multiple>
{% with value=form.course.value %}
{% for value in form.course.field.choices.queryset %}
<option title="{{value}}" value="{{ value.id }}">{{ value }}</option>
{% endfor %}
{% endwith %}
</select>
{% elif 'modelfield' not in field.name %}
{{ field }}
{% endif %}
</div>
</div> {% endfor %}
</table>
<input type="submit" value="Submit">
When I render the form template this way, I lose the "course" selected, but the title is added. Tried to do with widget settings. I don't know how to refer to "option" in "select". How to assign: option title="{{text_value}}"
with title but lose selected
without title but with selected

How to create macro to clean up WTForm error checking?

Is there a better way to set a 'has-error' class within my form fields? I am using Flask and WTForms. The below code works but is very repetitive. I tried to set a dynamic variable such as {% set field + 'error' = 'has-error' %} but found out you cannot set dynamic variables in jinja.
<form action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
{% if login_user_form.email.errors %}
{% set email_error = 'has-error' %}
{% endif %}
{% if login_user_form.password.errors %}
{% set password_error = 'has-error' %}
{% endif %}
<div class="form-group {{ email_error }}">
{{ login_user_form.email(class='form-control input-lg', placeholder='Email', required='true') }}
{% if login_user_form.email.errors %}
{% for error in login_user_form.email.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
{% endif %}
</div> <!-- / Email -->
<div class="form-group signin-password {{ password_error }}">
{{ login_user_form.password(class='form-control input-lg', placeholder='Password', required='true') }}
{% if login_user_form.password.errors %}
{% for error in login_user_form.password.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
{% endif %}
</div> <!-- / Password -->
<div class="form-actions">
<input type="submit" value="Log In" class="btn btn-primary btn-block btn-lg">
</div> <!-- / .form-actions -->
</form>

Use cycle for value in template

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