from django import forms
from django.conf import settings
from django.template.defaultfilters import striptags
class AjaxBaseForm(forms.BaseForm):
def errors_as_json(self, strip_tags=False):
error_summary = {}
errors = {}
for error in self.errors.iteritems():
errors.update({error[0] : unicode(striptags(error[1]) \
if strip_tags else error[1])})
error_summary.update({'errors' : errors })
return error_summary
class AjaxModelForm(AjaxBaseForm, forms.ModelForm):
"""Ajax Form class for ModelForms"""
class AjaxForm(AjaxBaseForm, forms.Form):
"""Ajax Form class for Forms"""
Example Usage:
#forms.py
from my_app import AjaxForm
class MyForm(AjaxForm):
first_name = models.CharField(max_length=40)
#views.py
try:
import json
except ImportError:
import simplejson
from django.views.shortcuts import render_to_response
from my_app.forms import MyForm
def my_view(request):
if request.method == 'GET':
form = MyForm()
else:
form = MyForm(request.POST)
if form.is_valid():
response = {'success' : True}
else:
response = form.errors_as_json()
return HttpResponse(json.dumps(response, ensure_ascii=False),
mimetype='application/json')
return render_to_response('my_template.html', {'form' : form})
Sample JavaScript implementation to handle json returned
using jQuery and the jQuery Form plugin. You'll need to add a hidden field
to your form to hold the value for the form prefix, if you're using one.
This example leverages the jQuery Form plugin:
http://www.malsup.com/jquery/form/
jQuery(function($){
var login_form = $('#login');
login_form.ajaxForm({
url : this.action,
dataType : 'json',
success : function(json)
{
if (json.errors != undefined)
process_form_errors(json, login_form)
else
//do something if there aren't errors
}
});
});
function hide_form_errors()
{
$('.errorlist').remove();
}
function process_form_errors(json, form)
{
hide_form_errors();
form.clearForm();
errors = json.errors;
if (errors.__all__ != undefined)
form.append(errors.__all__);
prefix = form.find(":hidden[name='prefix']").val();
prefix == undefined ? prefix = '' : prefix = prefix + '-';
for (field in errors)
$('#id_' + prefix + field).after(errors[field]);
}
Comments