I am struggling with displaying bootstraps form errors in a popup form modal. When I submit the form, with some missing required fields, I am still getting Django's built in basic form error messages, or even if a field requires a decimal, I enter text, I get an error but it's still django's built in basic validation error. I am using crispy-forms and bootstrap to try to display the errors in a nicer way on the page.
This is the way errors are being displayed now....
I have a simple form here...
{% load crispy_forms_tags %}
<form role="form" method="post" name="employee-add" id="employee-add" action="{% url 'employee_add' company_id %}">
{% csrf_token %}
<input type="hidden" id="companyID" name="comp" value="{{ company_id }}">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Add Employee</h4>
</div>
<div class="modal-body">
<div class="modal-inner defult-inner">
{% for field in employee_form %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
{{ field|as_crispy_field }}
{% for error in field.errors %}
<span class="error-msg">{{ error }}</span>s
{% endfor %}
</div>
{% endfor %}
<div class="footer-button employee-footer">
<button class="btn btn-default" data-dismiss="modal">Cancel</button>
<button class="btn btn-danger" id="save">Save</button>
</div>
</div>
</div>
</form>
The modal form is populated with an AJAX GET
request.
$(function () {
// GET request to grab employee form.
$(".js-create").click(function () {
let employee_id = $("input[name='employee_id']").val();
$.ajax({
url: `/company/employee/${employee_id}/`,
type: 'get',
data: {'employee_id': employee_id},
dataType: 'json',
beforeSend: function () {
$("#modal-employee").modal("show");
},
success: function (data) {
$("#modal-employee .modal-content").html(data.html_form);
$(".selectpicker").selectpicker('refresh');
}
});
});
});
Django view...
@csrf_protect
def employee_create(request, company_id):
template_name = 'business/employee-create.html'
data = dict()
company = Company.objects.get(id=company_id)
if request.method == 'POST':
employee_form = EmployeeForm(request.POST)
if employee_form.is_valid():
logger.debug('Valid')
emp = employee_form.save(commit=False)
emp.company = venue
emp.user = request.user
emp.save()
return redirect('comp_detail', company_id=company_id)
else:
logger.debug('Error')
else:
employee_form = EmployeeForm()
data['html_form'] = render_to_string(
template_name,
{'employee_form': employee_form, 'company_id': company.id},
request=request,
)
return JsonResponse(data)
I feel as though its something here..
{% for field in employee_form %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
{{ field|as_crispy_field }}
{% for error in field.errors %}
<span class="error-msg">{{ error }}</span>s
{% endfor %}
</div>
{% endfor %}
Because, the has-error
class never shows up when I inspect the page. Then if I remove the {% if field.errors %}
line and just add the has-error
class, the form loads with the nice red bootstrap form border. So I know bootstrap is loaded correctly.