]> git.proxmox.com Git - extjs.git/blame - extjs/build/examples/kitchensink/classic/samples/view/form/CustomErrorHandling.js
add extjs 6.0.1 sources
[extjs.git] / extjs / build / examples / kitchensink / classic / samples / view / form / CustomErrorHandling.js
CommitLineData
6527f429
DM
1/**\r
2 * This example shows a common site registration form. The form appears to be simple but\r
3 * it shows a few special things:\r
4 *\r
5 * - The display of field errors has been customized. Fields have `msgTarget: 'none'` so\r
6 * the errors are not displayed with the individual fields; instead event listeners are\r
7 * attached to the FormPanel to group up all error messages into a custom global error\r
8 * indicator, with a persistent tooltip showing the error details.\r
9 * - The "Terms of Use" link has an event handler attached so it opens the page in a modal\r
10 * Ext.Window.\r
11 * - The password fields have custom validation attached to verify the user enters the\r
12 * same value in both.\r
13 * - The submit button has `formBind: true` so it is only enabled when the form becomes\r
14 * valid.\r
15 */\r
16Ext.define('KitchenSink.view.form.CustomErrorHandling', {\r
17 extend: 'Ext.form.Panel',\r
18 xtype: 'form-customerrors',\r
19 controller: 'form-customerrors',\r
20 \r
21 //<example>\r
22 requires: [\r
23 'KitchenSink.view.form.CustomErrorHandlingController'\r
24 ],\r
25 \r
26 exampleTitle: 'Custom Error Handling',\r
27 otherContent: [{\r
28 type: 'ViewController',\r
29 path: 'classic/samples/view/form/CustomErrorHandlingController.js'\r
30 }],\r
31 //</example>\r
32 \r
33 frame: true,\r
34 width: 350,\r
35 bodyPadding: 10,\r
36 bodyBorder: true,\r
37 title: 'Account Registration',\r
38\r
39 defaults: {\r
40 anchor: '100%'\r
41 },\r
42 \r
43 fieldDefaults: {\r
44 labelWidth: 110,\r
45 labelAlign: 'left',\r
46 msgTarget: 'none',\r
47 invalidCls: '' //unset the invalidCls so individual fields do not get styled as invalid\r
48 },\r
49\r
50 /*\r
51 * Listen for validity change on the entire form and update the combined error icon\r
52 */\r
53 listeners: {\r
54 validitychange: 'updateErrorState',\r
55 errorchange: 'updateErrorState'\r
56 },\r
57\r
58 dockedItems: [{\r
59 cls: Ext.baseCSSPrefix + 'dd-drop-ok',\r
60 xtype: 'container',\r
61 dock: 'bottom',\r
62 layout: {\r
63 type: 'hbox',\r
64 align: 'middle'\r
65 },\r
66 padding: '10 10 5',\r
67\r
68 items: [{\r
69 xtype: 'component',\r
70 reference: 'formErrorState',\r
71 height: '100%',\r
72 invalidCls: Ext.baseCSSPrefix + 'form-invalid-icon-default',\r
73 validCls: Ext.baseCSSPrefix + 'dd-drop-icon',\r
74 baseCls: 'form-error-state',\r
75 flex: 1,\r
76 validText: 'Form is valid',\r
77 invalidText: 'Form has errors',\r
78 \r
79 tipTpl: [\r
80 '<ul class="' + Ext.baseCSSPrefix + 'list-plain">',\r
81 '<tpl for=".">',\r
82 '<li><span class="field-name">{name}</span>: ',\r
83 '<span class="error">{error}</span>',\r
84 '</li>',\r
85 '</tpl>',\r
86 '</ul>'\r
87 ],\r
88\r
89 setErrors: function(errors) {\r
90 var me = this,\r
91 tpl = me.tipTpl,\r
92 tip = me.tip;\r
93 \r
94 if (!me.tipTpl.isTemplate) {\r
95 tpl = me.tipTpl = new Ext.XTemplate(tpl);\r
96 }\r
97 \r
98 if (!tip) {\r
99 tip = me.tip = Ext.widget('tooltip', {\r
100 target: me.el,\r
101 title: 'Error Details:',\r
102 minWidth: 200,\r
103 autoHide: false,\r
104 anchor: 'top',\r
105 mouseOffset: [-11, -2],\r
106 closable: true,\r
107 constrainPosition: false,\r
108 cls: 'errors-tip'\r
109 });\r
110 }\r
111\r
112 errors = Ext.Array.from(errors);\r
113\r
114 // Update CSS class and tooltip content\r
115 if (errors.length) {\r
116 me.addCls(me.invalidCls);\r
117 me.removeCls(me.validCls);\r
118 me.update(me.invalidText);\r
119 tip.setDisabled(false);\r
120 tip.update(tpl.apply(errors));\r
121 tip.show();\r
122 }\r
123 else {\r
124 me.addCls(me.validCls);\r
125 me.removeCls(me.invalidCls);\r
126 me.update(me.validText);\r
127 tip.setDisabled(true);\r
128 tip.hide();\r
129 }\r
130 }\r
131 }, {\r
132 xtype: 'button',\r
133 formBind: true,\r
134 disabled: true,\r
135 text: 'Submit Registration',\r
136 minWidth: 140,\r
137 listeners: {\r
138 click: 'submitRegistration'\r
139 }\r
140 }]\r
141 }],\r
142 \r
143 items: [{\r
144 xtype: 'textfield',\r
145 name: 'username',\r
146 fieldLabel: 'User Name',\r
147 allowBlank: false,\r
148 minLength: 6\r
149 }, {\r
150 xtype: 'textfield',\r
151 name: 'email',\r
152 fieldLabel: 'Email Address',\r
153 vtype: 'email',\r
154 allowBlank: false\r
155 }, {\r
156 xtype: 'textfield',\r
157 name: 'password1',\r
158 fieldLabel: 'Password',\r
159 inputType: 'password',\r
160 style: 'margin-top: 15px',\r
161 allowBlank: false,\r
162 minLength: 8\r
163 }, {\r
164 xtype: 'textfield',\r
165 name: 'password2',\r
166 fieldLabel: 'Repeat Password',\r
167 inputType: 'password',\r
168 allowBlank: false,\r
169 \r
170 /*\r
171 * Custom validator implementation - checks that the value matches what was entered into\r
172 * the password1 field.\r
173 */\r
174 validator: function(value) {\r
175 var password1 = this.previousSibling('[name=password1]');\r
176 return (value === password1.getValue()) ? true : 'Passwords do not match.'\r
177 }\r
178 },\r
179\r
180 /*\r
181 * Terms of Use acceptance checkbox. Two things are special about this:\r
182 * 1) The boxLabel contains a HTML link to the Terms of Use page; a special\r
183 * click listener opens this page in a modal Ext window for convenient viewing,\r
184 * and the Decline and Accept buttons in the window update the checkbox's state\r
185 * automatically.\r
186 * 2) This checkbox is required, i.e. the form will not be able to be submitted\r
187 * unless the user has checked the box. Ext does not have this type of validation\r
188 * built in for checkboxes, so we add a custom getErrors method implementation.\r
189 */\r
190 {\r
191 xtype: 'checkboxfield',\r
192 name: 'acceptTerms',\r
193 reference: 'acceptTerms',\r
194 fieldLabel: 'Terms of Use',\r
195 hideLabel: true,\r
196 margin: '15 0 0 0',\r
197 boxLabel: 'I have read and accept the <a href="#" class="terms">Terms of Use</a>.',\r
198\r
199 // Listener to open the Terms of Use page link in a modal window\r
200 // Note that the listener method itself is defined in the ViewController\r
201 listeners: {\r
202 click: {\r
203 element: 'boxLabelEl',\r
204 fn: 'onTermsOfUseElementClick'\r
205 }\r
206 },\r
207\r
208 // Custom validation logic - requires the checkbox to be checked\r
209 getErrors: function() {\r
210 return this.getValue() ? [] : ['You must accept the Terms of Use']\r
211 }\r
212 }, {\r
213 // The window is added to the form's children array to be handled\r
214 // by the form's ViewController. In a more complicated case we would\r
215 // probably want the window to have its own ViewController.\r
216 xtype: 'window',\r
217 reference: 'termsOfUseWindow',\r
218 closeAction: 'hide',\r
219 title: 'Terms of Use',\r
220 modal: true,\r
221 width: 700,\r
222 height: 400,\r
223 bodyPadding: '10 20',\r
224 scrollable: true,\r
225\r
226 // Wall of text\r
227 loader: {\r
228 url: 'data/form/terms-of-use.html',\r
229 autoLoad: true\r
230 },\r
231 \r
232 buttons: [{\r
233 text: 'Decline',\r
234 handler: 'declineTermsOfUse'\r
235 }, {\r
236 text: 'Accept',\r
237 handler: 'acceptTermsOfUse'\r
238 }]\r
239 }],\r
240\r
241 beforeDestroy: function() {\r
242 var error = this.lookupReference('formErrorState');\r
243 if (error) {\r
244 Ext.destroy(error.tip);\r
245 }\r
246 this.callParent();\r
247 }\r
248});\r