Django errors while using crispy_forms and a custom template - django

I have problems display the default errors within a form I'm creating via crispy_forms using a custom template. Namely, the text "This field is required." is not present for two fields.
Please see, here
Here's the form's init code:
...
start_time = forms.TimeField(label='Start Time', required=True, input_formats=[TIME_FORMAT])
end_time = forms.TimeField(label='End Time', required=True, input_formats=[TIME_FORMAT])
...
Field('end_date', placeholder='dd/mm/yyyy'),
Field('start_time', placeholder='hh:mm (pm/am)', template="appointments/datetimefield.html"),
Field('end_time', placeholder='hh:mm (pm/am)', template="appointments/datetimefield.html"),
and the clean, save methods here:
Finally, the custom template:
{% load crispy_forms_field %}
<div id="div_{{ field.auto_id }}" class="form-group{% if field.errors %} has-error{% endif %}">
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div class="controls col-xs-8 col-md-9 col-lg-9">
{% crispy_field field %}
</div>
</div>

You need to show the errors in the template. Crispy forms has a template you can include for the errors: {% include 'bootstrap3/layout/help_text_and_errors.html' %} (if you're using bootstrap 3).
So your custom template might be like this:
<div id="div_{{ field.auto_id }}" class="form-group{% if field.errors %} has-error{% endif %}">
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="control-label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div class="controls col-xs-8 col-md-9 col-lg-9">
{% crispy_field field %}
{% include 'bootstrap3/layout/help_text_and_errors.html' %}
</div>
</div>

Maybe you should check the version of crispy_forms and update it.
I also had this problem with crispy_forms == 1.3.2 .But when I updated crispy_forms into 1.4.0, the problem disappeared.
Actually, I found that just bootstrap and uni_form folders were in the crispy_forms/templates and bootstrap3 folder was not when crispy_forms == 1.3.2 installed.

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 exclude specific field types in a template form loop

I am using django_widget_tweaks to loop over form fields:
{% for field in form.visible_fields %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
This displays a happy Bootstrap4 compliant interface, except when displaying fields like radio when I need to use a custom-control class not the form-control class.
How can I filter the form field loop to exclude radio inputs so I can write this code separately?
I need to understand how to filter the field loop and what the correct way to do this with the field type for radio is.

Error handling for checked fields Django multiselectfield

I have a conditional check where I need to look at a certain checkbox, and depending on that, a multiselect field becomes required.
I have something similar in place:
{% for value, text in form.customfield.field.choices %}
<div class="checkbox custom-control custom-checkbox list-inline-item" style="display:inline-flex;">
<input type="checkbox" name="{{customfield.name}}" value="{{value}}" class="list-inline-item custom-control-input" title="" id="id_{{value}}" {% if value in customfield.data %} checked="checked"{% endif %}>
<label for="id_{{value}}" class="form-check-label custom-control-label mr-3">{{text}}</label>
</div>
{% endfor %}
Is there a way to do error handling for this? I verified that my form.is_valid() returns false, but the error message does not get displayed, like it does for inputs/textboxes. I'm assuming I need to print the specific error out in the template explicitly, as I am not using defaults like {{ form.customfield }} or {{ bootstrap_field }}
form.is_valid() returns False.
form._errors gives me:
<ul class="errorlist"><li>customfield<ul class="errorlist"><li>This field is required when the other field is checked.</li></ul>
Rant: As with many other Django questions I've asked, I had to post my own answer. End Rant!
Along with the above check, just loop through the field.errors and display the error
Note: invalid-feedback is used to hide/display the error message in Bootstrap4, so
<div id="id_{{customfield.name}}" class="list-inline-item {% if customfield.errors %} is-invalid{% endif %}">
{% for value, text in form.customfield.field.choices %}
<div class="checkbox custom-control custom-checkbox list-inline-item">
<input type="checkbox" name="{{customfield.name}}" value="{{value}}" class="list-inline-item custom-control-input" title="" id="id_{{value}}" {% if value in customfield.data %} checked="checked"{% endif %}>
<label for="id_{{value}}" class="form-check-label custom-control-label">{{text}}</label>
</div>
{% endfor %}
</div>
{% if customfield.errors %}
<div class="invalid-feedback">
{% for error in customfield.errors %} {{ error }} {% endfor %}
</div>
{% endif %}

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>