Hybrid View

  1. #1
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,538
    Vote Rating
    380
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default [New] Remote Field Validation Plugin

    [New] Remote Field Validation Plugin


    Hi all,

    I've just posted Remote Field Validation Plugin for Form Fields.

    You can see demo here: http://aariadne.com/rvalidate

    Enjoy!
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  2. #2
    Sencha User
    Join Date
    Mar 2007
    Location
    Haarlem, Netherlands
    Posts
    1,243
    Vote Rating
    10
    TommyMaintz will become famous soon enough TommyMaintz will become famous soon enough

      0  

    Default


    Very nice plugin! This is very useful.

    p.s.
    I think the following piece of code can be removed from the the example source code. You don't use the function anywhere. In the button configuration you specify a more complete and anonymous function. (Or I just overlooked something)
    Code:
    var submit = function() {
    	form.getForm().submit({url:'echo.php', method:'post'});
    }

  3. #3
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,538
    Vote Rating
    380
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Yes, you're right. It's some stray code. I'll remove it.
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  4. #4
    Sencha User Tasm's Avatar
    Join Date
    Nov 2007
    Location
    Kazakhstan, Almaty
    Posts
    10
    Vote Rating
    0
    Tasm is on a distinguished road

      0  

    Default


    Hi.
    It's very useful plugin, thanks.
    But I'm little upgrate your plugin:
    - Changed validation logic
    - Added loading icon
    - Added Valid icon.
    Tested in IE6, Opera 9.02, FireFox 2.0.0.10

    Sory for my english, i hope i wrote understandable.

    Don't be too strict - i'm using ExtJS not long yet.
    And i'm not profi in css rules. And i don't like how i calculate left position of inserted div in function getVlmLeftPos. Please hwo can show me the better way to solve this problem.

    Now plugin looks so:
    Code:
    Ext.ux.plugins.RemoteValidator = {
    	init:function(field) {
    		 // save original functions
    		 var isValid = field.isValid;
    		 var validate = field.validate;
    		 var markInvalid = field.markInvalid;
     
    		 // apply remote validation to field
    		 Ext.apply(field, {
    				remoteValid:false,
    				requestExecuting: true,
     				isValid:function(preventMark) {
    					return isValid.call(this, preventMark) && !this.requestExecuting && this.remoteValid;
    				},
     				validate:function() {
    					if(!validate.call(this)) {
    						this.remoteValidationTask.cancel();
    						this.hideLoadingMask();
    						return false;
    					}
    
    					if (this.requestExecuting) {
    						 return false;
    					}
    					else {
    						if(this.remoteValid) {
    							 this.markValid();
    							 return true;
    						}
    						else {
    							 this.markInvalid(this.reason);
    							 return false;
    						}
    					}
    
    					return false;
    				},
    
    				getVlmLeftPos: function() {
    					if (Ext.isIE)
    						return this.width;
    					else
    						return this.getEl().getOffsetsTo(this.getEl().parent())[0] + this.getEl().getWidth() + 2;
    				},
     
    				markValid: function() {
    					this.clearInvalid();
    					
    					if (!this.validMarked){
    						this.validMarked = Ext.DomHelper.append(this.getEl().parent(), {
    							cls:'x-form-valid-icon',
    							style: 'left:' + this.getVlmLeftPos()
    						}, true)
    					}
    				},
     
     				unMarkValid: function() {
    					if (this.validMarked) {
    						this.validMarked.remove();
    						delete this.validMarked;
    					}
     				},
     
     				markInvalid: function(reason) {
     					this.unMarkValid();
     					markInvalid.call(this, reason);
     				},
     
     				showLoadingMask: function() {
    					this.requestExecuting = true;
    					this.clearInvalid();
    					this.unMarkValid();	 						
    
    					if (!this.validLoadMask){
    						this.validLoadMask = Ext.DomHelper.append(this.getEl().parent(), {
    							cls:'x-form-loading-icon',
    							style: 'left:' + this.getVlmLeftPos()
    						}, true)
    					}
     				},
     
     				hideLoadingMask: function() {
     					this.requestExecuting = false;
    					if (this.validLoadMask) {
    						this.validLoadMask.remove();
    						delete this.validLoadMask;
    					}
     				},
     
    				// private - remote validation request
    				validateRemote:function() {
    					this.rvOptions.params = this.rvOptions.params || {};
    					this.rvOptions.params.field = this.name;
    					this.rvOptions.params.value = this.getValue();
    					this.showLoadingMask();
    					this.remoteValid = false;
    					Ext.Ajax.request(this.rvOptions);
    				},
     
    				// private - remote validation request success handler
    				rvSuccess:function(response, options) {
    					this.hideLoadingMask();
    					var o;
    					try {
    						 o = Ext.decode(response.responseText);
    					}
    					catch(e) {
    						 throw this.cannotDecodeText;
    						 return false
    					}
    					
    					if('object' !== typeof o) {
    						 throw this.notObjectText;
    						 return false
    					}
    					if(true !== o.success) {
    						 throw this.serverErrorText + ': ' + o.error;
    						 return false
    					}
    					
    					var names = this.rvOptions.paramNames;
    					this.remoteValid = true === o[names.valid];
    					this.reason = o[names.reason];
    					this.validate();
    				},
     
    				// private - remote validation request failure handler
    				rvFailure:function(response, options) {
    					this.hideLoadingMask();
    					throw this.requestFailText
    					return false
    				},
     
    				// private - runs from keyup event handler
    				filterRemoteValidation:function(e) {
    					if(!e.isNavKeyPress()) {
    						 this.requestExecuting = true;
    						 this.remoteValidationTask.delay(this.remoteValidationDelay);
    					}
    				},
    				
    				// private - runs from field value changed event handler
    				forceRemoteValidation:function(e) {
    					this.remoteValidationTask.delay(0);
    				}
    		 });
     
    		 // remote validation defaults
    		 Ext.applyIf(field, {
    				remoteValidationDelay:500,
    				reason:'Server has not yet validated the value',
    				cannotDecodeText:'Cannot decode json object',
    				notObjectText:'Server response is not an object',
    				serverErrorText:'Server error',
    				requestFailText:'Server request failed'
    		 });
     
    		 // install event handlers on field render
    		 field.on({
    				render:{single:true, scope:field, fn:function() {
    					this.remoteValidationTask = new Ext.util.DelayedTask(this.validateRemote, this);
    					this.el.on({
    						'keyup': this.filterRemoteValidation,
    						'change': this.forceRemoteValidation,
    						scope: this
    					})
    				}}
    		 });
     
    		 // setup remote validation request options
    		 field.rvOptions = field.rvOptions || {};
    		 Ext.applyIf(field.rvOptions, {
    				method:'post',
    				scope: field,
    				success: field.rvSuccess,
    				failure: field.rvFailure,
    				paramNames: {
    					valid:'valid'
    					,reason:'reason'
    				}
    		});
    	}
    };
    and css:
    Code:
    .x-form-loading-icon {
    	visibility:visible;
    	display:block;
    	width:16px;
    	height:18px;
    	background:transparent url(../images/design/loading.gif) no-repeat scroll 0pt 2px;
    	position:absolute;
    	top:0px;
    }
    
    .x-form-valid-icon {
    	visibility:visible;
    	display:block;
    	width:16px;
    	height:18px;
    	background:transparent url(../images/design/valid.gif) no-repeat scroll 0pt 2px;
    	position:absolute;
    	top:0px;
    }
    Last edited by Tasm; 28 Nov 2007 at 5:04 PM. Reason: Some corrections

  5. #5
    Ext User tidal's Avatar
    Join Date
    Apr 2007
    Location
    Berlin / Germany
    Posts
    50
    Vote Rating
    0
    tidal is on a distinguished road

      0  

    Default


    Hi Saki!

    Very nice plugin and very nice code!
    Thanks for sharing!

    I know from your various postings that you are a witty guy ,
    so let me share some thoughts about your plugin.

    I took a deep look at it and think the performance can be
    a little bit improved.

    You did make the plugin a Singleton and put its configuration
    on the field-level.
    So the config is on a level which you have no control over
    and you introduce new properties (rvOptions) to the
    plugins container (field). While in most of the cases
    this will make no problems, by murphy

  6. #6
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,538
    Vote Rating
    380
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Thanks for ideas. I'll consider all of 'em in next version.

    Cheers,
    saki
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  7. #7
    Sencha User
    Join Date
    Mar 2007
    Posts
    464
    Vote Rating
    1
    JorisA is on a distinguished road

      0  

    Default


    Good to see your still doing your own stuff now you're in the developer team

    Simple but great and effective plugin! I like the way you handle json parsing errors.

  8. #8
    Ext User
    Join Date
    Nov 2007
    Posts
    11
    Vote Rating
    0
    lencho is on a distinguished road

      0  

    Default


    the firebug show the error:uncaught exception: Server error: undefined
    why??
    my server return the JSON object is [{"success":false},{"errors":"this is bad value "}] or [{"success":true}]
    please help me,thanks

  9. #9
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,538
    Vote Rating
    380
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    {"success":false, "errors":"this is bad value"}
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  10. #10
    Ext User
    Join Date
    Apr 2008
    Location
    Ravenna, Italy
    Posts
    41
    Vote Rating
    0
    mgallinucci is on a distinguished road

      0  

    Default Validation considering other fields

    Validation considering other fields


    Hi Saki,
    in my application I need to validate a field, considering other fields value, so I can't set all params when I'm creating the object. I need to specify params as functions and evaluate the function every time I validate the field; so I modified validateRemote:

    PHP Code:
    validateRemote:function() {
        
    this.rvOptions.params this.rvOptions.params || {};
        
    this.rvOptions.params.field this.name;
        
    this.rvOptions.params.value this.getValue();
        
        var 
    actualOptions = {params:{}};
        for (
    propName in this.rvOptions.params){
            var 
    this.rvOptions.params[propName];
            if (
    typeof p === 'function')
                
    actualOptions.params[propName] = p.call(this);
            else
                
    actualOptions.params[propName] = p;
        }
        
    Ext.applyIf(actualOptions,this.rvOptions);
        
        
    Ext.Ajax.request(actualOptions);

    And now I can use the plugin in this way:
    PHP Code:
    {
        
    id'titolo',
        
    name'titolo',
        
    xtype'textfield',
        
    fieldLabel'Titolo',
        
        
    plugins:[Ext.ux.plugins.RemoteValidator],
        
    rvOptions: {
            
    urlURL.isTitoloUnivoco,
            
    params:{
                
    idCategoria: function(){return Ext.getCmp('myForm').getForm().findField('idCategoria').getValue()}
           }
        }

    If you want, you can use my code in plugin.