registration.js 8.8 KB

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