ValidationStatus.html 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-ux-statusbar-ValidationStatus'>/**
  19. </span> * A {@link Ext.ux.statusbar.StatusBar} plugin that provides automatic error
  20. * notification when the associated form contains validation errors.
  21. */
  22. Ext.define('Ext.ux.statusbar.ValidationStatus', {
  23. extend: 'Ext.Component',
  24. requires: ['Ext.util.MixedCollection'],
  25. <span id='Ext-ux-statusbar-ValidationStatus-cfg-errorIconCls'> /**
  26. </span> * @cfg {String} errorIconCls
  27. * The {@link Ext.ux.statusbar.StatusBar#iconCls iconCls} value to be applied
  28. * to the status message when there is a validation error.
  29. */
  30. errorIconCls : 'x-status-error',
  31. <span id='Ext-ux-statusbar-ValidationStatus-cfg-errorListCls'> /**
  32. </span> * @cfg {String} errorListCls
  33. * The css class to be used for the error list when there are validation errors.
  34. */
  35. errorListCls : 'x-status-error-list',
  36. <span id='Ext-ux-statusbar-ValidationStatus-cfg-validIconCls'> /**
  37. </span> * @cfg {String} validIconCls
  38. * The {@link Ext.ux.statusbar.StatusBar#iconCls iconCls} value to be applied
  39. * to the status message when the form validates.
  40. */
  41. validIconCls : 'x-status-valid',
  42. <span id='Ext-ux-statusbar-ValidationStatus-cfg-showText'> /**
  43. </span> * @cfg {String} showText
  44. * The {@link Ext.ux.statusbar.StatusBar#text text} value to be applied when
  45. * there is a form validation error.
  46. */
  47. showText : 'The form has errors (click for details...)',
  48. <span id='Ext-ux-statusbar-ValidationStatus-cfg-hideText'> /**
  49. </span> * @cfg {String} hideText
  50. * The {@link Ext.ux.statusbar.StatusBar#text text} value to display when
  51. * the error list is displayed.
  52. */
  53. hideText : 'Click again to hide the error list',
  54. <span id='Ext-ux-statusbar-ValidationStatus-cfg-submitText'> /**
  55. </span> * @cfg {String} submitText
  56. * The {@link Ext.ux.statusbar.StatusBar#text text} value to be applied when
  57. * the form is being submitted.
  58. */
  59. submitText : 'Saving...',
  60. // private
  61. init : function(sb){
  62. sb.on('render', function(){
  63. this.statusBar = sb;
  64. this.monitor = true;
  65. this.errors = Ext.create('Ext.util.MixedCollection');
  66. this.listAlign = (sb.statusAlign === 'right' ? 'br-tr?' : 'bl-tl?');
  67. if (this.form) {
  68. this.formPanel = Ext.getCmp(this.form);
  69. this.basicForm = this.formPanel.getForm();
  70. this.startMonitoring();
  71. this.basicForm.on('beforeaction', function(f, action){
  72. if(action.type === 'submit'){
  73. // Ignore monitoring while submitting otherwise the field validation
  74. // events cause the status message to reset too early
  75. this.monitor = false;
  76. }
  77. }, this);
  78. var startMonitor = function(){
  79. this.monitor = true;
  80. };
  81. this.basicForm.on('actioncomplete', startMonitor, this);
  82. this.basicForm.on('actionfailed', startMonitor, this);
  83. }
  84. }, this, {single:true});
  85. sb.on({
  86. scope: this,
  87. afterlayout:{
  88. single: true,
  89. fn: function(){
  90. // Grab the statusEl after the first layout.
  91. sb.statusEl.getEl().on('click', this.onStatusClick, this, {buffer:200});
  92. }
  93. },
  94. beforedestroy:{
  95. single: true,
  96. fn: this.onDestroy
  97. }
  98. });
  99. },
  100. // private
  101. startMonitoring : function() {
  102. this.basicForm.getFields().each(function(f){
  103. f.on('validitychange', this.onFieldValidation, this);
  104. }, this);
  105. },
  106. // private
  107. stopMonitoring : function(){
  108. this.basicForm.getFields().each(function(f){
  109. f.un('validitychange', this.onFieldValidation, this);
  110. }, this);
  111. },
  112. // private
  113. onDestroy : function(){
  114. this.stopMonitoring();
  115. this.statusBar.statusEl.un('click', this.onStatusClick, this);
  116. this.callParent(arguments);
  117. },
  118. // private
  119. onFieldValidation : function(f, isValid){
  120. if (!this.monitor) {
  121. return false;
  122. }
  123. var msg = f.getErrors()[0];
  124. if (msg) {
  125. this.errors.add(f.id, {field:f, msg:msg});
  126. } else {
  127. this.errors.removeAtKey(f.id);
  128. }
  129. this.updateErrorList();
  130. if(this.errors.getCount() &gt; 0) {
  131. if(this.statusBar.getText() !== this.showText){
  132. this.statusBar.setStatus({text:this.showText, iconCls:this.errorIconCls});
  133. }
  134. }else{
  135. this.statusBar.clearStatus().setIcon(this.validIconCls);
  136. }
  137. },
  138. // private
  139. updateErrorList : function(){
  140. if(this.errors.getCount() &gt; 0){
  141. var msg = '&lt;ul&gt;';
  142. this.errors.each(function(err){
  143. msg += ('&lt;li id=&quot;x-err-'+ err.field.id +'&quot;&gt;&lt;a href=&quot;#&quot;&gt;' + err.msg + '&lt;/a&gt;&lt;/li&gt;');
  144. }, this);
  145. this.getMsgEl().update(msg+'&lt;/ul&gt;');
  146. }else{
  147. this.getMsgEl().update('');
  148. }
  149. // reset msgEl size
  150. this.getMsgEl().setSize('auto', 'auto');
  151. },
  152. // private
  153. getMsgEl : function(){
  154. if(!this.msgEl){
  155. this.msgEl = Ext.DomHelper.append(Ext.getBody(), {
  156. cls: this.errorListCls
  157. }, true);
  158. this.msgEl.hide();
  159. this.msgEl.on('click', function(e){
  160. var t = e.getTarget('li', 10, true);
  161. if(t){
  162. Ext.getCmp(t.id.split('x-err-')[1]).focus();
  163. this.hideErrors();
  164. }
  165. }, this, {stopEvent:true}); // prevent anchor click navigation
  166. }
  167. return this.msgEl;
  168. },
  169. // private
  170. showErrors : function(){
  171. this.updateErrorList();
  172. this.getMsgEl().alignTo(this.statusBar.getEl(), this.listAlign).slideIn('b', {duration: 300, easing:'easeOut'});
  173. this.statusBar.setText(this.hideText);
  174. this.formPanel.el.on('click', this.hideErrors, this, {single:true}); // hide if the user clicks directly into the form
  175. },
  176. // private
  177. hideErrors : function(){
  178. var el = this.getMsgEl();
  179. if(el.isVisible()){
  180. el.slideOut('b', {duration: 300, easing:'easeIn'});
  181. this.statusBar.setText(this.showText);
  182. }
  183. this.formPanel.el.un('click', this.hideErrors, this);
  184. },
  185. // private
  186. onStatusClick : function(){
  187. if(this.getMsgEl().isVisible()){
  188. this.hideErrors();
  189. }else if(this.errors.getCount() &gt; 0){
  190. this.showErrors();
  191. }
  192. }
  193. });</pre>
  194. </body>
  195. </html>