/** * A {@link Ext.ux.statusbar.StatusBar} plugin that provides automatic error * notification when the associated form contains validation errors. */ Ext.define('Ext.ux.statusbar.ValidationStatus', { extend: 'Ext.Component', requires: ['Ext.util.MixedCollection'], /** * @cfg {String} errorIconCls * The {@link Ext.ux.statusbar.StatusBar#iconCls iconCls} value to be applied * to the status message when there is a validation error. */ errorIconCls : 'x-status-error', /** * @cfg {String} errorListCls * The css class to be used for the error list when there are validation errors. */ errorListCls : 'x-status-error-list', /** * @cfg {String} validIconCls * The {@link Ext.ux.statusbar.StatusBar#iconCls iconCls} value to be applied * to the status message when the form validates. */ validIconCls : 'x-status-valid', /** * @cfg {String} showText * The {@link Ext.ux.statusbar.StatusBar#text text} value to be applied when * there is a form validation error. */ showText : 'The form has errors (click for details...)', /** * @cfg {String} hideText * The {@link Ext.ux.statusbar.StatusBar#text text} value to display when * the error list is displayed. */ hideText : 'Click again to hide the error list', /** * @cfg {String} submitText * The {@link Ext.ux.statusbar.StatusBar#text text} value to be applied when * the form is being submitted. */ submitText : 'Saving...', // private init : function(sb){ sb.on('render', function(){ this.statusBar = sb; this.monitor = true; this.errors = Ext.create('Ext.util.MixedCollection'); this.listAlign = (sb.statusAlign === 'right' ? 'br-tr?' : 'bl-tl?'); if (this.form) { this.formPanel = Ext.getCmp(this.form); this.basicForm = this.formPanel.getForm(); this.startMonitoring(); this.basicForm.on('beforeaction', function(f, action){ if(action.type === 'submit'){ // Ignore monitoring while submitting otherwise the field validation // events cause the status message to reset too early this.monitor = false; } }, this); var startMonitor = function(){ this.monitor = true; }; this.basicForm.on('actioncomplete', startMonitor, this); this.basicForm.on('actionfailed', startMonitor, this); } }, this, {single:true}); sb.on({ scope: this, afterlayout:{ single: true, fn: function(){ // Grab the statusEl after the first layout. sb.statusEl.getEl().on('click', this.onStatusClick, this, {buffer:200}); } }, beforedestroy:{ single: true, fn: this.onDestroy } }); }, // private startMonitoring : function() { this.basicForm.getFields().each(function(f){ f.on('validitychange', this.onFieldValidation, this); }, this); }, // private stopMonitoring : function(){ this.basicForm.getFields().each(function(f){ f.un('validitychange', this.onFieldValidation, this); }, this); }, // private onDestroy : function(){ this.stopMonitoring(); this.statusBar.statusEl.un('click', this.onStatusClick, this); this.callParent(arguments); }, // private onFieldValidation : function(f, isValid){ if (!this.monitor) { return false; } var msg = f.getErrors()[0]; if (msg) { this.errors.add(f.id, {field:f, msg:msg}); } else { this.errors.removeAtKey(f.id); } this.updateErrorList(); if(this.errors.getCount() > 0) { if(this.statusBar.getText() !== this.showText){ this.statusBar.setStatus({text:this.showText, iconCls:this.errorIconCls}); } }else{ this.statusBar.clearStatus().setIcon(this.validIconCls); } }, // private updateErrorList : function(){ if(this.errors.getCount() > 0){ var msg = '