FieldContainer2.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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-form-FieldContainer'>/**
  19. </span> * FieldContainer is a derivation of {@link Ext.container.Container Container} that implements the
  20. * {@link Ext.form.Labelable Labelable} mixin. This allows it to be configured so that it is rendered with
  21. * a {@link #fieldLabel field label} and optional {@link #msgTarget error message} around its sub-items.
  22. * This is useful for arranging a group of fields or other components within a single item in a form, so
  23. * that it lines up nicely with other fields. A common use is for grouping a set of related fields under
  24. * a single label in a form.
  25. *
  26. * The container's configured {@link #cfg-items} will be layed out within the field body area according to the
  27. * configured {@link #layout} type. The default layout is `'autocontainer'`.
  28. *
  29. * Like regular fields, FieldContainer can inherit its decoration configuration from the
  30. * {@link Ext.form.Panel#fieldDefaults fieldDefaults} of an enclosing FormPanel. In addition,
  31. * FieldContainer itself can pass {@link #fieldDefaults} to any {@link Ext.form.Labelable fields}
  32. * it may itself contain.
  33. *
  34. * If you are grouping a set of {@link Ext.form.field.Checkbox Checkbox} or {@link Ext.form.field.Radio Radio}
  35. * fields in a single labeled container, consider using a {@link Ext.form.CheckboxGroup}
  36. * or {@link Ext.form.RadioGroup} instead as they are specialized for handling those types.
  37. *
  38. * # Example
  39. *
  40. * @example
  41. * Ext.create('Ext.form.Panel', {
  42. * title: 'FieldContainer Example',
  43. * width: 550,
  44. * bodyPadding: 10,
  45. *
  46. * items: [{
  47. * xtype: 'fieldcontainer',
  48. * fieldLabel: 'Last Three Jobs',
  49. * labelWidth: 100,
  50. *
  51. * // The body area will contain three text fields, arranged
  52. * // horizontally, separated by draggable splitters.
  53. * layout: 'hbox',
  54. * items: [{
  55. * xtype: 'textfield',
  56. * flex: 1
  57. * }, {
  58. * xtype: 'splitter'
  59. * }, {
  60. * xtype: 'textfield',
  61. * flex: 1
  62. * }, {
  63. * xtype: 'splitter'
  64. * }, {
  65. * xtype: 'textfield',
  66. * flex: 1
  67. * }]
  68. * }],
  69. * renderTo: Ext.getBody()
  70. * });
  71. *
  72. * # Usage of fieldDefaults
  73. *
  74. * @example
  75. * Ext.create('Ext.form.Panel', {
  76. * title: 'FieldContainer Example',
  77. * width: 350,
  78. * bodyPadding: 10,
  79. *
  80. * items: [{
  81. * xtype: 'fieldcontainer',
  82. * fieldLabel: 'Your Name',
  83. * labelWidth: 75,
  84. * defaultType: 'textfield',
  85. *
  86. * // Arrange fields vertically, stretched to full width
  87. * layout: 'anchor',
  88. * defaults: {
  89. * layout: '100%'
  90. * },
  91. *
  92. * // These config values will be applied to both sub-fields, except
  93. * // for Last Name which will use its own msgTarget.
  94. * fieldDefaults: {
  95. * msgTarget: 'under',
  96. * labelAlign: 'top'
  97. * },
  98. *
  99. * items: [{
  100. * fieldLabel: 'First Name',
  101. * name: 'firstName'
  102. * }, {
  103. * fieldLabel: 'Last Name',
  104. * name: 'lastName',
  105. * msgTarget: 'under'
  106. * }]
  107. * }],
  108. * renderTo: Ext.getBody()
  109. * });
  110. *
  111. * @docauthor Jason Johnston &lt;jason@sencha.com&gt;
  112. */
  113. Ext.define('Ext.form.FieldContainer', {
  114. extend: 'Ext.container.Container',
  115. mixins: {
  116. labelable: 'Ext.form.Labelable',
  117. fieldAncestor: 'Ext.form.FieldAncestor'
  118. },
  119. requires: 'Ext.layout.component.field.FieldContainer',
  120. alias: 'widget.fieldcontainer',
  121. componentLayout: 'fieldcontainer',
  122. componentCls: Ext.baseCSSPrefix + 'form-fieldcontainer',
  123. <span id='Ext-form-FieldContainer-cfg-combineLabels'> /**
  124. </span> * @cfg {Boolean} combineLabels
  125. * If set to true, and there is no defined {@link #fieldLabel}, the field container will automatically
  126. * generate its label by combining the labels of all the fields it contains. Defaults to false.
  127. */
  128. combineLabels: false,
  129. //&lt;locale&gt;
  130. <span id='Ext-form-FieldContainer-cfg-labelConnector'> /**
  131. </span> * @cfg {String} labelConnector
  132. * The string to use when joining the labels of individual sub-fields, when {@link #combineLabels} is
  133. * set to true. Defaults to ', '.
  134. */
  135. labelConnector: ', ',
  136. //&lt;/locale&gt;
  137. <span id='Ext-form-FieldContainer-cfg-combineErrors'> /**
  138. </span> * @cfg {Boolean} combineErrors
  139. * If set to true, the field container will automatically combine and display the validation errors from
  140. * all the fields it contains as a single error on the container, according to the configured
  141. * {@link #msgTarget}. Defaults to false.
  142. */
  143. combineErrors: false,
  144. maskOnDisable: false,
  145. fieldSubTpl: '{%this.renderContainer(out,values)%}',
  146. initComponent: function() {
  147. var me = this;
  148. // Init mixins
  149. me.initLabelable();
  150. me.initFieldAncestor();
  151. me.callParent();
  152. },
  153. beforeRender: function(){
  154. this.callParent(arguments);
  155. this.beforeLabelableRender(arguments);
  156. },
  157. <span id='Ext-form-FieldContainer-method-onLabelableAdded'> /**
  158. </span> * @protected Called when a {@link Ext.form.Labelable} instance is added to the container's subtree.
  159. * @param {Ext.form.Labelable} labelable The instance that was added
  160. */
  161. onLabelableAdded: function(labelable) {
  162. var me = this;
  163. me.mixins.fieldAncestor.onLabelableAdded.call(this, labelable);
  164. me.updateLabel();
  165. },
  166. <span id='Ext-form-FieldContainer-method-onLabelableRemoved'> /**
  167. </span> * @protected Called when a {@link Ext.form.Labelable} instance is removed from the container's subtree.
  168. * @param {Ext.form.Labelable} labelable The instance that was removed
  169. */
  170. onLabelableRemoved: function(labelable) {
  171. var me = this;
  172. me.mixins.fieldAncestor.onLabelableRemoved.call(this, labelable);
  173. me.updateLabel();
  174. },
  175. initRenderTpl: function() {
  176. var me = this;
  177. if (!me.hasOwnProperty('renderTpl')) {
  178. me.renderTpl = me.getTpl('labelableRenderTpl');
  179. }
  180. return me.callParent();
  181. },
  182. initRenderData: function() {
  183. return Ext.applyIf(this.callParent(), this.getLabelableRenderData());
  184. },
  185. <span id='Ext-form-FieldContainer-method-getFieldLabel'> /**
  186. </span> * Returns the combined field label if {@link #combineLabels} is set to true and if there is no
  187. * set {@link #fieldLabel}. Otherwise returns the fieldLabel like normal. You can also override
  188. * this method to provide a custom generated label.
  189. * @template
  190. * @return {String} The label, or empty string if none.
  191. */
  192. getFieldLabel: function() {
  193. var label = this.fieldLabel || '';
  194. if (!label &amp;&amp; this.combineLabels) {
  195. label = Ext.Array.map(this.query('[isFieldLabelable]'), function(field) {
  196. return field.getFieldLabel();
  197. }).join(this.labelConnector);
  198. }
  199. return label;
  200. },
  201. getSubTplData: function() {
  202. var ret = this.initRenderData();
  203. Ext.apply(ret, this.subTplData);
  204. return ret;
  205. },
  206. getSubTplMarkup: function() {
  207. var me = this,
  208. tpl = me.getTpl('fieldSubTpl'),
  209. html;
  210. if (!tpl.renderContent) {
  211. me.setupRenderTpl(tpl);
  212. }
  213. html = tpl.apply(me.getSubTplData());
  214. return html;
  215. },
  216. <span id='Ext-form-FieldContainer-method-updateLabel'> /**
  217. </span> * @private Updates the content of the labelEl if it is rendered
  218. */
  219. updateLabel: function() {
  220. var me = this,
  221. label = me.labelEl;
  222. if (label) {
  223. me.setFieldLabel(me.getFieldLabel());
  224. }
  225. },
  226. <span id='Ext-form-FieldContainer-method-onFieldErrorChange'> /**
  227. </span> * @private Fired when the error message of any field within the container changes, and updates the
  228. * combined error message to match.
  229. */
  230. onFieldErrorChange: function(field, activeError) {
  231. if (this.combineErrors) {
  232. var me = this,
  233. oldError = me.getActiveError(),
  234. invalidFields = Ext.Array.filter(me.query('[isFormField]'), function(field) {
  235. return field.hasActiveError();
  236. }),
  237. newErrors = me.getCombinedErrors(invalidFields);
  238. if (newErrors) {
  239. me.setActiveErrors(newErrors);
  240. } else {
  241. me.unsetActiveError();
  242. }
  243. if (oldError !== me.getActiveError()) {
  244. me.doComponentLayout();
  245. }
  246. }
  247. },
  248. <span id='Ext-form-FieldContainer-method-getCombinedErrors'> /**
  249. </span> * Takes an Array of invalid {@link Ext.form.field.Field} objects and builds a combined list of error
  250. * messages from them. Defaults to prepending each message by the field name and a colon. This
  251. * can be overridden to provide custom combined error message handling, for instance changing
  252. * the format of each message or sorting the array (it is sorted in order of appearance by default).
  253. * @param {Ext.form.field.Field[]} invalidFields An Array of the sub-fields which are currently invalid.
  254. * @return {String[]} The combined list of error messages
  255. */
  256. getCombinedErrors: function(invalidFields) {
  257. var errors = [],
  258. f,
  259. fLen = invalidFields.length,
  260. field,
  261. activeErrors, a, aLen,
  262. error, label;
  263. for (f = 0; f &lt; fLen; f++) {
  264. field = invalidFields[f];
  265. activeErrors = field.getActiveErrors();
  266. aLen = activeErrors.length;
  267. for (a = 0; a &lt; aLen; a++) {
  268. error = activeErrors[a];
  269. label = field.getFieldLabel();
  270. errors.push((label ? label + ': ' : '') + error);
  271. }
  272. }
  273. return errors;
  274. },
  275. getTargetEl: function() {
  276. return this.bodyEl || this.callParent();
  277. }
  278. });
  279. </pre>
  280. </body>
  281. </html>