*Addedcommentingandformattingtotabs-wtfspaces?!(sidenote:IfyouarecodinginNotepadorvim,pleaseseekatherapist's help immediately. Perhaps you haven'theardthattherearefreetools(Notepad++,Emacs)thatdoformattingforyou,oryoucangoalloutanduseanactualintegrateddevelopmentenvironmentlikeaprofessionaldeveloperwhovaluestheirtimemight.)
//Gets the actual element to perform the validation on. This returns the input element if the input element isn't a surrogate for a hidden form element.
//Some widget libraries (such as Select2) hide the actual element that holds the data, and use custom graphical elements for the control and display logic.
//We need the actual element that holds the value, and not the display elements which fire the events we are interested in (focusout, etc).
//Select2 creates a structure of span elements whose parent span has the .select2 class and whose sibling is a hidden select element that contains the actual selection to be validated.
return$el.parents('.select2').siblings('select');
}
else{
return$el;
}
}
//The opposite of getActualWidget($el). Gets the visible surrogate widget for the actual hidden form widget.
//The actual hidden widget holds the value and acts like a form element when submitting the form, while the surrogate has the display and functionality desired by the view.
//Select2 creates a structure of span elements whose parent span has the .select2 class and whose sibling is a hidden select element that contains the actual selection to be validated.
//This will find some kind of matching elements in the form and when the validation event is detected on the match target (retrieved from the data-match element's 'match' data), a validation event will also be fired on the data-match element.
//Register an event handler on the match target element and if the match target element has a value, then fire the validator event on the data-match element also.
//Force validation on any elements that start with values (ignore those that don't).
//Filter the HTML elements we will be validating to get the set that contains values (ignore those that don't have values), then trigger a 'focusout' event on those elements (forcing validation as we start the Validator up).
this.$inputs.filter(function(){
returngetValue($(this))
}).trigger('focusout');
//Diable automatic native validation.
this.$element.attr('novalidate',true);
//Update the submit elements based on the current error state.
//Collects a list of HTML elements that require validation using the INPUT_SELECTOR option supplied when the Validator was created, and the default data-validate attribute that can be supplied in the HTML tags.
//Runs a complete validation. Returns this validator (does not return the result of the validation since the validation is performed in the future).
//@param fn An optional function that will be run after validating, and which will be passed a boolean indicating whether the form passed validation (isValid). [Added by Wynne Crisman 10/2016]
// Allows the user to validate and do something based on the form's validity without any complicated gyrations:
//Create a collection of promises by validating each input HTML element, then update the submit logic based on the presence of errors and set the focus to the first element with an error.
$.when(this.$inputs.map(function(el){
var$el=$(this);//Wrapper the event target with a jquery object.
var$surrogate=getSurrogate($el);//Gets the surrogate widget used to manage the display and functionality. Will === $el if there isn't a surrogate.
returnself.validateInput($el,$surrogate,false);
})).then(function(){
self.toggleSubmit();
self.focusError();
//Call the callback, passing whether the form is valid (boolean).
//Save the errors by attaching them to the HTML element.
$el.data('bs.validator.errors',errors);
//If there were no errors then call clearErrors() to remove the error styling on the view, otherwise we do have errors and we either show them immediately (change styling & HTML) or defer the showing of them until later if told to defer.
//If this is the first run of the validator for this element (prevErrors == undefined), or the previous errors are the same as the new errors (nothing changed), then fire an event notifying listeners of the change in error status.
//Returns a Promise where the result is the array of errors (error messages) found by the validator. The promise will be passed an empty array if there are no errors.
Validator.prototype.runValidators=function($el){
varerrors=[];
vardeferred=$.Deferred();
//If using deferred validation then reject (avoid recursive calls?).
//For each validator in the validator hashmap (key value pair), call the function f(key,validator) using this as the context (so it has access to 'this' from this method).
//See the VALIDATORS hashmap defined above (used as the default set of validator functions).
//If the HTML element has a value OR is required, AND there is data attached to the HTML element for the current validator OR the validator is 'native', AND the validator produces an error.
//Allow generic or state or specific validator errors to trump the validation error.
error=getErrorMessage(key)||error;
//If the error is not in the list then add it. Use jquery.inArray instead of indexOf since indexOf does not exist in some IE versions.
if(!~$.inArray(error,errors))errors.push(error);
}
},this));
//Get errors from the server if a 'remote' URL is provided (allow it to check the element's value and supply additional errors), and then resolve the promise with the collected errors.
//If there are no errors AND the HTML element has a value AND the HTML element has 'remote' data associated, then make an AJAX call sometime in the future to pass the server the element name and value, otherwise resolve the promise passing the error list.
//Assign elementName = elementValue to the data object.
data[$el.attr('name')]=getValue($el);
//Make an AJAX GET call to the URL stored in the element's 'remote' data, passing the object containing the element's name and its value. If there is an error in the AJAX call then add the error to the error list.
$.get($el.data('remote'),data)
.fail(function(jqXHR,textStatus,error){
errors.push(getErrorMessage('remote')||error)
})
.always(function(){
deferred.resolve(errors)
})
})
}
elsedeferred.resolve(errors);
//Return the promise that will be passed the collected errors (array of strings) when the error checking is complete.
returndeferred.promise();
};
//Changes the focus to the first element with an error.
//Defers the callback function so that it runs sometime in the future. Only one callback may be deferred at any given time. How far into the future it will be deferred depends on the 'delay' option.
//Used internally to defer validation as the user interacts with the form such that we don't validated constantly (for every character typed).
Validator.prototype.defer=function($el,callback){
//Wrapper the callback so it's 'this' variable will be the validator.
callback=$.proxy(callback,this,$el);
//If there isn't a delay then run the callback immediately.