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 , , , , , , , .

8 Responses

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

  1. Yoan said

    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 said

    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 said

    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 said

    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 said

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

  6. name said

    ,

  7. name said

    Smotri i y4is,

Some HTML is OK

or, reply to this post via trackback.