Skip to content


Django generic AJAX form validation

I just created a generic view for Django which allows a developer to easily add AJAX-style form validation to a newforms based form.

The system needs one server-side view, and some client-side JavaScript. You can find the view code in my Django snippets Git repository. The view only works with POST requests. It takes a standard HttpRequest and some options:

  • form_class: this parameter defines the newforms class to validate against. It can be specified in the extra args parameter of the view’s urlconf. If you don’t specify it, the ‘form_class’ POST field will be used. If this doesn’t exist either, an exception is raised. The parameter can be a newforms form instance, a string, or a class (which should be a subclass of BaseForm).
  • format: the serialization format to use. Currently only ‘json’ is supported.
  • args: extra argument list to provide to the form constructor (shouldn’t be provided in most cases)
  • kwargs: extra argument dics to provide to the form constructor (shouldn’t be provided in most cases)

Next to the server-side view you’ll need some pretty basic JavaScript code on client side. I use JQuery and the JQuery Form plugin. Here’s some sample code, assuming the form ID is ‘my_form’, and form fields are represented like this:

<p id="{{ form.field.name }}_container"><label for="{{ form.field.auto_id }}">{{ form.field.label|capfirst }}:</label>{{ form.field }}
{% if form.field.errors %}<span id="{{ form.field.name }}_error" class="error">{{ form.field.errors.0 }}</span>{% endif %}
</p>

Here’s the corresponding JavaScript code:

function do_something() {
}
function process_validation(data) {
    if(data['form_valid'] == true) {
        do_something();
        return;
    }
    for(var field in data["errors"]) {
        errors = data["errors"][field]
        if(errors.length > 0) {
            error = errors[0];
            if($("#" + field + "_error").length == 0) {
                s = $("<br /><span style=\"display: none;\" id=\"" + field + "_error\" class=\"error\">" + error + "</span>");
                $("#" + field + "_container").append(s);
            }
            $("#" + field + "_error").html(error).fadeIn("slow");
        }
    }
}
function validate_form(data) {
    data.push({name: 'form_class', value: 'project.application.forms.ApplicationForm'});
    $.post("{% url validate_form %}", data, process_validation, "json");
}
$(document).ready(function() {
    $("#my_form").submit(function() {
        data = $("#my_form").formToArray();
        $(".error").fadeOut("slow");
        validate_form(data);
        return false;
    });
});

Obviously this should be changed to suit your needs.

I hope this code can be useful for someone…

Posted in Development.

Tagged with , , , , , , , .


10 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Yoan says

    I’m wondering what is happening when you are clicking many times.

    $(“.error”).fadeOut(“slow”);

    This is a bit “light”, you should remove them from the DOM after fading them out. And please remove the br you are using or put it the error class name too.

    By the way, it’s a nice and useful idea.

    Cheers,

  2. Nicolas says

    That’s up to the client side developer I guess, I must admit I’m not that good at JavaScript/DOM coding.

    Clicking many times is not an issue as the existing container is re-used if it already exists.

    The BR is there to make things look good, I don’t now whether there’s better markup…

    Thanks for the constructive comment :-)

  3. Yoan says

    You’re right about the container, sorry.

    You shouldn’t load the server for testing a form anyway, reactivity is important so use Ajax carefully ;-)

  4. Nicolas says

    You’re right there. A really nice project would be to add client-side form validation code generation to Django’s newforms, so I could do something like:

    $(document).ready(function() {
        $("#myform").submit(function(form) {
            {% validate_form form myproject.myapp.forms.FooForm %}
        });
    });
  5. Nicolas says

    I started the above mentioned project, see http://eikke.com/tag/django-validation/ Enjoy!

  6. assaxy says
  7. name says

    ,

  8. name says

    Smotri i y4is,

  9. Tim McDonald says

    nice validation, first time i’ve set somthing like this up.. works well. Thank you.

  10. myspace quotes dude says

    Cool scripting… bit complex for me, but i’ll figure it out!



Some HTML is OK

or, reply to this post via trackback.