From b58c3448060c59f088bece393d4a8c32097c0213 Mon Sep 17 00:00:00 2001 From: Guillaume Potier Date: Mon, 21 Jan 2013 23:21:45 +0100 Subject: [PATCH] - updated doc. Added onFieldSuccess listener. Refs #17 --- dist/parsley-standalone.min.js | 20 ++++++++++---------- dist/parsley.extend.min.js | 2 +- dist/parsley.min.js | 20 ++++++++++---------- documentation.html | 28 +++++++++++++++++++++++++++- parsley.js | 18 ++++++++++++++---- tests/tests.js | 12 ++++++++++-- 6 files changed, 72 insertions(+), 28 deletions(-) diff --git a/dist/parsley-standalone.min.js b/dist/parsley-standalone.min.js index b90b5e396..a2b6f3d82 100644 --- a/dist/parsley-standalone.min.js +++ b/dist/parsley-standalone.min.js @@ -1,4 +1,4 @@ -/* Parsley dist/parsley-standalone.min.js build version 1.1.0 http://parsleyjs.org */ +/* Parsley dist/parsley-standalone.min.js build version 1.1.1 http://parsleyjs.org */ var Zepto=function(){function b(c){return"[object Function]"==M.call(c)}function p(c){return c instanceof Object}function s(c){return p(c)&&c.__proto__==Object.prototype}function t(c){return c instanceof Array}function u(c){return"number"==typeof c.length}function a(c){return c.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function e(c){return c in y?y[c]:y[c]=RegExp("(^|\\s)"+c+"(\\s|$)")}function f(c){return"children"in c?x.call(c.children):d.map(c.childNodes,function(c){if(1==c.nodeType)return c})}function g(c,a,d){for(q in a)d&&s(a[q])?(s(c[q])||(c[q]={}),g(c[q],a[q],d)):a[q]!==m&&(c[q]=a[q])}function n(c,a){return a===m?d(c):d(c).filter(a)}function j(c,a,d,e){return b(a)?a.call(c,d,e):a}function k(c,a){var d=c.className,b=d&&d.baseVal!==m;if(a===m)return b?d.baseVal:d;b?d.baseVal=a:c.className=a}function z(c){var a;try{return c?"true"==c||("false"==c?!1:"null"==c?null:isNaN(a=Number(c))?/^[\[\{]/.test(c)?d.parseJSON(c): c:a):c}catch(b){return c}}function A(c,a){a(c);for(var d in c.childNodes)A(c.childNodes[d],a)}var m,q,d,v,w=[],x=w.slice,B=w.filter,l=window.document,h={},y={},D=l.defaultView.getComputedStyle,G={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},H=/^\s*<(\w+|!)[^>]*>/,N=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,I=/^(?:body|html)$/i,O="val css html text data width height offset".split(" "),E=l.createElement("table"),J=l.createElement("tr"), @@ -52,15 +52,15 @@ b){return this.minlength(a,b)},maxcheck:function(a,b){return this.maxlength(a,b) b[f];else this.messages[a]=b}};var s=function(a,b,f){this.options=b;this.Validator=new p(b);this.init(a,f||"ParsleyField");return this};s.prototype={constructor:s,init:function(a,e){this.type=e;this.isValid=!0;this.element=a;this.validatedOnce=!1;this.$element=b(a);this.val=this.$element.val();this.isRequired=!1;this.constraints=[];this.isRadioOrCheckbox=!1;this.hash=this.generateHash();this.errorClassHandler=this.options.errors.classHandler(a)||this.$element;if("undefined"!==typeof this.options.required|| this.$element.hasClass("required")||"required"===this.$element.attr("required"))this.isRequired=this.options.required=!0;this.addConstraints();this.constraints.length&&this.bindValidationEvents()},addConstraints:function(){for(var a in this.options)"function"===typeof this.Validator.validators[a.toLowerCase()]&&this.constraints.push({name:a,requirements:this.options[a],isValid:null})},bindValidationEvents:function(){this.$element.addClass("parsley-validated");var a=this.options.trigger+(/key/i.test(this.options.trigger)? "":" keyup");this.options.remote&&(a+=/change/i.test(a)?"":" change");if(a)this.$element.on(a.split(" ").join("."+this.type+" "),!1,b.proxy(this.eventValidation,this))},generateHash:function(){for(var a="",b=0;5>b;b++)a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".charAt(Math.floor(52*Math.random()));return a},getHash:function(){return this.hash},getVal:function(){return this.$element.val()},eventValidation:function(a){var b=this.getVal();if("keyup"===a.type&&!/keyup/i.test(this.options.trigger)&& -this.isValid||b.length",errorElem:"
  • "},listeners:{onFieldValidate:function(){return!1},onFormSubmit:function(){},onFieldError:function(){}}}; -b(window).on("load",function(){b.fn.parsley.defaults=b.extend(!0,{},b.fn.parsley.defaults,"undefined"!==typeof window.ParsleyConfig?ParsleyConfig:{});b('[data-validate="parsley"]').each(function(){b(this).parsley()})})}(window.jQuery||window.Zepto); +"parsleyField":"parsleyFieldMultiple"));return"function"===typeof e?e():n};b.fn.parsley.Constructor=u;b.fn.parsley.defaults={inputs:"input, textarea, select",excluded:"input[type=hidden]",trigger:!1,focus:"first",validationMinlength:3,successClass:"parsley-success",errorClass:"parsley-error",validators:{},messages:{},errors:{classHandler:function(){},container:function(){},errorsWrapper:"",errorElem:"
  • "},listeners:{onFieldValidate:function(){return!1},onFormSubmit:function(){},onFieldError:function(){}, +onFieldSuccess:function(){}}};b(window).on("load",function(){b.fn.parsley.defaults=b.extend(!0,{},b.fn.parsley.defaults,"undefined"!==typeof window.ParsleyConfig?ParsleyConfig:{});b('[data-validate="parsley"]').each(function(){b(this).parsley()})})}(window.jQuery||window.Zepto); diff --git a/dist/parsley.extend.min.js b/dist/parsley.extend.min.js index e17d7078e..25353a868 100644 --- a/dist/parsley.extend.min.js +++ b/dist/parsley.extend.min.js @@ -1,4 +1,4 @@ -/* Parsley dist/parsley.extend.min.js build version 1.1.0 http://parsleyjs.org */ +/* Parsley dist/parsley.extend.min.js build version 1.1.1 http://parsleyjs.org */ window.ParsleyConfig=window.ParsleyConfig||{}; (function(c){window.ParsleyConfig=c.extend(!0,{},window.ParsleyConfig,{validators:{minwords:function(a,b){a=a.replace(/(^\s*)|(\s*$)/gi,"");a=a.replace(/[ ]{2,}/gi," ");a=a.replace(/\n /,"\n");a=a.split(" ").length;return a>=b},maxwords:function(a,b){a=a.replace(/(^\s*)|(\s*$)/gi,"");a=a.replace(/[ ]{2,}/gi," ");a=a.replace(/\n /,"\n");a=a.split(" ").length;return a<=b},rangewords:function(a,b){a=a.replace(/(^\s*)|(\s*$)/gi,"");a=a.replace(/[ ]{2,}/gi," ");a=a.replace(/\n /,"\n");a=a.split(" ").length; return a>=b[0]&&a<=b[1]}},messages:{minwords:"This value should have %s words at least.",maxwords:"This value should have %s words maximum.",rangewords:"This value should have between %s and %s words."}})})(window.jQuery||window.Zepto); diff --git a/dist/parsley.min.js b/dist/parsley.min.js index e208f8bc0..14a7594d9 100644 --- a/dist/parsley.min.js +++ b/dist/parsley.min.js @@ -1,4 +1,4 @@ -/* Parsley dist/parsley.min.js build version 1.1.0 http://parsleyjs.org */ +/* Parsley dist/parsley.min.js build version 1.1.1 http://parsleyjs.org */ !function(d){var k=function(a){this.init(a)};k.prototype={constructor:k,messages:{defaultMessage:"This value seems to be invalid.",type:{email:"This value should be a valid email.",url:"This value should be a valid url.",urlstrict:"This value should be a valid url.",number:"This value should be a valid number.",digits:"This value should be digits.",dateIso:"This value should be a valid date (YYYY-MM-DD).",alphanum:"This value should be alphanumeric."},notnull:"This value should not be null.",notblank:"This value should not be blank.", required:"This value is required.",regexp:"This value seems to be invalid.",min:"This value should be greater than %s.",max:"This value should be lower than %s.",range:"This value should be between %s and %s.",minlength:"This value is too short. It should have %s characters or more.",maxlength:"This value is too long. It should have %s characters or less.",rangelength:"This value length is invalid. It should be between %s and %s characters long.",equalto:"This value should be the same."},validators:{notnull:function(a){return 0< a.length},notblank:function(a){return""!==a.replace(/^\s+/g,"").replace(/\s+$/g,"")},required:function(a){return"object"===typeof a?0b;b++)a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".charAt(Math.floor(52*Math.random()));return a},getHash:function(){return this.hash},getVal:function(){return this.$element.val()},eventValidation:function(a){var b=this.getVal();if("keyup"===a.type&&!/keyup/i.test(this.options.trigger)&& -this.isValid||b.length",errorElem:"
  • "},listeners:{onFieldValidate:function(){return!1},onFormSubmit:function(){},onFieldError:function(){}}}; -d(window).on("load",function(){d.fn.parsley.defaults=d.extend(!0,{},d.fn.parsley.defaults,"undefined"!==typeof window.ParsleyConfig?ParsleyConfig:{});d('[data-validate="parsley"]').each(function(){d(this).parsley()})})}(window.jQuery||window.Zepto); +"parsleyField":"parsleyFieldMultiple"));return"function"===typeof b?b():f};d.fn.parsley.Constructor=j;d.fn.parsley.defaults={inputs:"input, textarea, select",excluded:"input[type=hidden]",trigger:!1,focus:"first",validationMinlength:3,successClass:"parsley-success",errorClass:"parsley-error",validators:{},messages:{},errors:{classHandler:function(){},container:function(){},errorsWrapper:"
      ",errorElem:"
    • "},listeners:{onFieldValidate:function(){return!1},onFormSubmit:function(){},onFieldError:function(){}, +onFieldSuccess:function(){}}};d(window).on("load",function(){d.fn.parsley.defaults=d.extend(!0,{},d.fn.parsley.defaults,"undefined"!==typeof window.ParsleyConfig?ParsleyConfig:{});d('[data-validate="parsley"]').each(function(){d(this).parsley()})})}(window.jQuery||window.Zepto); diff --git a/documentation.html b/documentation.html index d9c9bffb1..fd77c217f 100644 --- a/documentation.html +++ b/documentation.html @@ -961,7 +961,8 @@

      Javascript

      , listeners: { onFieldValidate: function ( elem ) { return false; } , onFormSubmit: function ( isFormValid, event, focusedField ) {} - , onFieldError: function ( elem, constraint ) {} + , onFieldError: function ( elem, constraints ) {} + , onFieldSuccess: function ( elem, constraints ) {} } } @@ -1057,6 +1058,9 @@

      Parsley CSS

      + + Default classes & templates + .parsley-validated Auto added on each form item that have Parsley validation. @@ -1077,6 +1081,28 @@

      Parsley CSS

      li.parsley-error Message for constraint failed on validation. + + Override them ! + + + Change class names +
      $('#form').parsley({ successClass: 'my name', errorClass: 'still my name' });
      + + + Change class handler + Add parsley-success and parsley-error to direct parent: +
      $('#form').parsley( {
      +    errors: {
      +        classHandler: function ( elem ) {
      +            return $( elem ).parent();
      +        }
      +    }
      +} );
      + + + Advanced changes + See errorsWrapper, errorElem and container errors properties in Parsley default options.. + diff --git a/parsley.js b/parsley.js index c655c4fc7..b13943d71 100644 --- a/parsley.js +++ b/parsley.js @@ -453,7 +453,7 @@ return this.isValid; } - if ( this.options.listeners.onFieldValidate( this.$element ) || '' === this.val && !this.isRequired ) { + if ( this.options.listeners.onFieldValidate( this.element ) || '' === this.val && !this.isRequired ) { this.reset(); return null; } @@ -504,6 +504,14 @@ return isValid; } + /** + * Update a constraint state. Curently used by remote async validator + * + * @method updateConstraint + * @param constraintName + * @param property + * @param value + */ , updateConstraint: function ( constraintName, property, value ) { for ( var i in this.constraints ) { if ( this.constraints[ i ].name === constraintName ) { @@ -528,7 +536,6 @@ for ( var constraint in this.constraints ) { if ( false === this.constraints[ constraint ].isValid ) { this.addError( this.constraints[ constraint ] ); - this.options.listeners.onFieldError( this.$element, this.constraints[ constraint ] ); isValid = false; } else if ( true === this.constraints[ constraint ].isValid ) { this.removeError( this.constraints[ constraint ].name ); @@ -541,9 +548,11 @@ if ( true === this.isValid ) { this.removeErrors(); this.errorClassHandler.removeClass( this.options.errorClass ).addClass( this.options.successClass ); + this.options.listeners.onFieldSuccess( this.element, this.constraints ); return true; } else if ( false === this.isValid ) { this.errorClassHandler.removeClass( this.options.successClass ).addClass( this.options.errorClass ); + this.options.listeners.onFieldError( this.element, this.constraints ); return false; } @@ -895,9 +904,10 @@ , errorElem: '
    • ' // each field constraint fail in an li } , listeners: { - onFieldValidate: function ( elem ) { return false; } // Return true to ignore field validation + onFieldValidate: function ( elem ) { return false; } // Executed on validation. Return true to ignore field validation , onFormSubmit: function ( isFormValid, event, focusedField ) {} // Executed once on form validation - , onFieldError: function ( field, constraint ) {} // Executed when a field is detected as invalid + , onFieldError: function ( elem, constraints ) {} // Executed when a field is detected as invalid + , onFieldSuccess: function ( elem, constraints ) {} // Executed when a field passes validation } } diff --git a/tests/tests.js b/tests/tests.js index ee466f802..abc78f201 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -61,8 +61,11 @@ $( '#onFieldValidate-form' ).parsley( { listeners: { return false; }, - onFieldError: function ( field, constraint ) { - $( field ).addClass( 'error-' + constraint.name + '_' + constraint.requirements ); + onFieldError: function ( field, constraints ) { + $( field ).addClass( 'error-' + constraints[ 0 ].name + '_' + constraints[ 0 ].requirements ); + }, + onFieldSuccess: function ( field ) { + $( field ).addClass( 'success-foo-bar' ); }, onFormSubmit: function ( isFormValid, event, focusField ) { $( '#onFieldValidate-form' ).addClass( 'this-form-is-invalid' ); @@ -563,6 +566,11 @@ var testSuite = function () { it ( 'test onFieldError()', function () { expect( $( '#onFieldValidate2' ).hasClass( 'error-type_email' ) ).to.be( true ); } ) + it ( 'test onFieldSuccess()', function () { + $( '#onFieldValidate2' ).val( 'foo@baz.baz' ); + $( '#onFieldValidate-form' ).parsley( 'validate' ); + expect( $( '#onFieldValidate2' ).hasClass( 'success-foo-bar' ) ).to.be( true ); + } ) it ( 'test addListener onFormSubmit', function () { $( '#listeners1' ).val( 'foo' ); expect( $( '#listeners-form' ).hasClass( 'onFormSubmit-ok' ) ).to.be( false );