]> git.proxmox.com Git - extjs.git/blame - extjs/examples/kitchensink/classic/samples/view/form/Checkout.js
add extjs 6.0.1 sources
[extjs.git] / extjs / examples / kitchensink / classic / samples / view / form / Checkout.js
CommitLineData
6527f429
DM
1/**\r
2 * This shows an example of a common shopping cart checkout form. It demonstrates uses\r
3 * of FieldContainer and various layouts for arranging and aligning fields, ComboBox\r
4 * fields for state and month selection, and listening to change events to automatically\r
5 * copy values from Mailing Address to Billing Address fields.\r
6 */\r
7Ext.define('KitchenSink.view.form.Checkout', {\r
8 extend: 'Ext.form.Panel',\r
9 xtype: 'form-checkout',\r
10 \r
11 //<example>\r
12 requires: [\r
13 'KitchenSink.model.State',\r
14 'KitchenSink.store.States'\r
15 ],\r
16 \r
17 exampleTitle: 'Checkout Form',\r
18 otherContent: [{\r
19 type: 'Model',\r
20 path: 'classic/samples/model/State.js'\r
21 },{\r
22 type: 'Data',\r
23 path: 'classic/samples/data/DataSets.js'\r
24 }],\r
25 profiles: {\r
26 classic: {\r
27 formWidth: 550,\r
28 normalLabelWidth: 90,\r
29 longLabelWidth: 90,\r
30 phoneWidth: 200,\r
31 phoneLabelWidth: 100,\r
32 stateWidth: 115,\r
33 postalCodeLabelWidth: 80,\r
34 expirationMonthWidth: 100,\r
35 expirationYearWidth: 70\r
36 },\r
37 neptune: {\r
38 formWidth: 550,\r
39 normalLabelWidth: 90,\r
40 longLabelWidth: 110,\r
41 phoneWidth: 200,\r
42 phoneLabelWidth: 100,\r
43 stateWidth: 115,\r
44 postalCodeLabelWidth: 80,\r
45 expirationMonthWidth: 100,\r
46 expirationYearWidth: 70\r
47 },\r
48 'neptune-touch': {\r
49 formWidth: 650,\r
50 normalLabelWidth: 100,\r
51 longLabelWidth: 130,\r
52 phoneWidth: 230,\r
53 phoneLabelWidth: 120,\r
54 stateWidth: 125,\r
55 postalCodeLabelWidth: 90,\r
56 expirationMonthWidth: 120,\r
57 expirationYearWidth: 110\r
58 }\r
59 },\r
60 //</example>\r
61\r
62 frame: true,\r
63 title: 'Complete Check Out',\r
64 bodyPadding: 5,\r
65\r
66 initComponent: function(){\r
67 var states = new Ext.data.Store({\r
68 model: KitchenSink.model.State,\r
69 proxy: {\r
70 type: 'memory',\r
71 reader: {\r
72 type: 'array'\r
73 }\r
74 },\r
75 data: KitchenSink.data.DataSets.states\r
76 }),\r
77 billingStates = new Ext.data.Store({\r
78 model: KitchenSink.model.State,\r
79 proxy: {\r
80 type: 'memory',\r
81 reader: {\r
82 type: 'array'\r
83 }\r
84 },\r
85 data: KitchenSink.data.DataSets.states\r
86 });\r
87 \r
88 if (!this.monthStore) {\r
89 this.self.prototype.monthStore = new Ext.data.Store({\r
90 fields: ['name', 'num'],\r
91 data: (function() {\r
92 var data = new Array(12);\r
93 Ext.Array.forEach(Ext.Date.monthNames, function(name, i) {\r
94 data[i] = {name: name, num: i + 1};\r
95 });\r
96 return data;\r
97 })()\r
98 });\r
99 }\r
100\r
101 Ext.apply(this, {\r
102 width: this.profileInfo.formWidth,\r
103 fieldDefaults: {\r
104 labelAlign: 'right',\r
105 labelWidth: this.profileInfo.normalLabelWidth,\r
106 msgTarget: Ext.supports.Touch ? 'side' : 'qtip'\r
107 },\r
108\r
109 items: [{\r
110 xtype: 'fieldset',\r
111 title: 'Your Contact Information',\r
112 defaultType: 'textfield',\r
113 layout: 'anchor',\r
114 defaults: {\r
115 anchor: '100%'\r
116 },\r
117 items: [{\r
118 xtype: 'fieldcontainer',\r
119 fieldLabel: 'Name',\r
120 layout: 'hbox',\r
121 combineErrors: true,\r
122 defaultType: 'textfield',\r
123 defaults: {\r
124 hideLabel: 'true'\r
125 },\r
126 items: [{\r
127 name: 'firstName',\r
128 fieldLabel: 'First Name',\r
129 flex: 2,\r
130 emptyText: 'First',\r
131 allowBlank: false\r
132 }, {\r
133 name: 'lastName',\r
134 fieldLabel: 'Last Name',\r
135 flex: 3,\r
136 margin: '0 0 0 6',\r
137 emptyText: 'Last',\r
138 allowBlank: false\r
139 }]\r
140 }, {\r
141 xtype: 'container',\r
142 layout: 'hbox',\r
143 defaultType: 'textfield',\r
144 margin: '0 0 5 0',\r
145 items: [{\r
146 fieldLabel: 'Email Address',\r
147 name: 'email',\r
148 vtype: 'email',\r
149 flex: 1,\r
150 allowBlank: false\r
151 }, {\r
152 fieldLabel: 'Phone Number',\r
153 labelWidth: this.profileInfo.phoneLabelWidth,\r
154 name: 'phone',\r
155 width: this.profileInfo.phoneWidth,\r
156 emptyText: 'xxx-xxx-xxxx',\r
157 maskRe: /[\d\-]/,\r
158 regex: /^\d{3}-\d{3}-\d{4}$/,\r
159 regexText: 'Must be in the format xxx-xxx-xxxx'\r
160 }]\r
161 }]\r
162 }, {\r
163 xtype: 'fieldset',\r
164 title: 'Mailing Address',\r
165 defaultType: 'textfield',\r
166 layout: 'anchor',\r
167 defaults: {\r
168 anchor: '100%'\r
169 },\r
170 items: [{\r
171 labelWidth: this.profileInfo.longLabelWidth,\r
172 fieldLabel: 'Street Address',\r
173 name: 'mailingStreet',\r
174 listeners: {\r
175 scope: this,\r
176 change: this.onMailingAddrFieldChange\r
177 },\r
178 billingFieldName: 'billingStreet',\r
179 allowBlank: false\r
180 }, {\r
181 xtype: 'container',\r
182 layout: 'hbox',\r
183 margin: '0 0 5 0',\r
184 items: [{\r
185 labelWidth: this.profileInfo.longLabelWidth,\r
186 xtype: 'textfield',\r
187 fieldLabel: 'City',\r
188 name: 'mailingCity',\r
189 listeners: {\r
190 scope: this,\r
191 change: this.onMailingAddrFieldChange\r
192 },\r
193 billingFieldName: 'billingCity',\r
194 flex: 1,\r
195 allowBlank: false\r
196 }, {\r
197 xtype: 'combobox',\r
198 name: 'mailingState',\r
199 forceSelection: true,\r
200 enforceMaxLength: true,\r
201 listeners: {\r
202 scope: this,\r
203 change: this.onMailingAddrFieldChange\r
204 },\r
205 billingFieldName: 'billingState',\r
206 fieldLabel: 'State',\r
207 labelWidth: 50,\r
208 width: this.profileInfo.stateWidth,\r
209 listConfig: {\r
210 minWidth: null\r
211 },\r
212 store: states,\r
213 valueField: 'abbr',\r
214 displayField: 'abbr',\r
215 typeAhead: true,\r
216 queryMode: 'local',\r
217 allowBlank: false\r
218 }, {\r
219 xtype: 'textfield',\r
220 fieldLabel: 'Postal Code',\r
221 labelWidth: this.profileInfo.postalCodeLabelWidth,\r
222 name: 'mailingPostalCode',\r
223 listeners: {\r
224 scope: this,\r
225 change: this.onMailingAddrFieldChange\r
226 },\r
227 billingFieldName: 'billingPostalCode',\r
228 width: 160,\r
229 allowBlank: false,\r
230 maxLength: 10,\r
231 enforceMaxLength: true,\r
232 maskRe: /[\d\-]/,\r
233 regex: /^\d{5}(\-\d{4})?$/,\r
234 regexText: 'Must be in the format xxxxx or xxxxx-xxxx'\r
235 }]\r
236 }]\r
237 }, {\r
238 xtype: 'fieldset',\r
239 title: 'Billing Address',\r
240 layout: 'anchor',\r
241 defaults: {\r
242 anchor: '100%'\r
243 },\r
244 items: [{\r
245 xtype: 'checkbox',\r
246 name: 'billingSameAsMailing',\r
247 boxLabel: 'Same as Mailing Address?',\r
248 hideLabel: true,\r
249 checked: true,\r
250 margin: '0 0 10 0',\r
251 scope: this,\r
252 handler: this.onSameAddressChange\r
253 }, {\r
254 labelWidth: this.profileInfo.longLabelWidth,\r
255 xtype: 'textfield',\r
256 fieldLabel: 'Street Address',\r
257 name: 'billingStreet',\r
258 style: 'opacity:.3',\r
259 disabled: true,\r
260 allowBlank: false\r
261 }, {\r
262 xtype: 'container',\r
263 layout: 'hbox',\r
264 margin: '0 0 5 0',\r
265 items: [{\r
266 labelWidth: this.profileInfo.longLabelWidth,\r
267 xtype: 'textfield',\r
268 fieldLabel: 'City',\r
269 name: 'billingCity',\r
270 style: 'opacity:.3',\r
271 flex: 1,\r
272 disabled: true,\r
273 allowBlank: false\r
274 }, {\r
275 xtype: 'combobox',\r
276 name: 'billingState',\r
277 enforceMaxLength: true,\r
278 style: 'opacity:.3',\r
279 fieldLabel: 'State',\r
280 labelWidth: 50,\r
281 listConfig: {\r
282 minWidth: null\r
283 },\r
284 width: this.profileInfo.stateWidth,\r
285 store: billingStates,\r
286 valueField: 'abbr',\r
287 displayField: 'abbr',\r
288 typeAhead: true,\r
289 queryMode: 'local',\r
290 disabled: true,\r
291 allowBlank: false,\r
292 forceSelection: true\r
293 }, {\r
294 xtype: 'textfield',\r
295 fieldLabel: 'Postal Code',\r
296 labelWidth: this.profileInfo.postalCodeLabelWidth,\r
297 name: 'billingPostalCode',\r
298 style: 'opacity:.3',\r
299 width: 160,\r
300 disabled: true,\r
301 allowBlank: false,\r
302 maxLength: 10,\r
303 enforceMaxLength: true,\r
304 maskRe: /[\d\-]/,\r
305 regex: /^\d{5}(\-\d{4})?$/,\r
306 regexText: 'Must be in the format xxxxx or xxxxx-xxxx'\r
307 }]\r
308 }]\r
309 }, {\r
310 xtype: 'fieldset',\r
311 title: 'Payment',\r
312 layout: 'anchor',\r
313 defaults: {\r
314 anchor: '100%'\r
315 },\r
316 items: [{\r
317 xtype: 'radiogroup',\r
318 layout: {\r
319 autoFlex: false\r
320 },\r
321 defaults: {\r
322 name: 'ccType',\r
323 margin: '0 15 0 0'\r
324 },\r
325 items: [{\r
326 inputValue: 'visa',\r
327 boxLabel: 'VISA',\r
328 checked: true\r
329 }, {\r
330 inputValue: 'mastercard',\r
331 boxLabel: 'MasterCard'\r
332 }, {\r
333 inputValue: 'amex',\r
334 boxLabel: 'American Express'\r
335 }, {\r
336 inputValue: 'discover',\r
337 boxLabel: 'Discover'\r
338 }]\r
339 }, {\r
340 xtype: 'textfield',\r
341 name: 'ccName',\r
342 fieldLabel: 'Name On Card',\r
343 labelWidth: 110,\r
344 allowBlank: false\r
345 }, {\r
346 xtype: 'container',\r
347 layout: 'hbox',\r
348 margin: '0 0 5 0',\r
349 items: [{\r
350 xtype: 'textfield',\r
351 name: 'ccNumber',\r
352 fieldLabel: 'Card Number',\r
353 labelWidth: 110,\r
354 flex: 1,\r
355 allowBlank: false,\r
356 minLength: 15,\r
357 maxLength: 16,\r
358 enforceMaxLength: true,\r
359 maskRe: /\d/\r
360 }, {\r
361 xtype: 'fieldcontainer',\r
362 fieldLabel: 'Expiration',\r
363 labelWidth: 75,\r
364 layout: 'hbox',\r
365 items: [{\r
366 xtype: 'combobox',\r
367 name: 'ccExpireMonth',\r
368 displayField: 'name',\r
369 valueField: 'num',\r
370 queryMode: 'local',\r
371 emptyText: 'Month',\r
372 hideLabel: true,\r
373 margin: '0 6 0 0',\r
374 store: this.monthStore,\r
375 width: this.profileInfo.expirationMonthWidth,\r
376 allowBlank: false,\r
377 forceSelection: true\r
378 }, {\r
379 xtype: 'numberfield',\r
380 name: 'ccExpireYear',\r
381 hideLabel: true,\r
382 width: this.profileInfo.expirationYearWidth,\r
383 value: new Date().getFullYear(),\r
384 minValue: new Date().getFullYear(),\r
385 allowBlank: false\r
386 }]\r
387 }]\r
388 }]\r
389 }\r
390 ],\r
391\r
392 buttons: [{\r
393 text: 'Reset',\r
394 scope: this,\r
395 handler: this.onResetClick\r
396 }, {\r
397 text: 'Complete Purchase',\r
398 width: 150,\r
399 scope: this,\r
400 handler: this.onCompleteClick\r
401 }]\r
402 });\r
403 this.callParent();\r
404 },\r
405\r
406 onResetClick: function(){\r
407 this.getForm().reset();\r
408 },\r
409\r
410 onCompleteClick: function(){\r
411 var form = this.getForm();\r
412 if (form.isValid()) {\r
413 Ext.MessageBox.alert('Submitted Values', form.getValues(true));\r
414 }\r
415 },\r
416\r
417 onMailingAddrFieldChange: function(field){\r
418 var copyToBilling = this.down('[name=billingSameAsMailing]').getValue(),\r
419 copyField = this.down('[name=' + field.billingFieldName + ']');\r
420\r
421 if (copyToBilling) {\r
422 copyField.setValue(field.getValue());\r
423 } else {\r
424 copyField.clearInvalid();\r
425 }\r
426 },\r
427\r
428 /**\r
429 * Enables or disables the billing address fields according to whether the checkbox is checked.\r
430 * In addition to disabling the fields, they are animated to a low opacity so they don't take\r
431 * up visual attention.\r
432 */\r
433 onSameAddressChange: function(box, checked){\r
434 var fieldset = box.ownerCt;\r
435 Ext.Array.forEach(fieldset.previousSibling().query('textfield'), this.onMailingAddrFieldChange, this);\r
436 Ext.Array.forEach(fieldset.query('textfield'), function(field) {\r
437 field.setDisabled(checked);\r
438 field.el.animate({opacity: checked ? 0.3 : 1});\r
439 });\r
440 }\r
441});\r