Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions ajax_validation/sites.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
# -*- coding: utf-8 -*-
from django.conf.urls.defaults import patterns
from django.db.models.base import ModelBase

from ajax_validation.views import ModelValidationView



class AlreadyRegistered(Exception):
pass



class NotRegistered(Exception):
pass



class ValidationSite(object):
def __init__(self):
self._registry = {}


def _get_iterable(self, validation_class_or_iterable):
if not isinstance(validation_class_or_iterable, ModelValidationView):
validation_class_or_iterable = [validation_class_or_iterable]
return validation_class_or_iterable


def register(self, validation_class_or_iterable):
validation_class_iterable = self._get_iterable(validation_class_or_iterable)

Expand All @@ -36,7 +30,6 @@ def register(self, validation_class_or_iterable):

self._registry[validation_class] = validation_class()


def unregister(self, validation_class_or_iterable):
validation_class_iterable = self._get_iterable(validation_class_or_iterable)

Expand All @@ -45,7 +38,6 @@ def unregister(self, validation_class_or_iterable):
raise NotRegistered('The validation_class %s is not registered' % validation_class.__name__)
del self._registry[validation_class]


def get_urls(self, url_prefix=''):
urlpatterns = patterns('')
for model, modelvalidationview in self._registry.iteritems():
Expand All @@ -54,5 +46,4 @@ def get_urls(self, url_prefix=''):
urls = property(lambda s: s.get_urls())



