Current state
This commit is contained in:
43
public/assets/plugins/parsley/extra/plugin/bind.js
Normal file
43
public/assets/plugins/parsley/extra/plugin/bind.js
Normal file
@@ -0,0 +1,43 @@
|
||||
// This plugin replace Parsley default form behavior that auto bind its fields children
|
||||
// With this plugin you must register in constructor your form's fields and their constraints
|
||||
// You have this way a total javascript control over your form validation, and nothing needed in DOM
|
||||
window.ParsleyConfig = $.extend(true, window.ParsleyConfig, { autoBind: false });
|
||||
window.ParsleyExtend = window.ParsleyExtend || {};
|
||||
|
||||
window.ParsleyExtend = $.extend(window.ParsleyExtend, {
|
||||
// { '#selector' : { constraintName1: value, constraintName2: value2 }, #selector2: { constraintName: value } }
|
||||
// { '#selector' : { constraintName1: { requirements: value, priority: value }, constraintName2: value2 } }
|
||||
_bindFields: function () {
|
||||
if ('ParsleyForm' !== this.__class__)
|
||||
throw new Error('`_bindFields` must be called on a form instance');
|
||||
|
||||
if ('undefined' === typeof this.options.fields)
|
||||
throw new Error('bind.js plugin needs to have Parsley instanciated with fields');
|
||||
|
||||
var field;
|
||||
this.fields = [];
|
||||
|
||||
for (var selector in this.options.fields) {
|
||||
if (0 === $(selector).length)
|
||||
continue;
|
||||
|
||||
field = $(selector).parsley();
|
||||
|
||||
for (var name in this.options.fields[selector]) {
|
||||
if ('object' === typeof this.options.fields[selector][name] && !(this.options.fields[selector][name] instanceof Array))
|
||||
field.addConstraint(name.toLowerCase(), this.options.fields[selector][name].requirements, this.options.fields[selector][name].priority || 32);
|
||||
else
|
||||
field.addConstraint(name.toLowerCase(), this.options.fields[selector][name]);
|
||||
}
|
||||
}
|
||||
|
||||
this.fields.push(field);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Do nothing
|
||||
_bindConstraints: function () {
|
||||
return this;
|
||||
}
|
||||
});
|
||||
253
public/assets/plugins/parsley/extra/plugin/remote.js
Normal file
253
public/assets/plugins/parsley/extra/plugin/remote.js
Normal file
@@ -0,0 +1,253 @@
|
||||
// `window.ParsleyExtend`, like `ParsleyAbstract`, is inherited by `ParsleyField` and `ParsleyForm`
|
||||
// That way, we could add new methods or redefine some for these both classes. In particular case
|
||||
// We are adding async validation methods that returns promises, bind them properly to triggered
|
||||
// Events like onkeyup when field is invalid or on form submit. These validation methods adds an
|
||||
// Extra `remote` validator which could not be simply added like other `ParsleyExtra` validators
|
||||
// Because returns promises instead of booleans.
|
||||
window.ParsleyExtend = window.ParsleyExtend || {};
|
||||
window.ParsleyExtend = $.extend(window.ParsleyExtend, {
|
||||
asyncSupport: true,
|
||||
|
||||
asyncValidators: $.extend({
|
||||
default: {
|
||||
fn: function (xhr) {
|
||||
return 'resolved' === xhr.state();
|
||||
},
|
||||
url: false
|
||||
},
|
||||
reverse: {
|
||||
fn: function (xhr) {
|
||||
// If reverse option is set, a failing ajax request is considered successful
|
||||
return 'rejected' === xhr.state();
|
||||
},
|
||||
url: false
|
||||
}
|
||||
}, window.ParsleyExtend.asyncValidators),
|
||||
|
||||
addAsyncValidator: function (name, fn, url) {
|
||||
this.asyncValidators[name.toLowerCase()] = {
|
||||
fn: fn,
|
||||
url: url || false
|
||||
};
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
asyncValidate: function () {
|
||||
if ('ParsleyForm' === this.__class__)
|
||||
return this._asyncValidateForm.apply(this, arguments);
|
||||
|
||||
return this._asyncValidateField.apply(this, arguments);
|
||||
},
|
||||
|
||||
asyncIsValid: function () {
|
||||
if ('ParsleyField' === this.__class__)
|
||||
return this._asyncIsValidField.apply(this, arguments);
|
||||
|
||||
return this._asyncIsValidForm.apply(this, arguments);
|
||||
},
|
||||
|
||||
onSubmitValidate: function (event) {
|
||||
var that = this;
|
||||
|
||||
// This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
|
||||
if (true === event.parsley)
|
||||
return;
|
||||
|
||||
// Clone the event object
|
||||
this.submitEvent = $.extend(true, {}, event);
|
||||
|
||||
// Prevent form submit and immediately stop its event propagation
|
||||
if (event instanceof $.Event) {
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
return this._asyncValidateForm(undefined, event)
|
||||
.done(function () {
|
||||
// If user do not have prevented the event, re-submit form
|
||||
if (!that.submitEvent.isDefaultPrevented())
|
||||
that.$element.trigger($.extend($.Event('submit'), { parsley: true }));
|
||||
});
|
||||
},
|
||||
|
||||
eventValidate: function (event) {
|
||||
// For keyup, keypress, keydown.. events that could be a little bit obstrusive
|
||||
// do not validate if val length < min threshold on first validation. Once field have been validated once and info
|
||||
// about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
|
||||
if (new RegExp('key').test(event.type))
|
||||
if (!this._ui.validationInformationVisible && this.getValue().length <= this.options.validationThreshold)
|
||||
return;
|
||||
|
||||
this._ui.validatedOnce = true;
|
||||
this.asyncValidate();
|
||||
},
|
||||
|
||||
// Returns Promise
|
||||
_asyncValidateForm: function (group, event) {
|
||||
var
|
||||
that = this,
|
||||
promises = [];
|
||||
|
||||
this._refreshFields();
|
||||
|
||||
$.emit('parsley:form:validate', this);
|
||||
|
||||
for (var i = 0; i < this.fields.length; i++) {
|
||||
|
||||
// do not validate a field if not the same as given validation group
|
||||
if (group && group !== this.fields[i].options.group)
|
||||
continue;
|
||||
|
||||
promises.push(this.fields[i]._asyncValidateField());
|
||||
}
|
||||
|
||||
return $.when.apply($, promises)
|
||||
.always(function () {
|
||||
$.emit('parsley:form:validated', that);
|
||||
});
|
||||
},
|
||||
|
||||
_asyncIsValidForm: function (group, force) {
|
||||
var promises = [];
|
||||
this._refreshFields();
|
||||
|
||||
for (var i = 0; i < this.fields.length; i++) {
|
||||
|
||||
// do not validate a field if not the same as given validation group
|
||||
if (group && group !== this.fields[i].options.group)
|
||||
continue;
|
||||
|
||||
promises.push(this.fields[i]._asyncIsValidField(force));
|
||||
}
|
||||
|
||||
return $.when.apply($, promises);
|
||||
},
|
||||
|
||||
_asyncValidateField: function (force) {
|
||||
var that = this;
|
||||
|
||||
$.emit('parsley:field:validate', this);
|
||||
|
||||
return this._asyncIsValidField(force)
|
||||
.done(function () {
|
||||
$.emit('parsley:field:success', that);
|
||||
})
|
||||
.fail(function () {
|
||||
$.emit('parsley:field:error', that);
|
||||
})
|
||||
.always(function () {
|
||||
$.emit('parsley:field:validated', that);
|
||||
});
|
||||
},
|
||||
|
||||
_asyncIsValidField: function (force, value) {
|
||||
var
|
||||
deferred = $.Deferred(),
|
||||
remoteConstraintIndex;
|
||||
|
||||
// If regular isValid (matching regular constraints) returns `false`, no need to go further
|
||||
// Directly reject promise, do not run remote validator and save server load
|
||||
if (false === this.isValid(force, value))
|
||||
deferred.rejectWith(this);
|
||||
|
||||
// If regular constraints are valid, and there is a remote validator registered, run it
|
||||
else if ('undefined' !== typeof this.constraintsByName.remote)
|
||||
this._remote(deferred);
|
||||
|
||||
// Otherwise all is good, resolve promise
|
||||
else
|
||||
deferred.resolveWith(this);
|
||||
|
||||
// Return promise
|
||||
return deferred.promise();
|
||||
},
|
||||
|
||||
_remote: function (deferred) {
|
||||
var
|
||||
that = this,
|
||||
data = {},
|
||||
ajaxOptions,
|
||||
csr,
|
||||
validator = this.options.remoteValidator || (true === this.options.remoteReverse ? 'reverse' : 'default');
|
||||
|
||||
validator = validator.toLowerCase();
|
||||
|
||||
if ('undefined' === typeof this.asyncValidators[validator])
|
||||
throw new Error('Calling an undefined async validator: `' + validator + '`');
|
||||
|
||||
// Fill data with current value
|
||||
data[this.$element.attr('name') || this.$element.attr('id')] = this.getValue();
|
||||
|
||||
// All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
|
||||
ajaxOptions = $.extend(true, {}, {
|
||||
url: this.asyncValidators[validator].url || this.options.remote,
|
||||
data: data,
|
||||
type: 'GET'
|
||||
}, this.options.remoteOptions || {});
|
||||
|
||||
// Generate store key based on ajax options
|
||||
csr = $.param(ajaxOptions);
|
||||
|
||||
// Initialise querry cache
|
||||
if ('undefined' === typeof this._remoteCache)
|
||||
this._remoteCache = {};
|
||||
|
||||
// Try to retrieve stored xhr
|
||||
if (!this._remoteCache[csr]) {
|
||||
// Prevent multi burst xhr queries
|
||||
if (this._xhr && 'pending' === this._xhr.state())
|
||||
this._xhr.abort();
|
||||
|
||||
// Make ajax call
|
||||
this._xhr = $.ajax(ajaxOptions)
|
||||
|
||||
// Store remote call result to avoid next calls with exact same parameters
|
||||
this._remoteCache[csr] = this._xhr;
|
||||
}
|
||||
|
||||
this._remoteCache[csr]
|
||||
.done(function (data, textStatus, xhr) {
|
||||
that._handleRemoteResult(validator, xhr, deferred);
|
||||
})
|
||||
.fail(function (xhr, status, message) {
|
||||
// If we aborted the query, do not handle nothing for this value
|
||||
if ('abort' === status)
|
||||
return;
|
||||
|
||||
that._handleRemoteResult(validator, xhr, deferred);
|
||||
});
|
||||
},
|
||||
|
||||
_handleRemoteResult: function (validator, xhr, deferred) {
|
||||
// If true, simply resolve and exit
|
||||
if ('function' === typeof this.asyncValidators[validator].fn && this.asyncValidators[validator].fn(xhr)) {
|
||||
deferred.resolveWith(this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Else, create a proper remote validation Violation to trigger right UI
|
||||
this.validationResult = [
|
||||
new window.ParsleyValidator.Validator.Violation(
|
||||
this.constraintsByName.remote,
|
||||
this.getValue(),
|
||||
null
|
||||
)
|
||||
];
|
||||
|
||||
deferred.rejectWith(this);
|
||||
}
|
||||
});
|
||||
|
||||
// Remote validator is just an always true sync validator with lowest (-1) priority possible
|
||||
// It will be overloaded in `validateThroughValidator()` that will do the heavy async work
|
||||
// This 'hack' is needed not to mess up too much with error messages and stuff in `ParsleyUI`
|
||||
window.ParsleyConfig = window.ParsleyConfig || {};
|
||||
window.ParsleyConfig.validators = window.ParsleyConfig.validators || {};
|
||||
window.ParsleyConfig.validators.remote = {
|
||||
fn: function () {
|
||||
return true;
|
||||
},
|
||||
priority: -1
|
||||
};
|
||||
11
public/assets/plugins/parsley/extra/validator/dateiso.js
Normal file
11
public/assets/plugins/parsley/extra/validator/dateiso.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// dateiso extra validator
|
||||
// Guillaume Potier
|
||||
window.ParsleyConfig = window.ParsleyConfig || {};
|
||||
window.ParsleyConfig.validators = window.ParsleyConfig.validators || {};
|
||||
|
||||
window.ParsleyConfig.validators.dateiso = {
|
||||
fn: function (value) {
|
||||
return /^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])$/.test(value);
|
||||
},
|
||||
priority: 256
|
||||
};
|
||||
Reference in New Issue
Block a user