开发者

How to reopen a Django form in a jQuery dialog when the form validation fails in the backend?

I have a Django form which I load dynamically to a jQuery dialog after a user has clicked a link on a webpage. The href in the link points to a Django page that contains just the form contents, not the whole site layout.

        $('#add-note').click(function() {
            $('#dialog').load($(this).attr('href')).dialog({
                title: 'Add a note',
                modal: true,
                draggable: false,
                minWidth: 500,
            });

            return false;
        });

This works fine if the user submits a form that validates in the backend. However, if the form contains validation errors, Django forwards the browser back to the form page, which in this case is not actually the page the user was viewing at the moment.

See, the user was on a totally different 开发者_开发问答page and the form was just dynamically loaded to the jQuery dialog. So the question is, what would be the best way to handle this kind of situation? How do I open the form with validation errors back in to the dialog and not the form page itself?

All help appreciated greatly!


When using AJAX and Django forms I usually do it the following approach (no code examples though, but I think you will get the idea).

  • create a different template just for rendering this form (no blocks, no extending from another template)
  • in your view which render the template to display the form, render this form direclty into html via django.template.loader.render_to_string (using the template I mentioned). Put this rendered form into the context pushing it to the template.
  • In your template create a container for the form and render the html inside there.
  • when you now submit your form via AJAX make sure the handler which submit the form renders the form as well (like in your original view via django.template.loader.render_to_string) and returns at least this as html. Thls will include the errors if the form was not valid.
  • When getting the AJAX response simply replace the form in your container completely. After that you got the Django form including all the errors from a original django form submit.

The advantages of this approach are that Django is still taking care of the form validation and error displaying and you don't need to take care of it via Javascript (can be a little annoying especially for field errors). Disadvantage is of course that you have to write more backend code for it. :)


If a form isn't valid, I return an error along with a message instead of returning 200, success, etc. In the view it's something like this:

if form.is_valid():
    ...hooray!
else:
    return HttpResponse(json.dumps({'error': msg}), status=400, 
                        mimetype='application/json')

In the ajax request I just made the the request will fail, and I'll display the error to the user somewhere (usually in the dialog) and the javascript will look something like this:

$.ajax({
  type: 'POST',
  data: form,
  error: function(data) {
    var error = $.parseJSON(data.responseText);
    $('#error').text(error.error);
    $('#error').show();
  }
}); 


A quick and dirty, non-ajax solution would be:

$(function() {
    {% if form.errors %}
        $( "#form" ).dialog( "open" );
    {% endif %}
});

Or if you have a formset:

{% if formset.is_bound and not formset.is_valid %}
    $( "#formset" ).dialog( "open" );
{% endif %}

Note: formset.errors will always be true (it's a list of empty dictionaries if there aren't any errors) so you have to use is_bound and is_valid in this way or you'll always open the dialog after submitting the formset.

Edit: This doesn't actually quite answer the original question. I oversaw that your form was loaded from a different url. My solution does work if you're handling the form in the same view and you're simply displaying it in a jQuery dialog on that same page.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