Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / examples / form / registration.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 Ext.require([
16     'Ext.form.*',
17     'Ext.Img',
18     'Ext.tip.QuickTipManager'
19 ]);
20
21 Ext.onReady(function() {
22     Ext.tip.QuickTipManager.init();
23
24     var formPanel = Ext.widget('form', {
25         renderTo: Ext.getBody(),
26         frame: true,
27         width: 350,
28         bodyPadding: 10,
29         bodyBorder: true,
30         title: 'Account Registration',
31
32         defaults: {
33             anchor: '100%'
34         },
35         fieldDefaults: {
36             labelAlign: 'left',
37             msgTarget: 'none',
38             invalidCls: '' //unset the invalidCls so individual fields do not get styled as invalid
39         },
40
41         /*
42          * Listen for validity change on the entire form and update the combined error icon
43          */
44         listeners: {
45             fieldvaliditychange: function() {
46                 this.updateErrorState();
47             },
48             fielderrorchange: function() {
49                 this.updateErrorState();
50             }
51         },
52
53         updateErrorState: function() {
54             var me = this,
55                 errorCmp, fields, errors;
56
57             if (me.hasBeenDirty || me.getForm().isDirty()) { //prevents showing global error when form first loads
58                 errorCmp = me.down('#formErrorState');
59                 fields = me.getForm().getFields();
60                 errors = [];
61                 fields.each(function(field) {
62                     Ext.Array.forEach(field.getErrors(), function(error) {
63                         errors.push({name: field.getFieldLabel(), error: error});
64                     });
65                 });
66                 errorCmp.setErrors(errors);
67                 me.hasBeenDirty = true;
68             }
69         },
70
71         items: [{
72             xtype: 'textfield',
73             name: 'username',
74             fieldLabel: 'User Name',
75             allowBlank: false,
76             minLength: 6
77         }, {
78             xtype: 'textfield',
79             name: 'email',
80             fieldLabel: 'Email Address',
81             vtype: 'email',
82             allowBlank: false
83         }, {
84             xtype: 'textfield',
85             name: 'password1',
86             fieldLabel: 'Password',
87             inputType: 'password',
88             style: 'margin-top:15px',
89             allowBlank: false,
90             minLength: 8
91         }, {
92             xtype: 'textfield',
93             name: 'password2',
94             fieldLabel: 'Repeat Password',
95             inputType: 'password',
96             allowBlank: false,
97             /**
98              * Custom validator implementation - checks that the value matches what was entered into
99              * the password1 field.
100              */
101             validator: function(value) {
102                 var password1 = this.previousSibling('[name=password1]');
103                 return (value === password1.getValue()) ? true : 'Passwords do not match.'
104             }
105         },
106
107         /*
108          * Terms of Use acceptance checkbox. Two things are special about this:
109          * 1) The boxLabel contains a HTML link to the Terms of Use page; a special click listener opens this
110          *    page in a modal Ext window for convenient viewing, and the Decline and Accept buttons in the window
111          *    update the checkbox's state automatically.
112          * 2) This checkbox is required, i.e. the form will not be able to be submitted unless the user has
113          *    checked the box. Ext does not have this type of validation built in for checkboxes, so we add a
114          *    custom getErrors method implementation.
115          */
116         {
117             xtype: 'checkboxfield',
118             name: 'acceptTerms',
119             fieldLabel: 'Terms of Use',
120             hideLabel: true,
121             style: 'margin-top:15px',
122             boxLabel: 'I have read and accept the <a href="http://www.sencha.com/legal/terms-of-use/" class="terms">Terms of Use</a>.',
123
124             // Listener to open the Terms of Use page link in a modal window
125             listeners: {
126                 click: {
127                     element: 'boxLabelEl',
128                     fn: function(e) {
129                         var target = e.getTarget('.terms'),
130                             win;
131                         if (target) {
132                             win = Ext.widget('window', {
133                                 title: 'Terms of Use',
134                                 modal: true,
135                                 html: '<iframe src="' + target.href + '" width="950" height="500" style="border:0"></iframe>',
136                                 buttons: [{
137                                     text: 'Decline',
138                                     handler: function() {
139                                         this.up('window').close();
140                                         formPanel.down('[name=acceptTerms]').setValue(false);
141                                     }
142                                 }, {
143                                     text: 'Accept',
144                                     handler: function() {
145                                         this.up('window').close();
146                                         formPanel.down('[name=acceptTerms]').setValue(true);
147                                     }
148                                 }]
149                             });
150                             win.show();
151                             e.preventDefault();
152                         }
153                     }
154                 }
155             },
156
157             // Custom validation logic - requires the checkbox to be checked
158             getErrors: function() {
159                 return this.getValue() ? [] : ['You must accept the Terms of Use']
160             }
161         }],
162
163         dockedItems: [{
164             xtype: 'container',
165             dock: 'bottom',
166             layout: {
167                 type: 'hbox',
168                 align: 'middle'
169             },
170             padding: '10 10 5',
171
172             items: [{
173                 xtype: 'component',
174                 id: 'formErrorState',
175                 baseCls: 'form-error-state',
176                 flex: 1,
177                 validText: 'Form is valid',
178                 invalidText: 'Form has errors',
179                 tipTpl: Ext.create('Ext.XTemplate', '<ul><tpl for="."><li><span class="field-name">{name}</span>: <span class="error">{error}</span></li></tpl></ul>'),
180
181                 getTip: function() {
182                     var tip = this.tip;
183                     if (!tip) {
184                         tip = this.tip = Ext.widget('tooltip', {
185                             target: this.el,
186                             title: 'Error Details:',
187                             autoHide: false,
188                             anchor: 'top',
189                             mouseOffset: [-11, -2],
190                             closable: true,
191                             constrainPosition: false,
192                             cls: 'errors-tip'
193                         });
194                         tip.show();
195                     }
196                     return tip;
197                 },
198
199                 setErrors: function(errors) {
200                     var me = this,
201                         baseCls = me.baseCls,
202                         tip = me.getTip();
203
204                     errors = Ext.Array.from(errors);
205
206                     // Update CSS class and tooltip content
207                     if (errors.length) {
208                         me.addCls(baseCls + '-invalid');
209                         me.removeCls(baseCls + '-valid');
210                         me.update(me.invalidText);
211                         tip.setDisabled(false);
212                         tip.update(me.tipTpl.apply(errors));
213                     } else {
214                         me.addCls(baseCls + '-valid');
215                         me.removeCls(baseCls + '-invalid');
216                         me.update(me.validText);
217                         tip.setDisabled(true);
218                         tip.hide();
219                     }
220                 }
221             }, {
222                 xtype: 'button',
223                 formBind: true,
224                 disabled: true,
225                 text: 'Submit Registration',
226                 width: 140,
227                 handler: function() {
228                     var form = this.up('form').getForm();
229
230                     /* Normally we would submit the form to the server here and handle the response...
231                     form.submit({
232                         clientValidation: true,
233                         url: 'register.php',
234                         success: function(form, action) {
235                            //...
236                         },
237                         failure: function(form, action) {
238                             //...
239                         }
240                     });
241                     */
242
243                     if (form.isValid()) {
244                         Ext.Msg.alert('Submitted Values', form.getValues(true));
245                     }
246                 }
247             }]
248         }]
249     });
250
251 });
252