Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display form errors with django and ajax

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

like image 753
Robin Avatar asked Dec 24 '15 20:12

Robin


2 Answers

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.

like image 191
mariodev Avatar answered Sep 21 '22 12:09

mariodev


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>
like image 41
Yanwar Sky Avatar answered Sep 20 '22 12:09

Yanwar Sky