= Ajax submiting and processing form errors with newforms and prototype = == The task == {{{ #!html }}} I want to submit only the form and get validation errors from django newforms without submiting the whole page. Django Newforms library is really exciting and easy to use. Django is also great that doesn't restrict me to use any specific ajax/js library so I can use whatever I want in this case ''prototype''. So I'm using {{{ #!html }}} == The Form == The form is a simple contact form with all four fields required. Just to have something to validate. :) {{{ #!python from django import newforms as forms from django.newforms.widgets import * # A simple contact form with four fields. class ContactForm(forms.Form): name = forms.CharField() email = forms.EmailField() topic = forms.CharField() message = forms.CharField(widget=Textarea()) }}} == The View == The view returns either JSON with the errors from the form or a whole page if javascript is disabled in the browser. I have a hidden input element in the form. I set it to None just before sending the form with javascript so the view knows what should it return, the whole page or just the errors with JSON. The rest is just a generic newforms code. I check if the form is valid and redirect the user if it is or return the errors if it's not. When the form is valid and using AJAX I use a special field {'OK': 'java script for the browser to execute'}. The client-side javascript "knows" that it should run the javascript when it encounters 'OK'. {{{ #!python def contactview(request): if request.method == 'POST': theform = ContactForm(request.POST) # if "js" got here together with the form it means that the # browser doesn't have javascript so handle the form without js js = request.POST.get('js', None) if theform.is_valid(): if not js: # simplejson makes a json format so we can do an # eval() and run the javascript the view returns jsaction = 'window.location.pathname="/"' data = simplejson.dumps({'OK':jsaction}) else: return HttpResponseRedirect('/') else: if not js: data = simplejson.dumps(theform.errors) else: return render_to_response('contactform.html', {'form': theform}) return HttpResponse(data, mimetype="text/javascript") else: # show a blank form return render_to_response('contactform.html', {'form': ContactForm()}) }}} == The Javascript == {{{ #!text/html }}} == The Template == The template for the form has a span element with id="for_fieldname" where the javascript puts the errors and {{ forms.fieldname.errors }} where django puts the errors if javascript is disabled. {{{ #!text/html Contact form
Contact form {# in the for_fieldname element I put the errors with js #} {# this are the errors when javascript is disabled #} {{ form.errors.name }}
{{ form.name }}

{{ form.errors.email }}
{{ form.email }}

{{ form.errors.topic }}
{{ form.topic }}

{{ form.errors.message }}
{{ form.message }}


}}}