commit extjs-2.2.1
[extjs.git] / examples / statusbar / ValidationStatus.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /**\r
10  * @class Ext.ux.ValidationStatus\r
11  * A {@link Ext.StatusBar} plugin that provides automatic error notification when the\r
12  * associated form contains validation errors.\r
13  * @extends Ext.Component\r
14  * @constructor\r
15  * Creates a new ValiationStatus plugin\r
16  * @param {Object} config A config object\r
17  */\r
18 Ext.ux.ValidationStatus = Ext.extend(Ext.Component, {\r
19     \r
20     errorIconCls : 'x-status-error',\r
21     \r
22     errorListCls : 'x-status-error-list',\r
23     \r
24     validIconCls : 'x-status-valid',\r
25     \r
26     showText : 'The form has errors (click for details...)',\r
27     \r
28     hideText : 'Click again to hide the error list',\r
29     \r
30     submitText : 'Saving...',\r
31     \r
32     // private\r
33     init : function(sb){\r
34         sb.on('render', function(){\r
35             this.statusBar = sb;\r
36             this.monitor = true;\r
37             this.errors = new Ext.util.MixedCollection();\r
38             this.listAlign = (sb.statusAlign=='right' ? 'br-tr?' : 'bl-tl?');\r
39             \r
40             if(this.form){\r
41                 this.form = Ext.getCmp(this.form).getForm();\r
42                 this.startMonitoring();\r
43                 \r
44                 // Have to give the status bar time to render since it happens in afterRender\r
45                 (function(){\r
46                     sb.statusEl.on('click', this.onStatusClick, this, {buffer:200});\r
47                 }).defer(200, this);\r
48                 \r
49                 this.form.on('beforeaction', function(f, action){\r
50                     if(action.type == 'submit'){\r
51                         // Ignore monitoring while submitting otherwise the field validation\r
52                         // events cause the status message to reset too early\r
53                         this.monitor = false;\r
54                     }\r
55                 }, this);\r
56                 var startMonitor = function(){\r
57                     this.monitor = true;\r
58                 }\r
59                 this.form.on('actioncomplete', startMonitor, this);\r
60                 this.form.on('actionfailed', startMonitor, this);\r
61             }\r
62         }, this, {single:true});\r
63     },\r
64     \r
65     // private\r
66     startMonitoring : function(){\r
67         this.form.items.each(function(f){\r
68             f.on('invalid', this.onFieldValidation, this);\r
69             f.on('valid', this.onFieldValidation, this);\r
70         }, this);\r
71     },\r
72     \r
73     // private\r
74     stopMonitoring : function(){\r
75         this.form.items.each(function(f){\r
76             f.un('invalid', this.onFieldValidation, this);\r
77             f.un('valid', this.onFieldValidation, this);\r
78         }, this);\r
79     },\r
80     \r
81     // private\r
82     onDestroy : function(){\r
83         this.stopMonitoring();\r
84         this.statusBar.statusEl.un('click', this.onStatusClick, this);\r
85         Ext.ux.ValidationStatus.superclass.onDestroy.call(this);\r
86     },\r
87     \r
88     // private\r
89     onFieldValidation : function(f, msg){\r
90         if(!this.monitor){\r
91             return false;\r
92         }\r
93         if(msg){\r
94             this.errors.add(f.id, {field:f, msg:msg});\r
95         }else{\r
96             this.errors.removeKey(f.id);\r
97         }\r
98         this.updateErrorList();\r
99         if(this.errors.getCount() > 0){\r
100             if(this.statusBar.getText() != this.showText){\r
101                 this.statusBar.setStatus({text:this.showText, iconCls:this.errorIconCls});\r
102             }\r
103         }else{\r
104             this.statusBar.clearStatus().setIcon(this.validIconCls);\r
105         }\r
106     },\r
107     \r
108     // private\r
109     updateErrorList : function(){\r
110         if(this.errors.getCount() > 0){\r
111                 var msg = '<ul>';\r
112                 this.errors.each(function(err){\r
113                     msg += ('<li id="x-err-'+ err.field.id +'"><a href="#">' + err.msg + '</a></li>');\r
114                 }, this);\r
115                 this.getMsgEl().update(msg+'</ul>');\r
116         }else{\r
117             this.getMsgEl().update('');\r
118         }\r
119     },\r
120     \r
121     // private\r
122     getMsgEl : function(){\r
123         if(!this.msgEl){\r
124             this.msgEl = Ext.DomHelper.append(Ext.getBody(), {\r
125                 cls: this.errorListCls+' x-hide-offsets'\r
126             }, true);\r
127             \r
128             this.msgEl.on('click', function(e){\r
129                 var t = e.getTarget('li', 10, true);\r
130                 if(t){\r
131                     Ext.getCmp(t.id.split('x-err-')[1]).focus();\r
132                     this.hideErrors();\r
133                 }\r
134             }, this, {stopEvent:true}); // prevent anchor click navigation\r
135         }\r
136         return this.msgEl;\r
137     },\r
138     \r
139     // private\r
140     showErrors : function(){\r
141         this.updateErrorList();\r
142         this.getMsgEl().alignTo(this.statusBar.getEl(), this.listAlign).slideIn('b', {duration:.3, easing:'easeOut'});\r
143         this.statusBar.setText(this.hideText);\r
144         this.form.getEl().on('click', this.hideErrors, this, {single:true}); // hide if the user clicks directly into the form\r
145     },\r
146     \r
147     // private\r
148     hideErrors : function(){\r
149         var el = this.getMsgEl();\r
150         if(el.isVisible()){\r
151                 el.slideOut('b', {duration:.2, easing:'easeIn'});\r
152                 this.statusBar.setText(this.showText);\r
153         }\r
154         this.form.getEl().un('click', this.hideErrors, this);\r
155     },\r
156     \r
157     // private\r
158     onStatusClick : function(){\r
159         if(this.getMsgEl().isVisible()){\r
160             this.hideErrors();\r
161         }else if(this.errors.getCount() > 0){\r
162             this.showErrors();\r
163         }\r
164     }\r
165 });