Skip to content

Instantly share code, notes, and snippets.

@thunklife
Last active December 11, 2015 08:08
Show Gist options
  • Select an option

  • Save thunklife/4570899 to your computer and use it in GitHub Desktop.

Select an option

Save thunklife/4570899 to your computer and use it in GitHub Desktop.
Another spike for declaring client-side validation bindings
(function ($, validation, continuations) {
// You can compose these however you like
validation.Validator = $.fubuvalidation.Core.Validator.basic();
validation.Processor = $.fubuvalidation.UI.ValidationProcessor.basic();
function submitHandler(form) {
form = $(form);
var elements = elementsFor(form);
var notification = new validation.Core.Notification();
elements.each(function () {
var target = validation.Core.Target.forElement($(this), form.attr('id'));
validation.Validator.validate(target, notification);
});
processNotification(notification, form);
return notification.isValid();
}
function elementsFor(form) {
return form.find("input, select, textarea").not(":submit, :reset, :image, [disabled]");
}
function processNotification(notification, form) {
var continuation = notification.toContinuation();
continuation.form = form;
validation.Processor.process(continuation);
form.storeNotification(notification);
}
function elementHandler(element, form) {
var notification = form.notification();
var elementNotification = new validation.Core.Notification();
var target = validation.Core.Target.forElement(element, form.attr('id'));
validation.Validator.validate(target, elementNotification);
notification.importForTarget(elementNotification, target);
processNotification(notification, form);
}
$.fn.bindAll = function (delegate, type, handler) {
return this.bind(type, function (event) {
var target = $(event.target);
if (target.is(delegate)) {
return handler.apply(target, arguments);
}
});
};
function unbindEvents(bindings) {
$.each(bindings, function (key, value) {
$(value.selector).unbind(value.events);
});
}
function bindEvents(form, bindings) {
$.each(bindings, function (key, value) {
form.bindAll(value.selector, value.events, function(){
elementHandler($(this), form);
});
}
);
}
$.fn.storeNotification = function (notification) {
$.data(this[0], 'fubu-notification', notification);
};
$.fn.notification = function () {
var notification = $.data(this[0], 'fubu-notification');
if (!notification || typeof (notification) == 'undefined') {
notification = new validation.Core.Notification();
this.storeNotification(notification);
}
return notification;
};
$.fn.validate = function (options) {
return this.each(function () {
var settings = {
ajax: true,
continuationSuccess: function (continuation) {
// no -op
},
bindingConfiguration: {
bindings:[{selector: ":text, [type='password'], [type='file'], select, textarea, " +
"[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
"[type='email'], [type='datetime'], [type='date'], [type='month'], " +
"[type='week'], [type='time'], [type='datetime-local'], " +
"[type='range'], [type='color']",
events: "focusin focusout keyup"
},
{ selector: "select", events: "click change" }],
clearExisting: false,
preserveDefaults: true
}
};
//calling $.extend causes the default bindings to be replace with the configured ones.
//so we combine the two arrays if we need to preserve the defaults the $.extend is fine
if (settings.bindingConfiguration.preserveDefaults) {
options.bindingConfiguration.bindings = settings.bindingConfiguration.bindings.concat(options.bindingConfiguration.bindings);
}
settings = $.extend(true, settings, options);
if (settings.bindingConfiguration.clearExisting) {
unbindEvents(settings.bindingConfiguration.bindings);
}
bindEvents($(this), settings.bindingConfiguration.bindings);
$(this).submit(function () {
if (!submitHandler(this)) {
return false;
}
if (settings.ajax) {
$(this).correlatedSubmit({
continuationSuccess: settings.continuationSuccess
});
return false;
}
return true;
});
});
};
var _reset = $.fn.resetForm;
$.fn.resetForm = function () {
var continuation = new continuations.continuation();
continuation.success = true;
continuation.form = $(this);
validation.Processor.reset(continuation);
return _reset.call(this);
};
continuations.applyPolicy({
matches: function (continuation) {
return continuation.matchOnProperty('form', function (form) {
return form.size() != 0;
});
},
execute: function (continuation) {
if (!continuation.errors) {
continuation.errors = [];
}
validation.Processor.process(continuation);
}
});
} (jQuery, jQuery.fubuvalidation, jQuery.continuations));
$(document).ready(function () {
$('form.validated-form').each(function () {
var mode = $(this).data('validationMode');
$(this).validate({
ajax: mode == 'ajax',
continuationSuccess: function (continuation) {
continuation.form.trigger('validation:success', continuation);
},
bindingConfiguration: {
//bindings is an array of selectors and corresponding events
//defaults are provided and any specified here are added to those defaults
//any events specified are in addition to the defaults
bindings: [
{ selector: '[name="Name"]', events: "focusin focusout keyup" },
]
//,clearExisting: true <--This wipes out any previous bindings by calling unbind() on all configured selectors
//,preserveDefaults: false <--This overrides the default bindings
}
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment