alex / django-ajax-validation Goto Github PK
View Code? Open in Web Editor NEWA reusable application to preform ajax validation on django forms.
License: Other
A reusable application to preform ajax validation on django forms.
License: Other
The current version of the validate
view returns valid: True
if the form is valid or if final_errors
is empty. This is different from past behaviour and only makes sense when validating a whole form.
When validating individual fields the JS callback (or built in code for p, table and ul types) still needs to execute when the form is invalid even when the individual field being validated has no errors so that the validation errors can be removed from that particular field as the user progresses to the next field.
Maybe this has just something to do with the version of jQuery or django i'm using, but for me the validation of individual fields doesn't work until I change the two mentions of 'fields' to 'fields[]' in views.py. So it becomes:
if request.POST.getlist('fields[]'):
fields = request.POST.getlist('fields[]') + ['all']
instead of:
if request.POST.getlist('fields'):
fields = request.POST.getlist('fields') + ['all']
(i accidentally closed a copy of this issue and can't figure out how to open it, so I'm creating a new one :-p )
In the jQuery plugin, fields to attach errors are searched this way:
$('#' + key)....
The problem is that can happen to have more than one form in one page and that the two forms have a field with the same name (which results in two fields with same id in the HTML source).
This shouldn't happen since two elements cannot have the same id in HTML, but this is the way it works for now with django.
So, to assure that the errors are shown next to the right field, I think fields should be serached this way instead:
form.find('#' + key)...
Thanks for your great plugin ;)
at line 70 of jquery-ajax-validation.js, it says:
get_form_error_position(key).parent().before('
There's a period (.) where it shouldn't be right before the first closing tag ()
I would like a place to insert a callback for when the form is valid and before it submits.
like the submitHandler callback here:
http://docs.jquery.com/Plugins/Validation/validate#toptions
The invalid Handler is pretty nice too but I think that is approximately what your callback does.
When validation responce is {valid: true} script doesn't clear old error messages.
Hello,
This app looks really nice, but unfortunately I didn't success to make it work.
I got a CRSF validation error when the validation view is called (see below).
I don't know how to make it work.
Any ideas ?
Thanks,
Stéphane
Error seen from firebug:
Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
No CSRF or session cookie.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
It would be nice if you could tell the validation function that it should wait 500 ms after the last onkey event before it starts validating. That way you have almost instant feedback on what you're typing, but you're not sending a request to the server for every character.
Here's how I'm doing it now:
<script type="text/javascript"> $(document).ready(function() { var timers = []; var selectorAndFields = [['#id_username',['username']], ['#id_email',['username','email']], ['#id_password1',['username','email','password1']], ['#id_password2',['username','email','password2', 'password1']]]; for (i = 0; i < selectorAndFields.length; i++) { // bind the validation function to the change event for the input field. $('#signUpForm').validate('{% url registration_form_validation %}', {type: 'table', fields: selectorAndFields[i][1], dom: $(selectorAndFields[i][0]), event: 'change'}); // trigger a change event 500 msecs after the last keyup-event for the same input field. $(selectorAndFields[i][0]).keyup(function() { var field = $(this); if (timers[i]) { clearTimeout(timers[i]); } timers[i] = setTimeout(function(){field.trigger('change')},500); }); } }); </script>
I've set it up so that it validates the field in which the user is typing but also all the fields above. (I thought it would be silly to get feedback on fields you haven't gotten to typing into yet).
Maybe this has just something to do with the version of jQuery or django i'm using, but for me the validation of individual fields doesn't work until I change the two mentions of 'fields' to 'fields[]' in views.py. So it becomes:
if request.POST.getlist('fields[]'):
fields = request.POST.getlist('fields[]') + ['all']
instead of
if request.POST.getlist('fields'):
fields = request.POST.getlist('fields') + ['all']
If multiple errors are associated with a field, they are showed togheter in a single
This does not make sense: every field error should be inside its own
I suggest to edit the jquery-ajax-validation.js file changing the various occurrences of
error.before('<ul class="errorlist"><li>' + val + '</li></ul>');
to
error.before('<ul class="errorlist"><li>' + val.join('</li><li>') + '</li></ul>');
In views.validate you have:
def validate(request, _args, *_kwargs):
form_class = kwargs.pop('form_class')
extra_args_func = kwargs.pop('callback', lambda request, _args, *_kwargs: {})
kwargs = extra_args_func(request, _args, *_kwargs)
kwargs['data'] = request.POST
form = form_class(**kwargs)
I think it would be better to enable the callback function to change also the 'data' parameter passed to the form constructor.
A common use case is a Comment Applcation where for an anonymous user you have post fields with its data (nick, email, url) while for authenticated users you don't have that fields in the POST request and a callback function could simply specify them!
(This is the way the Comment Application bundled with django works)
So, I suggest to convert that code to something like that:
def validate(request, _args, *_kwargs):
form_class = kwargs.pop('form_class')
extra_args_func = kwargs.pop('callback', lambda request, _args, *_kwargs: {'data':request.POST})
kwargs = extra_args_func(request, _args, *_kwargs)
form = form_class(**kwargs)
I've written a patch that adds a semi-colon to the start of the JS so it can be included with other jquery plugins which might omit the closing semi-colon, adds async
param to the validate method so that events like keyup, blur and change can trigger validation in the background while input continues, adds method
param to the validate method so ajax validation can be used with GET method forms and views, allows form_class
to be specified as a string so you can pass it as a URL argument or hard coded path rather than having to import the form class into urls.py. I also cleaned up white space in a few places.
The patch is available at: http://paste.pocoo.org/show/153778/
Because it rocks!
if views.py line 27 change if to elif:
for key, val in errors.iteritems():
if key == '__all__':
final_errors['__all__'] = val
elif not isinstance(form.fields[key], forms.FileField):
html_id = form.fields[key].widget.attrs.get('id') or form[key].auto_id
html_id = form.fields[key].widget.id_for_label(html_id)
final_errors[html_id] = val
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.