| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593 |
- ;(function ( $ ) {
- "use strict";
-
- /* Defaul options */
- var defaults = {
- rules: {},
- messages: {},
- error: {
- scroll: true,
- highlight: true,
- inBlock: false,
- inTooltip: false,
- underField: true,
- inTooltipClass: "j-tooltip-right-top",
- },
- success: {
- highlight: true,
- },
- validationEvent: {
- onsubmit: true,
- onchange: true,
- onkeyup: true,
- },
- formType: {
- modal: false,
- multistep: false,
- },
- formRedirect: {
- redirect: false,
- address: "http://codedthemes.com"
- },
- formHide: {
- hide: false,
- closeBtn: false
- },
- formTotalData: false,
- timeoutSuccessMsg: 5000,
- repeatSubmission: true,
- submit: true,
- debug: false,
- debugArr: [],
- afterInitHandler:function() { return true; },
- beforeSubmitHandler:function() { return true; },
- afterSubmitHandler:function() { return true; },
- dict: {
- debugError: "Oops! Debug errors occurred. Enable debug mode for JavaScript code",
- rulesError: "User settings: You have to specify validation rules for a form",
- messagesError: "User settings: You have to specify validation messages for a form",
- modalOpenError: "Could not find a link/button with class='j-modal-open' to open modal form",
- responseBlockError: "Could not find a block with class='j-response' for server response",
- submitBtnError: "Could not find a button[type='submit'] for form submission",
- totalDataBlockError: "Could not find a block with class='j-total-data' for total form data",
- multistepOneStepError: "Multistep form has only one step. At least two steps are required!",
- rulesUnknownRuleError: "User settings -> 'rules' array: Unknown validation rule: ",
- rulesNotAllowedValueError: "User settings -> 'rules' array -> Not allowed value: ",
- rulesMessagesMismatchError: "User settings: field names in 'rules' and 'messages' are mismatched",
- formDataError: "FormData is not supported in this browser. Please update it to the latest version or use another browser",
- disabledBtn: "Thanks!",
- multistepNextBtn: "Next",
- multistepPrevBtn: "Back",
- errorBlockText: "Oops! The following errors occurred:",
- successBlockText: "Thank you! We got your email successfully",
- },
- mimeTypes: {
- "jpeg": "image/jpeg",
- "tiff": "image/tiff",
- "jpg": "image/jpg",
- "png": "image/png",
- "gif": "image/gif",
- "ico": "image/vnd.microsoft.icon",
- "doc": "application/msword",
- "xls": "application/vnd.ms-excel",
- "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
- "txt": "text/plain",
- "csv": "text/csv",
- "zip": "application/zip",
- "gzip": "application/gzip",
- "rar": "application/x-rar-compressed",
- "odf": ["application/vnd.oasis.opendocument.text",
- "application/vnd.oasis.opendocument.spreadsheet",
- "application/vnd.oasis.opendocument.presentation",
- "application/vnd.oasis.opendocument.graphics"],
- "pdf": "application/pdf",
- "powerpoint": ["application/vnd.ms-powerpoint",
- "application/vnd.openxmlformats-officedocument.presentationml.presentation"],
- "mpeg": ["audio/mpeg","video/mpeg"],
- "mp4": ["audio/mp4","video/mp4"],
- "ogg": ["audio/ogg","video/ogg","application/ogg"],
- },
- };
-
- /* File validation */
- function _fileCheck( fileObj, rules, messages, mimeTypes ) {
- var type, len, i,
- file = fileObj[0].files[0],
- required = rules.required,
- validate = rules.validate,
- extension = rules.extension.toLowerCase(),
- size = rules.size * 1024 * 1024,
- allowedTypes = [],
- extensionArr = extension.split("|");
-
- // Add required valid types
- for ( type in mimeTypes ) {
- if ( extensionArr.indexOf(type) === -1 ) {
- continue;
- }
- if ( $.isArray( mimeTypes[type] ) ) {
- len = mimeTypes[type].length;
- for ( i=0; i<len; i++ ) {
- allowedTypes.push( mimeTypes[type][i] );
- }
- continue;
- }
- allowedTypes.push( mimeTypes[type] );
- }
-
- // Validation
- if ( validate || required ) {
- // If file is required
- if ( required ) {
- // If file is empty
- if ( !file ) {
- return messages.required;
- }
- }
- // If file is not required
- // Validate file only if it exists
- if ( file ) {
- // Check allowed file types
- if ( allowedTypes.indexOf(file.type) === -1 ) {
- return messages.size_extension;
- }
- // Check allowed file size
- if ( file.size > size) {
- return messages.size_extension;
- }
- return false;
- }
- }
- }
-
- /* Email validation */
- function _emailCheck( value ) {
- var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i;
- return !re.test( value );
- }
-
- /* Url validation */
- function _urlCheck( value ){
- var re = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
- return !re.test( value );
- }
-
- /* EqualTo validation */
- function _equalToCheck( value, targetValue ) {
- return ( value.trim() !== targetValue.trim() ) ? true : false;
- }
-
- /* Min value validation */
- function _minValueCheck( value, minVal ) {
- var val = value.trim();
-
- if ( _numberCheck( val ) ) {
- return true;
- }
- return ( val < minVal ) ? true : false;
- }
-
- /* Max value validation */
- function _maxValueCheck( value, maxVal ) {
- var val = value.trim();
-
- if ( _numberCheck( val ) ) {
- return true;
- }
- return ( val > maxVal ) ? true : false;
- }
-
- /* Range value validation */
- function _rangeValueCheck( value, rangeVal ) {
- var val = value.trim();
-
- if ( _numberCheck( val ) ) {
- return true;
- }
- return ( val < rangeVal[0] || val > rangeVal[1] ) ? true : false;
- }
-
- /* Min length validation */
- function _minLengthCheck( value, minLen ) {
- return ( value.trim().length < minLen ) ? true : false;
- }
-
- /* Max length validation */
- function _maxLengthCheck( value, maxLen ) {
- return ( value.trim().length > maxLen ) ? true : false;
- }
-
- /* Range length validation */
- function _rangeLengthCheck( value, rangeLen ) {
- var val = value.trim().length;
- return ( val < rangeLen[0] || val > rangeLen[1] ) ? true : false;
- }
-
- /* Integer validation */
- function _integerCheck( value ) {
- var re = /^-?\d+$/;
- return !re.test( value );
- }
-
- /* Number validation */
- function _numberCheck( value ) {
- var re = /^-?\d+(?:\.\d+)?$/;
- return !re.test( value );
- }
-
- /* Validate rules object */
- function _rulesCheck( obj ) {
- var self = this,
- config = self.config,
- message = self.config.dict.rulesNotAllowedValueError;
-
- $.each(obj, function( name, value ) {
- $.each(value, function( rule, val ) {
- switch( rule ) {
- case "required":
- case "email":
- case "url":
- case "integer":
- case "number":
- case "validate":
- if ( $.type( val ) !== "boolean" ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- case "minlength":
- case "maxlength":
- if ( _integerCheck( val ) || val < 0 ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- case "minvalue":
- case "maxvalue":
- if ( _numberCheck( val ) ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- case "rangelength":
- if ( !$.isArray( val ) ||
- val.length !== 2 ||
- _integerCheck( val[0] ) ||
- _integerCheck( val[1] ) ||
- val[0] > val[1]
- ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- case "rangevalue":
- if ( !$.isArray( val ) ||
- val.length !== 2 ||
- _numberCheck( val[0] ) ||
- _numberCheck( val[1] ) ||
- val[0] > val[1]
- ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- case "size":
- if ( _numberCheck( val ) || val <= 0 ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- case "extension":
- case "equalTo":
- if ( $.type( val ) !== "string" ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- case "requiredFromGroup":
- if ( !$.isArray( val ) ||
- val.length !== 2 ||
- _integerCheck( val[0] ) ||
- $.type( val[1] ) !== "string"
- ) {
- config.debugArr.push( _errorMsg( message, rule, val ) );
- }
- break;
- default:
- config.debugArr.push( config.dict.rulesUnknownRuleError + rule );
- }
- });
- });
- }
-
- /* Validate messages object */
- function _messagesCheck( obj ) {
- var rKeys = Object.keys( obj.rules ).sort(),
- mKeys = Object.keys( obj.messages ).sort();
-
- if ( JSON.stringify( rKeys ) !== JSON.stringify( mKeys ) ) {
- this.config.debugArr.push( this.config.dict.rulesMessagesMismatchError );
- }
- }
-
- /* Config check error message */
- function _errorMsg( message, rule, val ) {
- return message + rule + ": " + val +" ( " + $.type(val) + " )";
- }
-
- /* Get field value */
- function _getValue( obj ) {
- var res;
-
- obj.each( function() {
- if ( $( this ).is( ":checkbox" ) || $( this ).is( ":radio" ) ) {
- if ( $( this ).is( ":checked" ) ) {
- if ( res !== undefined ) {
- res += ", "+$( this ).val();
- } else {
- res = $( this ).val();
- }
- }
- } else {
- res = $( this ).val();
- }
- });
-
- if ( $.isArray( res ) ) {
- res = res.join(", ");
- }
- return ( res === undefined || res === null ) ? "" : res;
- }
-
- /* Check if field is hidden or has "display:none;" */
- function _hiddenCheck( field ) {
- if ( $( field ).css("display") === "none" ||
- $( field ).css("visibility") === "hidden" ||
- $( field ).is(":disabled") ){
- return true;
- }
- return false;
- }
-
- /* Constructor */
- function JustFormsPro( obj, options ) {
- this.config = $.extend( true, {}, defaults, options );
- this.form = obj[0];
- this.$form = obj;
- this.$formObj = {};
- this.$formObjActiveStep = {};
- this.errorExists = false;
- this.errorMessages = {};
-
- // Form elements processing
- this.$formResponseBlock = this.$form.find( ".j-response" );
- this.$submitBtn = this.$form.find( "button[type='submit']" );
-
- // Form plugin init
- this.init();
- }
-
- JustFormsPro.prototype = {
-
- /* Init */
- init: function() {
- var self = this,
- $form = self.$form,
- config = self.config,
- $formObj = self.$formObj,
- str, $el;
-
- // FormData support
- if ( typeof window.FormData === "undefined" ) {
- config.debugArr.push( config.dict.formDataError );
- }
-
- // User input validaion
- if ( $.isEmptyObject( config.rules ) ) {
- config.debugArr.push( config.dict.rulesError );
- } else {
- _rulesCheck.call( self, config.rules );
- }
- if ( $.isEmptyObject( config.messages ) ) {
- config.debugArr.push( config.dict.messagesError );
- } else {
- _messagesCheck.call( self, config );
- }
-
- // Response block availability
- if ( !self.$formResponseBlock.length ){
- config.debugArr.push( config.dict.responseBlockError );
- }
-
- // Submit button availability
- if ( !self.$submitBtn.length ){
- config.debugArr.push( config.dict.submitBtnError );
- }
-
- // Hide form
- if ( config.formHide.hide ) {
- self.initHideForm();
- }
-
- // Modal form
- if ( config.formType.modal ) {
- self.initModalForm();
- }
-
- // Multistep form
- if ( config.formType.multistep ) {
- self.initMultistepForm();
- }
-
- // Init total form data
- if ( config.formTotalData ) {
- self.initTotalData();
- }
-
- // Debug result
- if ( config.debugArr.length ) {
- if ( !config.debug ){
- alert( config.dict.debugError );
- $form.on( "submit", false );
- return false;
- }
- str = config.debugArr.join( '\n -------------- \n' );
- console.warn( str );
- alert( str );
- config.debugArr = [];
- $form.on( "submit", false );
- return false;
- }
-
- // Object with html entities
- $.each( config.rules, function( name, rules ) {
- $el = $form.find( "[name='"+name+"']" );
- if ( $el.length ) {
- $formObj[name] = $el;
- }
- });
-
- // Events
- if ( config.validationEvent.onchange || config.validationEvent.onkeyup ) {
- self.initEvent();
- }
-
- // Processing total form data
- if ( config.formTotalData ) {
- self.processingTotalData();
- }
-
- // Bind submit event
- $form.on( "submit", self.submitForm.bind(self) );
- },
-
- /* Init events */
- initEvent: function() {
- var self = this,
- config = self.config,
- $formObj = self.$formObj,
- eventsArr = [];
-
- // Create events
- if ( config.validationEvent.onchange ) {
- eventsArr.push("change");
- }
- if ( config.validationEvent.onkeyup ) {
- eventsArr.push("keyup");
- }
-
- // Add events
- eventsArr.forEach( function(event) {
- self.$form.on( event, ":input", function() {
- self.clearField( this );
- self.validateField( this );
- });
- $.each( config.rules, function( name, rules ) {
- $.each( rules, function( rule, value ){
- if ( rule === "equalTo" ) {
- $( value ).on( event, function(){
- self.clearField( $formObj[name][0] );
- self.validateField( $formObj[name][0] );
- });
- }
- });
- });
- });
- },
-
- /* Submit a form */
- submitForm: function(e) {
- var self = this,
- config = self.config,
- $prevBtn = self.$prevBtn,
- $submitBtn = self.$submitBtn;
-
- if (e) {
- e.preventDefault();
- e.stopPropagation();
- }
-
- // After init custom handler
- if ( !config.afterInitHandler() ) {
- return false;
- }
-
- // Form validation
- if ( config.validationEvent.onsubmit ) {
- // Buttons disabled
- $submitBtn.toggleClass( "j-processing", true ).attr( "disabled", true );
- if ( config.formType.multistep ) {
- $prevBtn.attr( "disabled", true );
- }
-
- // Clear a form
- self.clearForm();
-
- // Validate form
- self.validateForm();
- }
-
- // If errors exist
- if ( self.errorExists ) {
- // Scroll to first element with error
- if ( config.error.scroll ) {
- self.scrollToError();
- }
-
- // Show errors within an error block
- if ( config.error.inBlock ) {
- self.createErrorBlock( self.errorMessages );
- }
-
- // Buttons enabled
- $submitBtn.toggleClass( "j-processing", false ).removeAttr( "disabled" );
- if ( config.formType.multistep ) {
- $prevBtn.removeAttr( "disabled" );
- }
- return false;
- }
-
- // Before submit custom handler
- if ( !config.submit || !config.beforeSubmitHandler() ) {
- // Buttons enabled
- $submitBtn.toggleClass( "j-processing", false ).removeAttr( "disabled" );
- if ( self.config.formType.multistep ) {
- $prevBtn.removeAttr( "disabled" );
- }
- return false;
- }
-
- // Send form data
- self.getServerResponse();
- },
-
- /* AJAX request */
- sendFormDataAsync: function() {
- var self = this,
- form = self.form,
- formData;
-
- // Form data
- formData = new FormData( form );
-
- return $.ajax({
- url: form.action,
- type: form.method,
- contentType: false,
- processData: false,
- data: formData
- });
- },
-
- /* Send form data */
- getServerResponse: function() {
- var self = this,
- config = self.config,
- $prevBtn = self.$prevBtn,
- $submitBtn = self.$submitBtn,
- $formResponseBlock = self.$formResponseBlock,
- result;
-
- self.sendFormDataAsync().then(function( data ) {
-
- // Server error processing
- if ( config.debug ) {
- console.warn( data );
- }
-
- result = $.parseJSON( data );
-
- // Error message from server
- if ( result.error ) {
-
- // Add class "j-error-message"
- $formResponseBlock.toggleClass( "j-error-message j-unit", true );
- $formResponseBlock.html( result.error );
-
- // Buttons enabled
- $submitBtn.removeClass( "j-processing" ).removeAttr( "disabled" );
- if ( config.formType.multistep ) {
- $prevBtn.removeAttr( "disabled" );
- }
- }
-
- // Success message from server
- if ( result.success ) {
-
- // Custom function applied after submission
- if ( !config.afterSubmitHandler() ) {
- // Buttons enabled
- $submitBtn.removeClass( "j-processing" ).removeAttr( "disabled" );
- if ( config.formType.multistep ) {
- $prevBtn.removeAttr( "disabled" );
- }
- return false;
- }
-
- // Hide form after successful submitting
- if ( config.formHide.hide ) {
- self.processingHideForm();
- return false;
- }
-
- // Redirect form after success submitting
- if ( config.formRedirect.redirect ) {
- self.redirectForm();
- return false;
- }
-
- // Clear a form
- // Show success message
- self.resetForm();
- self.createSuccessBlock( result.success );
- }
- });
- },
-
- /* Validate field */
- validateField: function( field ) {
- var self = this,
- config = self.config,
- $formObj = self.$formObj,
- fieldName = $( field ).attr( "name" ),
- fieldValue;
-
- // If a form does not have a field
- if ( $formObj[fieldName] === undefined || $formObj[fieldName] === null ) {
- return false;
- }
-
- fieldValue = _getValue( $formObj[fieldName] );
-
- self.validation( config.rules[fieldName], field, fieldValue, fieldName);
-
- // Show errors within an error block
- if ( config.error.inBlock ) {
- self.createErrorBlock();
- }
- },
-
- /* Validate all form fields */
- validateForm: function() {
- var self = this,
- config = self.config,
- $formObj, fieldValue;
-
- // If form is mulultistep
- // Get fields from "active" step only
- if ( config.formType.multistep ) {
- self.$formObjActiveStep = {};
- self.getActiveStepField();
- $formObj = self.$formObjActiveStep;
- } else {
- $formObj = self.$formObj;
- }
-
- $.each( config.rules, function( name, rules ) {
-
- // If a form does not have a field
- if ( $formObj[name] === undefined || $formObj[name] === null ) {
- return;
- }
-
- // Skip the validation if field is hidden
- if ( _hiddenCheck( $formObj[name] ) ){
- return;
- }
-
- // Get field value
- fieldValue = _getValue( $formObj[name] );
-
- // Fields processing
- self.validation( rules, $formObj[name], fieldValue, name );
- });
- },
-
- /* Validation functions */
- validation: function( rules, field, fieldValue, fieldName ) {
- var self = this,
- config = self.config,
- count = 0,
- groupObj = {},
- res, groupClass, id;
-
- // Files processing
- if ( $( field ).attr( "type" ) && $( field ).attr( "type" ) === "file" ) {
- if ( config.rules[fieldName].required === true ||
- config.rules[fieldName].validate === true ) {
-
- res = _fileCheck( $( field ), config.rules[fieldName],
- config.messages[fieldName], config.mimeTypes );
-
- if ( res ) {
- self.setErrorState( $( field ), res );
- return false;
- }
- self.setSuccessState( field );
- }
- }
-
- // Fields processing
- $.each( rules, function( rule, ruleValue ){
- switch( rule ) {
- case "required":
- if ( ruleValue === true ) {
- if ( _minLengthCheck( fieldValue, 1 ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- }
- break;
- case "email":
- if ( ruleValue === true ) {
- if ( _emailCheck( fieldValue ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- }
- break;
- case "url":
- if ( ruleValue === true ) {
- if ( _urlCheck( fieldValue ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- }
- break;
- case "integer":
- if ( ruleValue === true ) {
- if ( _integerCheck( fieldValue ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- }
- break;
- case "number":
- if ( ruleValue === true ) {
- if ( _numberCheck( fieldValue ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- }
- break;
- case "minlength":
- if ( _minLengthCheck( fieldValue, config.rules[fieldName][rule] ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- break;
- case "maxlength":
- if ( _maxLengthCheck( fieldValue, config.rules[fieldName][rule] ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- break;
- case "rangelength":
- if ( _rangeLengthCheck( fieldValue, config.rules[fieldName][rule] ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- break;
- case "minvalue":
- if ( _minValueCheck( fieldValue, config.rules[fieldName][rule] ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- break;
- case "maxvalue":
- if ( _maxValueCheck( fieldValue, config.rules[fieldName][rule] ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- break;
- case "rangevalue":
- if ( _rangeValueCheck( fieldValue, config.rules[fieldName][rule] ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- break;
- case "equalTo":
-
- // Get id
- id = ruleValue.slice(1);
-
- // Get element's value with id
- $.each( self.$formObj, function(){
- if ( this.attr( "id" ) === id ) {
- res = this.val();
- }
- });
- if ( _equalToCheck( fieldValue, res ) ) {
- self.setErrorState( field, config.messages[fieldName][rule] );
- return false;
- }
- self.setSuccessState( field );
- break;
- case "requiredFromGroup":
-
- // Get class name
- groupClass = ruleValue[1].slice(1);
-
- // Get elements with class
- $.each( self.$formObj, function( fieldName, fieldObj ){
- if ( fieldObj.hasClass( groupClass ) ) {
- groupObj[fieldName] = fieldObj;
- self.clearField( fieldObj );
- }
- });
-
- // Validation
- $.each( groupObj, function(){
- if ( !_minLengthCheck( _getValue( this ), 1 ) ) {
- count++;
- }
- });
-
- // Add error state
- if ( count < ruleValue[0] ) {
- $.each( groupObj, function(){
- self.setErrorState( this, config.messages[fieldName][rule] );
- });
- return false;
- }
-
- // Add success state
- $.each( groupObj, function(){
- self.setSuccessState( this );
- });
- break;
- }
- });
- },
-
- /* Set error conditions for form fields */
- setErrorState: function( field, msg ) {
- var self = this,
- config = self.config,
- $input = $( field ).closest( ".j-input" ),
- elem;
-
- // Error exists
- self.errorExists = true;
-
- /* Remove class "j-success-view" */
- $input.toggleClass( "j-success-view", false );
-
- // Add class "j-error-view"
- if ( config.error.highlight ) {
- $input.addClass( "j-error-view" );
- }
-
- // Show errors in tooltips
- if ( config.error.inTooltip ) {
- elem = $( "<span />", {
- class: "j-tooltip j-error-view " + config.error.inTooltipClass,
- text: msg
- });
- $input.append( elem );
- }
-
- // Show errors under appropriate fields
- if ( config.error.underField ) {
- elem = $( "<span />", {
- class: "j-error-view",
- text: msg
- });
- $input.append( elem );
- }
-
- // Add error message into an array
- // For showing into error block
- if ( config.error.inBlock ) {
- var fieldName = $( field ).attr( "name" );
- self.errorMessages[fieldName] = msg;
- }
- },
-
- /* Set success conditions for form fields */
- setSuccessState: function( field ) {
- var self = this,
- $input = $( field ).closest( ".j-input" );
-
- // Add class "j-success-view"
- if ( self.config.success.highlight ) {
- $input.toggleClass( "j-success-view", true );
- }
- },
-
- /* Init total form data */
- initTotalData: function() {
- var self = this;
-
- self.$totalDataBlock = self.$form.find( ".j-total-data" );
- if ( !self.$totalDataBlock.length ){
- self.config.debugArr.push( self.config.dict.totalDataBlockError );
- }
- },
-
- /* Total form data processing */
- processingTotalData: function() {
- var self = this,
- $formObj = self.$formObj,
- $totalDataBlock = self.$totalDataBlock,
- $totalDataList, $totalDataValue, $fieldName, $elem;
-
- // List of fields to insert data in
- $totalDataList = $totalDataBlock.find("span[data-field]");
-
- $.each( $totalDataList, function(){
-
- // Get form field with the name
- $fieldName = $( this ).attr("data-field");
- $elem = self.$form.find( "[name='"+$fieldName+"']" );
-
- if ( $elem.length ) {
-
- if ( $formObj[$fieldName] === undefined || $formObj[$fieldName] === null ){
- return;
- }
-
- // Add event listener
- $elem.on("change", (function(obj, name){
- return function(){
- $totalDataValue = _getValue( obj[name] );
- $totalDataBlock.find( "span[data-field='"+name+"']" ).html( $totalDataValue );
- };
- })($formObj, $fieldName));
- }
- });
- },
-
- /* Init multistep form */
- initMultistepForm: function() {
- var self = this,
- $form = self.$form;
-
- self.$nextBtn = $form.find( ".j-multi-next-btn" );
- self.$prevBtn = $form.find( ".j-multi-prev-btn" );
- self.$stepTitleList = $form.find( ".j-step-title" );
- self.$contentBlock = $form.children( ".j-content" );
- self.$footerBlock = $form.children( ".j-footer" );
- self.$stepList = self.$contentBlock.children( "fieldset" );
-
- self.createMultistepForm();
- self.processingMultistepForm();
- },
-
- /* Make a layout for multistep form */
- createMultistepForm: function() {
- var self = this,
- $form = self.$form,
- $stepTitleBlock, $elem, $elems, $elemsLen, $tempStep, $tempStepList, i;
-
- // Add class "j-multistep"
- $form.toggleClass( "j-multistep", true );
-
- // If a form doesn't have "next" button
- if ( !self.$nextBtn.length ) {
- $elem = $("<button />", {
- type: "button",
- class: "j-primary-btn j-multi-next-btn",
- text: self.config.dict.multistepNextBtn
- });
- if ( self.$footerBlock.length ) {
- self.$footerBlock.append( $elem );
- } else {
- self.$contentBlock.append( $elem );
- }
- self.$nextBtn = self.$form.find( ".j-multi-next-btn" );
- }
-
- // If a form doesn't have "previous" button
- if ( !self.$prevBtn.length ) {
- $elem = $("<button />", {
- type: "button",
- class: "j-secondary-btn j-multi-prev-btn",
- text: self.config.dict.multistepPrevBtn
- });
- if ( self.$footerBlock.length ) {
- self.$footerBlock.append( $elem );
- } else {
- self.$contentBlock.append( $elem );
- }
- self.$prevBtn = self.$form.find( ".j-multi-prev-btn" );
- }
-
- // If a form doesn't have fieldsets
- if ( !self.$stepList.length ) {
-
- // Find form fields
- $elems = self.$contentBlock.children( ".j-unit, .j-row" ).filter(":not(.j-step-titles)");
- $stepTitleBlock = self.$contentBlock.children( ".j-step-titles" );
-
- $elemsLen = $elems.length;
-
- // Cerate steps for every set of fields
- for ( i=0; i<$elemsLen; i+=3 ) {
-
- // Add fields to a step
- $tempStep = $( "<fieldset />" ).append( $elems.slice( i, i+3 ) );
-
- // Add step to a form
- $tempStepList = self.$contentBlock.children( "fieldset" );
- if ( !$tempStepList.length ){
- if ( !$stepTitleBlock.length ){
- self.$contentBlock.prepend( $tempStep );
- continue;
- }
- $tempStep.insertAfter( $stepTitleBlock );
- continue;
- }
- $tempStep.insertAfter( $tempStepList.last() );
- }
- self.$stepList = self.$contentBlock.children( "fieldset" );
- }
- },
-
- /* Multistep form processing */
- processingMultistepForm: function() {
- var self = this,
- config = self.config,
- $stepList = self.$stepList,
- $nextBtn = self.$nextBtn,
- $prevBtn = self.$prevBtn,
- $submitBtn = self.$submitBtn,
- $stepTitleList = self.$stepTitleList,
- len = self.$stepList.length;
-
- // If multistep form has one step only
- if ( len === 1 ){
- config.debugArr.push( config.dict.multistepOneStepError );
- $stepList.eq( 0 ).addClass( "j-active-fieldset" );
- return false;
- }
-
- // Processing of the first fieldset
- $stepList.eq( 0 ).addClass( "j-active-fieldset" );
- $submitBtn.addClass( "j-hiddenBtn" );
- $prevBtn.addClass( "j-hiddenBtn" );
-
- // Set active step title
- if ( $stepTitleList.length ){
- $stepTitleList.eq(0).addClass( "j-active-step" );
- }
-
- // Click on the "next" button
- $nextBtn.on( "click", function( e ){
- if ( e ) {
- e.preventDefault();
- e.stopPropagation();
- }
-
- // Clear a form
- self.clearForm();
-
- // Form validation
- self.validateForm();
-
- // If errors don"t exist
- if ( !self.errorExists ) {
-
- // Switch the "active" class to the next fieldset
- $stepList.filter( ".j-active-fieldset" ).removeClass( "j-active-fieldset" ).
- next( "fieldset" ).addClass( "j-active-fieldset" );
-
- // Switch the "active" class to the next step
- if ( $stepTitleList.length ) {
- $stepTitleList.filter( ".j-active-step" ).removeClass( "j-active-step" ).
- addClass( "j-passed-step" ).next( ".j-step-title" ).addClass( "j-active-step" );
- }
-
- // Display "prev" button
- $prevBtn.removeClass( "j-hiddenBtn" );
-
- // If active fieldset is a last
- // processing the buttons
- if ( $stepList.eq( len-1 ).hasClass( "j-active-fieldset" ) ) {
- $submitBtn.removeClass( "j-hiddenBtn" );
- $nextBtn.addClass( "j-hiddenBtn" );
- }
-
- // If current fieldset has validation errors
- } else {
- // Scroll to first element with error
- if ( config.error.scroll ) {
- self.scrollToError();
- }
- // Show errors within an error block
- if ( config.error.inBlock ) {
- self.createErrorBlock();
- }
- return false;
- }
- });
-
- // Click on the "prev" button
- $prevBtn.on( "click", function( e ){
- if ( e ) {
- e.preventDefault();
- e.stopPropagation();
- }
-
- // Clear a form
- self.clearForm();
-
- // Switch the "active" class to the previous fieldset
- $stepList.filter( ".j-active-fieldset" ).removeClass( "j-active-fieldset" ).
- prev( "fieldset" ).addClass( "j-active-fieldset" );
-
-
- // Switch the "active" class to the next step
- if ( $stepTitleList.length ) {
- $stepTitleList.filter( ".j-active-step" ).removeClass( "j-active-step" ).
- prev( ".j-step-title" ).removeClass( "j-passed-step" ).addClass( "j-active-step" );
- }
-
- // If active fieldset is a first
- // processing the buttons
- if ( $stepList.eq(0).hasClass( "j-active-fieldset" ) ) {
- $prevBtn.addClass( "j-hiddenBtn" );
- }
-
- // If active fieldset is a penultimate
- // processing the buttons
- if ( $stepList.eq( len-2 ).hasClass( "j-active-fieldset" ) ) {
- $submitBtn.addClass( "j-hiddenBtn" );
- $nextBtn.removeClass( "j-hiddenBtn" );
- }
-
- // Get fields from active step
- self.getActiveStepField();
- });
- },
-
- /* Get fields from active step only */
- getActiveStepField: function() {
- var self = this,
- config = self.config,
- $form = self.$form,
- $el;
-
- if ( config.formType.multistep ) {
- $.each( config.rules, function( name, rules ) {
- $el = $form.find( "fieldset.j-active-fieldset [name='"+name+"']" );
- if ( $el.length ) {
- self.$formObjActiveStep[name] = $el;
- }
- });
- }
- },
-
- /* Init modal form */
- initModalForm: function() {
- var self = this,
- $form = self.$form;
-
- self.$modalWrap = $form.closest( ".j-modal-form" );
- self.$modalClose = $form.find( ".j-modal-close" );
- self.$modalOpen = $( document ).find( ".j-modal-open" );
-
- // If modal links dont exist
- if ( !self.$modalOpen.length ) {
- self.config.debugArr.push( self.config.dict.modalOpenError );
- return false;
- }
-
- self.createModalForm();
- self.processingModalForm();
- },
-
- /* Make a layout for modal form */
- createModalForm: function() {
- var self = this,
- $form = self.$form,
- $elem, $formWrap;
-
- // If a form doesn't have modal wrapper
- if ( !self.$modalWrap.length ) {
- $formWrap = $form.closest( ".j-wrapper" );
-
- // Modal wrapper
- $elem = $( "<div />", {
- class: "j-modal-form",
- id: "j-modalwrap-" + $form.attr( "id" )
- });
-
- // Wrap a form with modal wrapper
- $formWrap.wrap( $elem );
- self.$modalWrap = $form.closest( ".j-modal-form" );
- }
-
- // If a form doesn't have modal close button
- if ( !self.$modalClose.length ) {
-
- // Close button
- $elem = $( "<label />", {
- class: "j-modal-close"
- }).append( "<i></i>" );
-
- // Add close modal button to form
- $form.append( $elem );
- self.$modalClose = $form.find( ".j-modal-close" );
- }
- },
-
- /* Modal form processing */
- processingModalForm: function() {
- var self = this;
-
- // Modal links processing
- self.$modalOpen.each( function(){
- $( this ).on( "click", function( e ){
- if ( e ) {
- e.preventDefault();
- e.stopPropagation();
- }
-
- // Show modal form for approriate modal link
- if ( $( this ).data( "modal-wrap" ) === self.$modalWrap.attr( "id" ) ) {
- self.$modalWrap.addClass( "j-modal-visible" );
- $( "body" ).addClass( "j-modal-scroll" );
- }
- });
- });
-
- // Close button processing
- self.$modalClose.on( "click", function(){
- self.$modalWrap.removeClass( "j-modal-visible" );
- $( "body" ).removeClass( "j-modal-scroll" );
- });
- },
-
- /* Init hide form feature */
- initHideForm: function() {
- var self = this;
-
- self.$finalBlock = $( document ).find( ".j-final-block" );
- self.$finalBlockCloseBtn = self.$finalBlock.find( ".j-close" );
-
- self.createHideForm();
- },
-
- /* Make a layout for final block after form hidding */
- createHideForm: function() {
- var self = this,
- config = self.config,
- $form = self.$form,
- $elem;
-
- // If final block doesn't exist
- if ( !self.$finalBlock.length ) {
- $elem = $("<div />", {
- class: "j-final-block j-hidden"
- });
- $form.after( $elem.html( config.dict.successBlockText ) );
- self.$finalBlock = $form.siblings( ".j-final-block" );
- }
-
- // If "Close" btn doesn't exist
- if ( !self.$finalBlockCloseBtn.length ) {
- if ( config.formHide.closeBtn ) {
- $elem = $( "<label />", {
- class: "j-close"
- }).append( "<i></i>" );
- self.$finalBlock.append( $elem );
- self.$finalBlockCloseBtn = self.$finalBlock.find( ".j-close" );
- }
- } else {
- if ( !config.formHide.closeBtn ) {
- self.$finalBlockCloseBtn.addClass( "j-hidden" );
- }
- }
- },
-
- /* Hide form processing */
- processingHideForm: function() {
- var self = this,
- $finalBlock = self.$finalBlock,
- $finalBlockCloseBtn = self.$finalBlockCloseBtn;
-
- self.$form.addClass( "j-hidden" );
- $finalBlock.removeClass( "j-hidden" );
-
- if ( $finalBlockCloseBtn.length ) {
- $finalBlockCloseBtn.on("click", function() {
- if ( self.config.formType.modal ) {
-
- var $modalForm = $( document ).find( "div.j-modal-form" );
- if ( $modalForm.hasClass( "j-modal-visible" ) ) {
- $modalForm.removeClass( "j-modal-visible" );
- $( "body" ).removeClass( "j-modal-scroll" );
- }
- } else {
- $finalBlock.addClass( "j-hidden" );
- }
- });
- }
- },
-
- /* Reset form */
- resetForm: function() {
- var self = this,
- config = self.config,
- $input, $totalDataList;
-
- // Reset a form
- self.form.reset();
-
- // Remove success condition from the fields
- if ( config.success.highlight ){
- $input = self.$form.find( ".j-input" );
- $input.each( function(){
- $( this ).toggleClass( "j-success-view", false );
- });
- }
-
- // Clear total form data block
- if ( config.formTotalData ){
- $totalDataList = self.$totalDataBlock.find("span[data-field]");
- $.each( $totalDataList, function(){
- $( this ).html( "" );
- });
- }
- },
-
- /* Redirect form */
- redirectForm: function() {
- var self = this;
-
- $( location ).attr( "href", self.config.formRedirect.address );
- },
-
- /* Scroll to first element with error */
- scrollToError: function() {
- var self = this,
- $form = self.$form,
- $err = $form.find( ".j-error-view" ).eq(0),
- $modalWrap, $wrapper, $offset;
-
- if ( !$err.length ) {
- return false;
- }
-
- // Scroll modal form
- if ( self.config.formType.modal ){
-
- $modalWrap = $( document ).find( "#j-modalwrap-"+$form.attr("id") );
- $wrapper = $( document ).find(".j-wrapper");
- $offset = $wrapper.offset().top - $err.offset().top;
-
- $modalWrap.animate({
- scrollTop: -$offset - 60
- }, 500);
- return false;
- }
-
- // Scroll not modal form
- $("html, body").animate({
- scrollTop: $err.offset().top - 60
- }, 500);
- },
-
- /* Create a block with error messages */
- createErrorBlock: function() {
- var self = this,
- $ul = $( "<ul></ul>" ),
- elems = false,
- $formResponseBlock = self.$formResponseBlock,
- $li;
-
- // If error object contains error messages
- $.each( self.errorMessages, function( key, val ) {
- if ( val !== null ) {
- elems = true;
- return false;
- }
- });
-
- if ( elems ) {
-
- // Add class "j-error-message"
- $formResponseBlock.toggleClass( "j-error-message j-unit", true );
- $formResponseBlock.text( self.config.dict.errorBlockText ).append( $ul );
-
- $.each( self.errorMessages, function( name, mes ) {
- if ( mes !== null ) {
- $li = $( "<li></li>" ).text( mes );
- $ul.append( $li );
- }
- });
- } else {
- self.clearBlock();
- }
- },
-
- /* Create a block with success message */
- createSuccessBlock: function( msg ) {
- var self = this,
- config = self.config,
- $submitBtn = self.$submitBtn,
- $formResponseBlock = self.$formResponseBlock,
- $recaptcha = self.$form.find(".g-recaptcha");
-
- // Clear response block
- if ( $formResponseBlock.hasClass( "j-error-message" ) ) {
- self.clearBlock();
- }
-
- // Add success message
- $formResponseBlock.addClass( "j-success-message j-unit" ).text( msg );
-
- // Button enabled
- $submitBtn.removeClass( "j-processing" );
-
- // If repeated form submission is not allowed
- if ( !config.repeatSubmission ) {
-
- // Disable submit button
- $submitBtn.addClass( "j-disabled-view" ).html( config.dict.disabledBtn );
- }
-
- setTimeout(function(){
-
- self.clearBlock();
-
- // Google reCaptcha reloading
- if ( $recaptcha.length ) {
- grecaptcha.reset();
- }
-
- // If repeated form submission is allowed
- if ( config.repeatSubmission ) {
- $submitBtn.removeAttr( "disabled" );
- }
-
- // Modal form processing
- if ( config.formType.modal ) {
- $( "div.j-modal-form" ).removeClass( "j-modal-visible" );
- $( "body" ).removeClass( "j-modal-scroll" );
- }
-
- // Multistep form processing
- if ( config.formType.multistep ) {
-
- // Buttons processing
- self.$prevBtn.removeAttr( "disabled" ).addClass( "j-hiddenBtn" );
- self.$nextBtn.removeClass( "j-hiddenBtn" );
- $submitBtn.addClass( "j-hiddenBtn" );
-
- // Steps processing
- self.$stepList.removeClass( "j-active-fieldset" ).eq( 0 ).addClass( "j-active-fieldset" );
-
- // Step titles processing
- if ( self.$stepTitleList.length ){
- self.$stepTitleList.removeClass('j-active-step j-passed-step').eq(0).addClass('j-active-step');
- }
- }
- }, config.timeoutSuccessMsg);
- },
-
- /* Delete all error messages, all "error" CSS classes */
- clearForm: function() {
- var self = this,
- $form = self.$form,
- config = self.config,
- $spanErr, $tooltipErr, $input;
-
- // Clear error variables
- self.errorExists = false;
- self.errorMessages = {};
-
- // Delete error messages under the fields
- if ( config.error.underField ) {
- $spanErr = $form.find("span.j-error-view");
- $spanErr.each(function(){
- $( this ).remove();
- });
- }
-
- // Delete error messages from an error block
- if ( config.error.inBlock ) {
- self.clearBlock();
- }
-
- // Remove error condition from the fields
- if ( config.error.highlight ) {
- $input = $form.find( ".j-input" );
- $input.each( function(){
- $( this ).toggleClass( "j-error-view", false );
- });
- }
-
- // Delete tooltip error messages
- if ( config.error.inTooltip ) {
- $tooltipErr = $form.find( "span.j-tooltip.j-error-view" );
- $tooltipErr.each(function(){
- $( this ).remove();
- });
- }
- },
-
- /* Delete field's error message, field's "error" CSS classes */
- clearField: function( field ) {
- var self = this,
- config = self.config,
- errorMessages = self.errorMessages,
- fieldName = $( field ).attr("name"),
- $input, $span, $tooltip;
-
- // If a form does not have a field
- if ( self.$formObj[fieldName] === undefined || self.$formObj[fieldName] === null ){
- return false;
- }
-
- self.errorExists = false;
- $input = $( field ).closest( ".j-input" );
-
- // Delete error messages under the fields
- if ( config.error.underField ){
- $span = $input.find( "span.j-error-view" );
- if ( $span.length ) {
- $span.remove();
- }
- }
-
- // Remove error condition from the fields
- if ( config.error.highlight ) {
- $input.toggleClass( "j-error-view", false );
- }
-
- // Delete tooltip error messages
- if ( config.error.inTooltip ) {
- $tooltip = $input.find( "span.j-tooltip.j-error-view" );
- if ( $tooltip.length ) {
- $tooltip.remove();
- }
- }
-
- // Delete error message from error object
- if ( config.error.inBlock ){
- if ( errorMessages[fieldName] !== undefined && errorMessages[fieldName] !== null ) {
- errorMessages[fieldName] = null;
- }
- }
- },
-
- /* Clear a block with validation result */
- clearBlock: function() {
- var self = this;
-
- self.$formResponseBlock.removeClass( "j-error-message j-success-message j-unit" ).html( "" );
- },
- };
-
- $.fn.justFormsPro = function( options ){
- new JustFormsPro( this, options );
- return this;
- };
- }( jQuery ));
|