9

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 the errors if there's any like it displays above the input fields and not just the errors, but both the input and the errors. It does however differentiate between the success and error result, as the ajax request was successful. But I need to display the actual form errors. How do I that? Your help will be very much appreciated. Thank you.

views:

def contact(request):
    if request.is_ajax() and request.POST:
        form = ContactForm(request.POST)
        if form.is_valid():
            new_contact = form.save()
            data = {
                'result': 'success',
                'message': 'Message Sent.'
            }
            return JsonResponse(data)
        else:
            data = {
                'result': 'error',
                'message': 'Form invalid',
                'form': 'oops.'
            }
            return JsonResponse(data)
    else:
        form = ContactForm()
        return render(request, 'public_contact.html', {
            'form': form
        })

js:

contact_right_form.find('#submit').on('click', function(event) {
    event.preventDefault();
    $.ajax({
        type: contact_right_form.attr('method'),
        url: '/contact/',
        data: contact_right_form.serialize(),
        dataType: 'json',
        success: function(data) {
            if ( data.result == 'success') {
                contact_right_message_sent.text(data.message);
                contact_right_message_sent.show();
            }
            else {
                contact_right_message_sent.text(data.message);
                contact_right_message_sent.show();
            }
        },
        error: function() {
            contact_right_message_sent.text('Sorry! Something went wrong.')
        }
    });
})

Update

I would like to display the errors like the below as it normally does without ajax:

enter image description here

3
  • Does your error message show? ("something went wrong") or is that the issue you're trying to fix Commented Dec 24, 2015 at 20:37
  • @Sayse Yes, it does. The Form invalid is displayed. I need to display the actual form errors. Commented Dec 24, 2015 at 20:38
  • You can return form.errors stackoverflow.com/questions/2624761/… Commented Dec 24, 2015 at 20:41

3 Answers 3

9

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>

Sign up to request clarification or add additional context in comments.

Comments

7
+25

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.

6 Comments

Use form.errors.as_json() and then iterate on the js side.
But how do I display the errors above each of the respective fields? Please see the update for reference.
I would define the form fields explicitly and use smth like <div class="field-[fieldname]-error"> before each field. Then iterate over error json list (returned by ajax) to put the message inside. This is fairly easy to accomplish, so please try to google around.
You can also avoid all this by simply rendering the whole html using ajax, so the errors are rendered on the backend and you send the whole form html. There's a lot of help online for this solution, so please do some search first.
Try using the technique described by Kenneth Love. It uses some JS helper functions to handle and render the form field errors via Ajax in a manner similar to the base Django messages.
|
4

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.