I have a contact form through which users would be able to contact me. I am using django with ajax, and it works fine if there\'s no error. I would like to show
as an example
django form returns errors with json format using form.errors.as_json(). assume:
{
"sender": [
{
"message": "Enter a valid email address.",
"code": "invalid"
}
],
"subject": [
{
"message": "This field is required.",
"code": "required"
}
]
}
after that, ajax get a response (in success: function(data) {}
. assume already become an object:
data = {
"sender": [
{
"message": "Enter a valid email address.",
"code": "invalid"
},
{
"message": "Enter a .",
"code": "invalid"
}
],
"subject": [
{
"message": "This field is required.",
"code": "required"
}
]
};
and you're already renders previous form, assume:
<input type="text" name="sender"> <br>
<input type="text" name="subject"> <br>
<button>Submit</button>
and to render these messages, you can write scripts in the click events:
// in ajax success (event click)
if ($("input").next('p').length) $("input").nextAll('p').empty();
for (var name in data) {
for (var i in data[name]) {
// object message error django
var $input = $("input[name='"+ name +"']");
$input.after("<p>" + data[name][i].message + "</p>");
}
}
simulation example:
// simulation example, Data obtained from ajax response
var data = {
"sender": [
{
"message": "Enter a valid email address.",
"code": "invalid"
},
{
"message": "Enter a .",
"code": "invalid"
}
],
"subject": [
{
"message": "This field is required.",
"code": "required"
}
]
};
$("button").on("click", function() {
if ($("input").next('p').length) $("input").nextAll('p').empty();
for (var name in data) {
for (var i in data[name]) {
// object message error django
var $input = $("input[name='"+ name +"']");
$input.after("<p>" + data[name][i].message + "</p>");
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="sender"> <br>
<input type="text" name="subject"> <br>
<button>Submit</button>
You need to define status_code
argument for JsonResponse
.
return JsonResponse(data, status_code=400)
This way it will end up in the error
callback in $.ajax.
While you could return all json back and add the errors to the fields, another approach would be to render a partial template of just the form and return the html back to the browser. You would then just replace the form with the returned form.
I'm not saying this is the best thing to do, but it is one approach.
For example, you have /form.html and you include it on the page
{% include 'form.html' %}
then in your form_invalid method, return the rendered html string
return render(self.request, 'form.html', {'form' : form}, status=500)
then in your JS error method, replace the form on the page with the html returned from the server.