site = ValidationSite()
174 changes: 100 additions & 74 deletions ajax_validation/static/ajax_validation/js/jquery-ajax-validation.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,58 @@
(function($) {
function inputs(form) {
(function ($) {
"use strict";
function inputs(form) {
return form.find(":input:visible:not(:button)");
}

var errorRemover = {
p: function(form, fields){
get_form_error_position(form, '__all__').prev('ul.errorlist').remove();
if (!fields)
form.find('ul.errorlist').remove();
else
fields.closest('p').prev('ul.errorlist').remove();
},
table: function(form, fields){
form.find('tr:has(ul.errorlist):not(:has(label))').remove();
if (!fields)
inputs(form).prev('ul.errorlist').remove();
else
fields.prev('ul.errorlist').remove();

},
ul: function(form, fields){
form.find('li:has(ul.errorlist):not(:has(label))').remove();
if (!fields)
inputs(form).prev().prev('ul.errorlist').remove();
else
fields.prev().prev('ul.errorlist').remove();
},
};

function removeErrors(form, form_type, fields){
if (fields)
fields = $(fields.map(function(n){ return '*[name="'+n+'"]'; }).join(', '));
return errorRemover[form_type](form, fields);
}


function get_form_error_position(form, key) {
key = key || '__all__';
if (key == '__all__') {
var filter = ':first';
var filter;
if (key === '__all__') {
filter = ':first';
} else {
var filter = ':first[id^=id_' + key.replace('__all__', '') + ']';
filter = ':first[id^=id_' + key.replace('__all__', '') + ']';
}
return inputs(form).filter(filter).parent();
}

var errorRemover = {
p: function (form, fields) {
get_form_error_position(form, '__all__').prev('ul.errorlist').remove();
if (!fields) {
form.find('ul.errorlist').remove();
} else {
fields.closest('p').prev('ul.errorlist').remove();
}
},
table: function (form, fields) {
form.find('tr:has(ul.errorlist):not(:has(label))').remove();
if (!fields) {
inputs(form).prev('ul.errorlist').remove();
} else {
fields.prev('ul.errorlist').remove();
}

},
ul: function (form, fields) {
form.find('li:has(ul.errorlist):not(:has(label))').remove();
if (!fields) {
inputs(form).prev().prev('ul.errorlist').remove();
} else {
fields.prev().prev('ul.errorlist').remove();
}
}
};

function removeErrors(form, form_type, fields) {
if (fields) {
fields = $(fields.map(function (n) {return '*[name="' + n + '"]'; }).join(', '));
}
return errorRemover[form_type](form, fields);
}

var errorInjector = {
p: function(form, data) {
$.each(data.errors, function(key, val) {
p: function (form, data) {
$.each(data.errors, function (key, val) {
if (key.indexOf('__all__') >= 0) {
var error = get_form_error_position(form, key);
if (error.prev().is('ul.errorlist')) {
Expand All @@ -60,113 +65,134 @@
}
});
},
table: function(form, data) {
$.each(data.errors, function(key, val) {
table: function (form, data) {
$.each(data.errors, function (key, val) {
if (key.indexOf('__all__') >= 0) {
get_form_error_position(form, key).parent().before('<tr><td colspan="2"><ul class="errorlist"><li>' + val + '</li></ul></td></tr>');
} else {
$('#' + key, form).before('<ul class="errorlist"><li>' + val + '</li></ul>');
}
});
},
ul: function(form, data) {
$.each(data.errors, function(key, val) {
ul: function (form, data) {
$.each(data.errors, function (key, val) {
if (key.indexOf('__all__') >= 0) {
get_form_error_position(form, key).before('<li><ul class="errorlist"><li>' + val + '</li></ul></li>');
} else {
$('#' + key, form).prev().before('<ul class="errorlist"><li>' + val + '</li></ul>');
}
});
},
}
};

function injectErrors(type, form, data){
errorInjector[type](form, data);
function injectErrors(type, form, data) {
errorInjector[type](form, data);
}

function getUntilCurrent(ev, nodeNames) {
var current = ev.originalEvent.explicitOriginalTarget;
if (current.nodeName.toLowerCase() === "option") {
function getUntilCurrent(ev, nodeNames, form) {
var current = ev.originalEvent.explicitOriginalTarget || ev.originalEvent.target || form.find("input, select, textarea").last()[0];
if (current.tagName.toLowerCase() === "option") {
current = $(current).parents("select")[0];
}
if (nodeNames.split(", ").indexOf(current.nodeName.toLowerCase()) === -1) {
if (nodeNames.split(", ").indexOf(current.nodeName.toLowerCase()) === -1) {
return false;
}
return current;
}

$.fn.validate = function(url, settings) {
$.fn.validate = function (url, settings) {
settings = $.extend({
type: 'table',
callback: false,
fields: false,
dom: this,
event: 'submit',
submitHandler: null,
untilCurrent: false,
removeErrors: removeErrors,
injectErrors: injectErrors,
getUntilCurrent: getUntilCurrent
}, settings);

return this.each(function() {
return this.each(function () {
var form = $(this);
settings.dom.bind(settings.event, function(ev) {
var status = false;
var current = null;
var validation = function (ev, is_submitting) {
var responseData = {};
var data = form.serialize();
var nodeNames = "input, select, textarea";
if (settings.fields) {
data += '&' + $.param({fields: settings.fields});
} else if (settings.untilCurrent) {
var current = settings.getUntilCurrent(ev, nodeNames);
current = settings.getUntilCurrent(ev, nodeNames, form);
if (!current) {
return current;
}
var f = $(current).parents("form");
var find = false;
var fieldsName = []
var fieldsName = [];
var fields = f.find(nodeNames).each(function () {
if (!find) {
fieldsName[fieldsName.length] = $(this).attr("name");
}
}
if (this === current) {
find = true;
return;
}
});
data += '&' + $.param({fields: fieldsName});
}
var that = this;
$.ajax({
async: false,
async: true,
data: data,
dataType: 'json',
traditional: true,
error: function(XHR, textStatus, errorThrown) {
status = true;
error: function (XHR, textStatus, errorThrown) {
},
success: function(data, textStatus) {
success: function (data, textStatus) {
responseData = data;
status = data.valid;
settings.removeErrors(form, settings.type, settings.fields);
if (!status) {
if (settings.callback) {
var is_valid = data.valid;
var fields = settings.fields;
var fieldsTags = form.find(nodeNames);
var fieldsToRemove = [];
var i;
if (current !== null) {
for (i = 0; i < fieldsTags.length; i = i + 1) {
var field = fieldsTags[i];
if (fields !== null || fields.indexOf(field) !== -1) {
fieldsToRemove[fieldsToRemove.length] = field.name;
}
if (field === current) {
break;
}
}
} else {
fieldsToRemove = fields;
}
settings.removeErrors(form, settings.type, fieldsToRemove);
if (!is_valid) {
if (settings.callback) {
settings.callback(data, form);
} else {
settings.injectErrors(settings.type, form, data);
}
}
if (is_submitting && is_valid) {
form.submit();
} else {
is_submitting = false;
}
},
type: 'POST',
url: url
});
if (status && settings.submitHandler) {
return settings.submitHandler(form, responseData);
}
return status;
});
};
settings.dom.bind(settings.event, validation);
if (settings.event !== "submit") {
settings.dom.find("input[type=submit]").click(function (ev) {
ev.preventDefault();
validation(ev, true);
});
}
});
};
})(jQuery);

})(jQuery);
1 change: 1 addition & 0 deletions ajax_validation/templatetags/jquery_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

VALIDATION_SCRIPT = None


def include_validation():
global VALIDATION_SCRIPT
if VALIDATION_SCRIPT is None:
Expand Down
2 changes: 2 additions & 0 deletions ajax_validation/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.utils.functional import Promise
from django.utils.encoding import force_unicode

try:
from simplejson import JSONEncoder
except ImportError:
Expand All @@ -8,6 +9,7 @@
except ImportError:
from django.utils.simplejson import JSONEncoder


class LazyEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, Promise):
Expand Down
Loading