Labelable.html 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  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-Labelable'>/**
  19. </span> * A mixin which allows a component to be configured and decorated with a label and/or error message as is
  20. * common for form fields. This is used by e.g. Ext.form.field.Base and Ext.form.FieldContainer
  21. * to let them be managed by the Field layout.
  22. *
  23. * NOTE: This mixin is mainly for internal library use and most users should not need to use it directly. It
  24. * is more likely you will want to use one of the component classes that import this mixin, such as
  25. * Ext.form.field.Base or Ext.form.FieldContainer.
  26. *
  27. * Use of this mixin does not make a component a field in the logical sense, meaning it does not provide any
  28. * logic or state related to values or validation; that is handled by the related Ext.form.field.Field
  29. * mixin. These two mixins may be used separately (for example Ext.form.FieldContainer is Labelable but not a
  30. * Field), or in combination (for example Ext.form.field.Base implements both and has logic for connecting the
  31. * two.)
  32. *
  33. * Component classes which use this mixin should use the Field layout
  34. * or a derivation thereof to properly size and position the label and message according to the component config.
  35. * They must also call the {@link #initLabelable} method during component initialization to ensure the mixin gets
  36. * set up correctly.
  37. *
  38. * @docauthor Jason Johnston &lt;jason@sencha.com&gt;
  39. */
  40. Ext.define(&quot;Ext.form.Labelable&quot;, {
  41. requires: ['Ext.XTemplate'],
  42. autoEl: {
  43. tag: 'table',
  44. cellpadding: 0
  45. },
  46. childEls: [
  47. <span id='Ext-form-Labelable-property-labelCell'> /**
  48. </span> * @property {Ext.Element} labelCell
  49. * The `&lt;TD&gt;` Element which contains the label Element for this component. Only available after the component has been rendered.
  50. */
  51. 'labelCell',
  52. <span id='Ext-form-Labelable-property-labelEl'> /**
  53. </span> * @property {Ext.Element} labelEl
  54. * The label Element for this component. Only available after the component has been rendered.
  55. */
  56. 'labelEl',
  57. <span id='Ext-form-Labelable-property-bodyEl'> /**
  58. </span> * @property {Ext.Element} bodyEl
  59. * The div Element wrapping the component's contents. Only available after the component has been rendered.
  60. */
  61. 'bodyEl',
  62. // private - the TD which contains the msgTarget: 'side' error icon
  63. 'sideErrorCell',
  64. <span id='Ext-form-Labelable-property-errorEl'> /**
  65. </span> * @property {Ext.Element} errorEl
  66. * The div Element that will contain the component's error message(s). Note that depending on the configured
  67. * {@link #msgTarget}, this element may be hidden in favor of some other form of presentation, but will always
  68. * be present in the DOM for use by assistive technologies.
  69. */
  70. 'errorEl',
  71. 'inputRow',
  72. 'bottomPlaceHolder'
  73. ],
  74. <span id='Ext-form-Labelable-cfg-labelableRenderTpl'> /**
  75. </span> * @cfg {String/String[]/Ext.XTemplate} labelableRenderTpl
  76. * The rendering template for the field decorations. Component classes using this mixin
  77. * should include logic to use this as their {@link Ext.AbstractComponent#renderTpl renderTpl},
  78. * and implement the {@link #getSubTplMarkup} method to generate the field body content.
  79. *
  80. * The structure of a field is a table as follows:
  81. *
  82. * If `labelAlign: 'left', `msgTarget: 'side'`
  83. *
  84. * +----------------------+----------------------+-------------+
  85. * | Label: | InputField | sideErrorEl |
  86. * +----------------------+----------------------+-------------+
  87. *
  88. * If `labelAlign: 'left', `msgTarget: 'under'`
  89. *
  90. * +----------------------+------------------------------------+
  91. * | Label: | InputField (colspan=2) |
  92. * | | underErrorEl |
  93. * +----------------------+------------------------------------+
  94. *
  95. * If `labelAlign: 'top', `msgTarget: 'side'`
  96. *
  97. * +---------------------------------------------+-------------+
  98. * | label | |
  99. * | InputField | sideErrorEl |
  100. * +---------------------------------------------+-------------+
  101. *
  102. * If `labelAlign: 'top', `msgTarget: 'under'`
  103. *
  104. * +-----------------------------------------------------------+
  105. * | label |
  106. * | InputField (colspan=2) |
  107. * | underErrorEl |
  108. * +-----------------------------------------------------------+
  109. *
  110. * The total columns always the same for fields with each setting of {@link #labelAlign} because when
  111. * rendered into a {@link Ext.layout.container.Form} layout, just the `TR` of the table
  112. * will be placed into the form's main `TABLE`, and the columns of all the siblings
  113. * must match so that they all line up. In a {@link Ext.layout.container.Form} layout, different
  114. * settings of {@link #labelAlign} are not supported because of the incompatible column structure.
  115. *
  116. * When the triggerCell or side error cell are hidden or shown, the input cell's colspan
  117. * is recalculated to maintain the correct 3 visible column count.
  118. * @private
  119. */
  120. labelableRenderTpl: [
  121. // body row. If a heighted Field (eg TextArea, HtmlEditor, this must greedily consume height.
  122. '&lt;tr id=&quot;{id}-inputRow&quot; &lt;tpl if=&quot;inFormLayout&quot;&gt;id=&quot;{id}&quot;&lt;/tpl&gt;&gt;',
  123. // Label cell
  124. '&lt;tpl if=&quot;labelOnLeft&quot;&gt;',
  125. '&lt;td id=&quot;{id}-labelCell&quot; style=&quot;{labelCellStyle}&quot; {labelCellAttrs}&gt;',
  126. '{beforeLabelTpl}',
  127. '&lt;label id=&quot;{id}-labelEl&quot; {labelAttrTpl}&lt;tpl if=&quot;inputId&quot;&gt; for=&quot;{inputId}&quot;&lt;/tpl&gt; class=&quot;{labelCls}&quot;',
  128. '&lt;tpl if=&quot;labelStyle&quot;&gt; style=&quot;{labelStyle}&quot;&lt;/tpl&gt;&gt;',
  129. '{beforeLabelTextTpl}',
  130. '&lt;tpl if=&quot;fieldLabel&quot;&gt;{fieldLabel}{labelSeparator}&lt;/tpl&gt;',
  131. '{afterLabelTextTpl}',
  132. '&lt;/label&gt;',
  133. '{afterLabelTpl}',
  134. '&lt;/td&gt;',
  135. '&lt;/tpl&gt;',
  136. // Body of the input. That will be an input element, or, from a TriggerField, a table containing an input cell and trigger cell(s)
  137. '&lt;td class=&quot;{baseBodyCls} {fieldBodyCls}&quot; id=&quot;{id}-bodyEl&quot; colspan=&quot;{bodyColspan}&quot; role=&quot;presentation&quot;&gt;',
  138. '{beforeBodyEl}',
  139. // Label just sits on top of the input field if labelAlign === 'top'
  140. '&lt;tpl if=&quot;labelAlign==\'top\'&quot;&gt;',
  141. '{beforeLabelTpl}',
  142. '&lt;div id=&quot;{id}-labelCell&quot; style=&quot;{labelCellStyle}&quot;&gt;',
  143. '&lt;label id=&quot;{id}-labelEl&quot; {labelAttrTpl}&lt;tpl if=&quot;inputId&quot;&gt; for=&quot;{inputId}&quot;&lt;/tpl&gt; class=&quot;{labelCls}&quot;',
  144. '&lt;tpl if=&quot;labelStyle&quot;&gt; style=&quot;{labelStyle}&quot;&lt;/tpl&gt;&gt;',
  145. '{beforeLabelTextTpl}',
  146. '&lt;tpl if=&quot;fieldLabel&quot;&gt;{fieldLabel}{labelSeparator}&lt;/tpl&gt;',
  147. '{afterLabelTextTpl}',
  148. '&lt;/label&gt;',
  149. '&lt;/div&gt;',
  150. '{afterLabelTpl}',
  151. '&lt;/tpl&gt;',
  152. '{beforeSubTpl}',
  153. '{[values.$comp.getSubTplMarkup()]}',
  154. '{afterSubTpl}',
  155. // Final TD. It's a side error element unless there's a floating external one
  156. '&lt;tpl if=&quot;msgTarget===\'side\'&quot;&gt;',
  157. '{afterBodyEl}',
  158. '&lt;/td&gt;',
  159. '&lt;td id=&quot;{id}-sideErrorCell&quot; vAlign=&quot;{[values.labelAlign===\'top\' &amp;&amp; !values.hideLabel ? \'bottom\' : \'middle\']}&quot; style=&quot;{[values.autoFitErrors ? \'display:none\' : \'\']}&quot; width=&quot;{errorIconWidth}&quot;&gt;',
  160. '&lt;div id=&quot;{id}-errorEl&quot; class=&quot;{errorMsgCls}&quot; style=&quot;display:none;width:{errorIconWidth}px&quot;&gt;&lt;/div&gt;',
  161. '&lt;/td&gt;',
  162. '&lt;tpl elseif=&quot;msgTarget==\'under\'&quot;&gt;',
  163. '&lt;div id=&quot;{id}-errorEl&quot; class=&quot;{errorMsgClass}&quot; colspan=&quot;2&quot; style=&quot;display:none&quot;&gt;&lt;/div&gt;',
  164. '{afterBodyEl}',
  165. '&lt;/td&gt;',
  166. '&lt;/tpl&gt;',
  167. '&lt;/tr&gt;',
  168. {
  169. disableFormats: true
  170. }
  171. ],
  172. <span id='Ext-form-Labelable-cfg-activeErrorsTpl'> /**
  173. </span> * @cfg {String/String[]/Ext.XTemplate} activeErrorsTpl
  174. * The template used to format the Array of error messages passed to {@link #setActiveErrors} into a single HTML
  175. * string. By default this renders each message as an item in an unordered list.
  176. */
  177. activeErrorsTpl: [
  178. '&lt;tpl if=&quot;errors &amp;&amp; errors.length&quot;&gt;',
  179. '&lt;ul&gt;&lt;tpl for=&quot;errors&quot;&gt;&lt;li&gt;{.}&lt;/li&gt;&lt;/tpl&gt;&lt;/ul&gt;',
  180. '&lt;/tpl&gt;'
  181. ],
  182. <span id='Ext-form-Labelable-property-isFieldLabelable'> /**
  183. </span> * @property {Boolean} isFieldLabelable
  184. * Flag denoting that this object is labelable as a field. Always true.
  185. */
  186. isFieldLabelable: true,
  187. <span id='Ext-form-Labelable-cfg-formItemCls'> /**
  188. </span> * @cfg {String} formItemCls
  189. * A CSS class to be applied to the outermost element to denote that it is participating in the form field layout.
  190. */
  191. formItemCls: Ext.baseCSSPrefix + 'form-item',
  192. <span id='Ext-form-Labelable-cfg-labelCls'> /**
  193. </span> * @cfg {String} labelCls
  194. * The CSS class to be applied to the label element. This (single) CSS class is used to formulate the renderSelector
  195. * and drives the field layout where it is concatenated with a hyphen ('-') and {@link #labelAlign}. To add
  196. * additional classes, use {@link #labelClsExtra}.
  197. */
  198. labelCls: Ext.baseCSSPrefix + 'form-item-label',
  199. <span id='Ext-form-Labelable-cfg-labelClsExtra'> /**
  200. </span> * @cfg {String} labelClsExtra
  201. * An optional string of one or more additional CSS classes to add to the label element. Defaults to empty.
  202. */
  203. <span id='Ext-form-Labelable-cfg-errorMsgCls'> /**
  204. </span> * @cfg {String} errorMsgCls
  205. * The CSS class to be applied to the error message element.
  206. */
  207. errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg',
  208. <span id='Ext-form-Labelable-cfg-baseBodyCls'> /**
  209. </span> * @cfg {String} baseBodyCls
  210. * The CSS class to be applied to the body content element.
  211. */
  212. baseBodyCls: Ext.baseCSSPrefix + 'form-item-body',
  213. <span id='Ext-form-Labelable-cfg-fieldBodyCls'> /**
  214. </span> * @cfg {String} fieldBodyCls
  215. * An extra CSS class to be applied to the body content element in addition to {@link #baseBodyCls}.
  216. */
  217. fieldBodyCls: '',
  218. <span id='Ext-form-Labelable-cfg-clearCls'> /**
  219. </span> * @cfg {String} clearCls
  220. * The CSS class to be applied to the special clearing div rendered directly after the field contents wrapper to
  221. * provide field clearing.
  222. */
  223. clearCls: Ext.baseCSSPrefix + 'clear',
  224. <span id='Ext-form-Labelable-cfg-invalidCls'> /**
  225. </span> * @cfg {String} invalidCls
  226. * The CSS class to use when marking the component invalid.
  227. */
  228. invalidCls : Ext.baseCSSPrefix + 'form-invalid',
  229. <span id='Ext-form-Labelable-cfg-fieldLabel'> /**
  230. </span> * @cfg {String} fieldLabel
  231. * The label for the field. It gets appended with the {@link #labelSeparator}, and its position and sizing is
  232. * determined by the {@link #labelAlign}, {@link #labelWidth}, and {@link #labelPad} configs.
  233. */
  234. fieldLabel: undefined,
  235. <span id='Ext-form-Labelable-cfg-labelAlign'> /**
  236. </span> * @cfg {String} labelAlign
  237. * Controls the position and alignment of the {@link #fieldLabel}. Valid values are:
  238. *
  239. * - &quot;left&quot; (the default) - The label is positioned to the left of the field, with its text aligned to the left.
  240. * Its width is determined by the {@link #labelWidth} config.
  241. * - &quot;top&quot; - The label is positioned above the field.
  242. * - &quot;right&quot; - The label is positioned to the left of the field, with its text aligned to the right.
  243. * Its width is determined by the {@link #labelWidth} config.
  244. */
  245. labelAlign : 'left',
  246. <span id='Ext-form-Labelable-cfg-labelWidth'> /**
  247. </span> * @cfg {Number} labelWidth
  248. * The width of the {@link #fieldLabel} in pixels. Only applicable if the {@link #labelAlign} is set to &quot;left&quot; or
  249. * &quot;right&quot;.
  250. */
  251. labelWidth: 100,
  252. <span id='Ext-form-Labelable-cfg-labelPad'> /**
  253. </span> * @cfg {Number} labelPad
  254. * The amount of space in pixels between the {@link #fieldLabel} and the input field.
  255. */
  256. labelPad : 5,
  257. //&lt;locale&gt;
  258. <span id='Ext-form-Labelable-cfg-labelSeparator'> /**
  259. </span> * @cfg {String} labelSeparator
  260. * Character(s) to be inserted at the end of the {@link #fieldLabel label text}.
  261. *
  262. * Set to empty string to hide the separator completely.
  263. */
  264. labelSeparator : ':',
  265. //&lt;/locale&gt;
  266. <span id='Ext-form-Labelable-cfg-labelStyle'> /**
  267. </span> * @cfg {String} labelStyle
  268. * A CSS style specification string to apply directly to this field's label.
  269. */
  270. <span id='Ext-form-Labelable-cfg-hideLabel'> /**
  271. </span> * @cfg {Boolean} hideLabel
  272. * Set to true to completely hide the label element ({@link #fieldLabel} and {@link #labelSeparator}). Also see
  273. * {@link #hideEmptyLabel}, which controls whether space will be reserved for an empty fieldLabel.
  274. */
  275. hideLabel: false,
  276. <span id='Ext-form-Labelable-cfg-hideEmptyLabel'> /**
  277. </span> * @cfg {Boolean} hideEmptyLabel
  278. * When set to true, the label element ({@link #fieldLabel} and {@link #labelSeparator}) will be automatically
  279. * hidden if the {@link #fieldLabel} is empty. Setting this to false will cause the empty label element to be
  280. * rendered and space to be reserved for it; this is useful if you want a field without a label to line up with
  281. * other labeled fields in the same form.
  282. *
  283. * If you wish to unconditionall hide the label even if a non-empty fieldLabel is configured, then set the
  284. * {@link #hideLabel} config to true.
  285. */
  286. hideEmptyLabel: true,
  287. <span id='Ext-form-Labelable-cfg-preventMark'> /**
  288. </span> * @cfg {Boolean} preventMark
  289. * true to disable displaying any {@link #setActiveError error message} set on this object.
  290. */
  291. preventMark: false,
  292. <span id='Ext-form-Labelable-cfg-autoFitErrors'> /**
  293. </span> * @cfg {Boolean} autoFitErrors
  294. * Whether to adjust the component's body area to make room for 'side' or 'under' {@link #msgTarget error messages}.
  295. */
  296. autoFitErrors: true,
  297. <span id='Ext-form-Labelable-cfg-msgTarget'> /**
  298. </span> * @cfg {String} msgTarget
  299. * The location where the error message text should display. Must be one of the following values:
  300. *
  301. * - `qtip` Display a quick tip containing the message when the user hovers over the field.
  302. * This is the default.
  303. *
  304. * **{@link Ext.tip.QuickTipManager#init} must have been called for this setting to work.**
  305. *
  306. * - `title` Display the message in a default browser title attribute popup.
  307. * - `under` Add a block div beneath the field containing the error message.
  308. * - `side` Add an error icon to the right of the field, displaying the message in a popup on hover.
  309. * - `none` Don't display any error message. This might be useful if you are implementing custom error display.
  310. * - `[element id]` Add the error message directly to the innerHTML of the specified element.
  311. */
  312. msgTarget: 'qtip',
  313. <span id='Ext-form-Labelable-cfg-activeError'> /**
  314. </span> * @cfg {String} activeError
  315. * If specified, then the component will be displayed with this value as its active error when first rendered. Use
  316. * {@link #setActiveError} or {@link #unsetActiveError} to change it after component creation.
  317. */
  318. <span id='Ext-form-Labelable-property-noWrap'> /**
  319. </span> * @private
  320. * Tells the layout system that the height can be measured immediately because the width does not need setting.
  321. */
  322. noWrap: true,
  323. labelableInsertions: [
  324. <span id='Ext-form-Labelable-cfg-beforeBodyEl'> /**
  325. </span> * @cfg {String/Array/Ext.XTemplate} beforeBodyEl
  326. * An optional string or `XTemplate` configuration to insert in the field markup
  327. * at the beginning of the input containing element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
  328. * serves as the context.
  329. */
  330. 'beforeBodyEl',
  331. <span id='Ext-form-Labelable-cfg-afterBodyEl'> /**
  332. </span> * @cfg {String/Array/Ext.XTemplate} afterBodyEl
  333. * An optional string or `XTemplate` configuration to insert in the field markup
  334. * at the end of the input containing element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
  335. * serves as the context.
  336. */
  337. 'afterBodyEl',
  338. <span id='Ext-form-Labelable-cfg-beforeLabelTpl'> /**
  339. </span> * @cfg {String/Array/Ext.XTemplate} beforeLabelTpl
  340. * An optional string or `XTemplate` configuration to insert in the field markup
  341. * before the label element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
  342. * serves as the context.
  343. */
  344. 'beforeLabelTpl',
  345. <span id='Ext-form-Labelable-cfg-afterLabelTpl'> /**
  346. </span> * @cfg {String/Array/Ext.XTemplate} afterLabelTpl
  347. * An optional string or `XTemplate` configuration to insert in the field markup
  348. * after the label element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
  349. * serves as the context.
  350. */
  351. 'afterLabelTpl',
  352. <span id='Ext-form-Labelable-cfg-beforeSubTpl'> /**
  353. </span> * @cfg {String/Array/Ext.XTemplate} beforeSubTpl
  354. * An optional string or `XTemplate` configuration to insert in the field markup
  355. * before the {@link #getSubTplMarkup subTpl markup}. If an `XTemplate` is used, the
  356. * component's {@link Ext.AbstractComponent#renderData render data} serves as the context.
  357. */
  358. 'beforeSubTpl',
  359. <span id='Ext-form-Labelable-cfg-afterSubTpl'> /**
  360. </span> * @cfg {String/Array/Ext.XTemplate} afterSubTpl
  361. * An optional string or `XTemplate` configuration to insert in the field markup
  362. * after the {@link #getSubTplMarkup subTpl markup}. If an `XTemplate` is used, the
  363. * component's {@link Ext.AbstractComponent#renderData render data} serves as the context.
  364. */
  365. 'afterSubTpl',
  366. <span id='Ext-form-Labelable-cfg-beforeLabelTextTpl'> /**
  367. </span> * @cfg {String/Array/Ext.XTemplate} beforeLabelTextTpl
  368. * An optional string or `XTemplate` configuration to insert in the field markup
  369. * before the label text. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
  370. * serves as the context.
  371. */
  372. 'beforeLabelTextTpl',
  373. <span id='Ext-form-Labelable-cfg-afterLabelTextTpl'> /**
  374. </span> * @cfg {String/Array/Ext.XTemplate} afterLabelTextTpl
  375. * An optional string or `XTemplate` configuration to insert in the field markup
  376. * after the label text. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
  377. * serves as the context.
  378. */
  379. 'afterLabelTextTpl',
  380. <span id='Ext-form-Labelable-cfg-labelAttrTpl'> /**
  381. </span> * @cfg {String/Array/Ext.XTemplate} labelAttrTpl
  382. * An optional string or `XTemplate` configuration to insert in the field markup
  383. * inside the label element (as attributes). If an `XTemplate` is used, the component's
  384. * {@link Ext.AbstractComponent#renderData render data} serves as the context.
  385. */
  386. 'labelAttrTpl'
  387. ],
  388. // This is an array to avoid a split on every call to Ext.copyTo
  389. labelableRenderProps: [ 'allowBlank', 'id', 'labelAlign', 'fieldBodyCls', 'baseBodyCls',
  390. 'clearCls', 'labelSeparator', 'msgTarget' ],
  391. <span id='Ext-form-Labelable-method-initLabelable'> /**
  392. </span> * Performs initialization of this mixin. Component classes using this mixin should call this method during their
  393. * own initialization.
  394. */
  395. initLabelable: function() {
  396. var me = this,
  397. padding = me.padding;
  398. // This Component is rendered as a table. Padding doesn't work on tables
  399. // Before padding can be applied to the encapsulating table element, copy the padding into
  400. // an extraMargins property which is to be added to all computed margins post render :(
  401. if (padding) {
  402. me.padding = undefined;
  403. me.extraMargins = Ext.Element.parseBox(padding);
  404. }
  405. me.addCls(me.formItemCls);
  406. // Prevent first render of active error, at Field render time from signalling a change from undefined to &quot;
  407. me.lastActiveError = '';
  408. me.addEvents(
  409. <span id='Ext-form-Labelable-event-errorchange'> /**
  410. </span> * @event errorchange
  411. * Fires when the active error message is changed via {@link #setActiveError}.
  412. * @param {Ext.form.Labelable} this
  413. * @param {String} error The active error message
  414. */
  415. 'errorchange'
  416. );
  417. },
  418. <span id='Ext-form-Labelable-method-trimLabelSeparator'> /**
  419. </span> * Returns the trimmed label by slicing off the label separator character. Can be overridden.
  420. * @return {String} The trimmed field label, or empty string if not defined
  421. */
  422. trimLabelSeparator: function() {
  423. var me = this,
  424. separator = me.labelSeparator,
  425. label = me.fieldLabel || '',
  426. lastChar = label.substr(label.length - 1);
  427. // if the last char is the same as the label separator then slice it off otherwise just return label value
  428. return lastChar === separator ? label.slice(0, -1) : label;
  429. },
  430. <span id='Ext-form-Labelable-method-getFieldLabel'> /**
  431. </span> * Returns the label for the field. Defaults to simply returning the {@link #fieldLabel} config. Can be overridden
  432. * to provide a custom generated label.
  433. * @template
  434. * @return {String} The configured field label, or empty string if not defined
  435. */
  436. getFieldLabel: function() {
  437. return this.trimLabelSeparator();
  438. },
  439. <span id='Ext-form-Labelable-method-setFieldLabel'> /**
  440. </span> * Set the label of this field.
  441. * @param {String} label The new label. The {@link #labelSeparator} will be automatically appended to the label
  442. * string.
  443. */
  444. setFieldLabel: function(label){
  445. label = label || '';
  446. var me = this,
  447. separator = me.labelSeparator,
  448. labelEl = me.labelEl;
  449. me.fieldLabel = label;
  450. if (me.rendered) {
  451. if (Ext.isEmpty(label) &amp;&amp; me.hideEmptyLabel) {
  452. labelEl.parent().setDisplayed('none');
  453. } else {
  454. if (separator) {
  455. label = me.trimLabelSeparator() + separator;
  456. }
  457. labelEl.update(label);
  458. labelEl.parent().setDisplayed('');
  459. }
  460. me.updateLayout();
  461. }
  462. },
  463. getInsertionRenderData: function (data, names) {
  464. var i = names.length,
  465. name, value;
  466. while (i--) {
  467. name = names[i];
  468. value = this[name];
  469. if (value) {
  470. if (typeof value != 'string') {
  471. if (!value.isTemplate) {
  472. value = Ext.XTemplate.getTpl(this, name);
  473. }
  474. value = value.apply(data);
  475. }
  476. }
  477. data[name] = value || '';
  478. }
  479. return data;
  480. },
  481. <span id='Ext-form-Labelable-method-getLabelableRenderData'> /**
  482. </span> * Generates the arguments for the field decorations {@link #labelableRenderTpl rendering template}.
  483. * @return {Object} The template arguments
  484. * @protected
  485. */
  486. getLabelableRenderData: function() {
  487. var me = this,
  488. data,
  489. tempEl,
  490. topLabel = me.labelAlign === 'top';
  491. if (!Ext.form.Labelable.errorIconWidth) {
  492. Ext.form.Labelable.errorIconWidth = (tempEl = Ext.resetElement.createChild({style: 'position:absolute', cls: Ext.baseCSSPrefix + 'form-invalid-icon'})).getWidth();
  493. tempEl.remove();
  494. }
  495. data = Ext.copyTo({
  496. inFormLayout : me.ownerLayout &amp;&amp; me.ownerLayout.type === 'form',
  497. inputId : me.getInputId(),
  498. labelOnLeft : !topLabel,
  499. hideLabel : !me.hasVisibleLabel(),
  500. fieldLabel : me.getFieldLabel(),
  501. labelCellStyle : me.getLabelCellStyle(),
  502. labelCellAttrs : me.getLabelCellAttrs(),
  503. labelCls : me.getLabelCls(),
  504. labelStyle : me.getLabelStyle(),
  505. bodyColspan : me.getBodyColspan(),
  506. externalError : !me.autoFitErrors,
  507. errorMsgCls : me.getErrorMsgCls(),
  508. errorIconWidth : Ext.form.Labelable.errorIconWidth
  509. },
  510. me, me.labelableRenderProps, true);
  511. me.getInsertionRenderData(data, me.labelableInsertions);
  512. return data;
  513. },
  514. beforeLabelableRender: function() {
  515. var me = this;
  516. if (me.ownerLayout) {
  517. me.addCls(Ext.baseCSSPrefix + me.ownerLayout.type + '-form-item');
  518. }
  519. },
  520. onLabelableRender: function() {
  521. var me = this,
  522. margins,
  523. side,
  524. style = {};
  525. if (me.extraMargins) {
  526. margins = me.el.getMargin();
  527. for (side in margins) {
  528. if (margins.hasOwnProperty(side)) {
  529. style['margin-' + side] = (margins[side] + me.extraMargins[side]) + 'px';
  530. }
  531. }
  532. me.el.setStyle(style);
  533. }
  534. },
  535. <span id='Ext-form-Labelable-method-hasVisibleLabel'> /**
  536. </span> * Checks if the field has a visible label
  537. * @return {Boolean} True if the field has a visible label
  538. */
  539. hasVisibleLabel: function(){
  540. if (this.hideLabel) {
  541. return false;
  542. }
  543. return !(this.hideEmptyLabel &amp;&amp; !this.getFieldLabel());
  544. },
  545. <span id='Ext-form-Labelable-method-getBodyColspan'> /**
  546. </span> * @private
  547. * Calculates the colspan value for the body cell - the cell which contains the input field.
  548. *
  549. * The field table structure contains 4 columns:
  550. */
  551. getBodyColspan: function() {
  552. var me = this,
  553. result;
  554. if (me.msgTarget === 'side' &amp;&amp; (!me.autoFitErrors || me.hasActiveError())) {
  555. result = 1;
  556. } else {
  557. result = 2;
  558. }
  559. if (me.labelAlign !== 'top' &amp;&amp; !me.hasVisibleLabel()) {
  560. result++;
  561. }
  562. return result;
  563. },
  564. getLabelCls: function() {
  565. var labelCls = this.labelCls,
  566. labelClsExtra = this.labelClsExtra;
  567. if (this.labelAlign === 'top') {
  568. labelCls += '-top';
  569. }
  570. return labelClsExtra ? labelCls + ' ' + labelClsExtra : labelCls;
  571. },
  572. getLabelCellStyle: function() {
  573. var me = this,
  574. hideLabelCell = me.hideLabel || (!me.fieldLabel &amp;&amp; me.hideEmptyLabel);
  575. return hideLabelCell ? 'display:none;' : '';
  576. },
  577. getErrorMsgCls: function() {
  578. var me = this,
  579. hideLabelCell = (me.hideLabel || (!me.fieldLabel &amp;&amp; me.hideEmptyLabel));
  580. return me.errorMsgCls + (!hideLabelCell &amp;&amp; me.labelAlign === 'top' ? ' ' + Ext.baseCSSPrefix + 'lbl-top-err-icon' : '');
  581. },
  582. getLabelCellAttrs: function() {
  583. var me = this,
  584. labelAlign = me.labelAlign,
  585. result = '';
  586. if (labelAlign !== 'top') {
  587. result = 'valign=&quot;top&quot; halign=&quot;' + labelAlign + '&quot; width=&quot;' + (me.labelWidth + me.labelPad) + '&quot;';
  588. }
  589. return result + ' class=&quot;' + Ext.baseCSSPrefix + 'field-label-cell&quot;';
  590. },
  591. <span id='Ext-form-Labelable-method-getLabelStyle'> /**
  592. </span> * Gets any label styling for the labelEl
  593. * @private
  594. * @return {String} The label styling
  595. */
  596. getLabelStyle: function(){
  597. var me = this,
  598. labelPad = me.labelPad,
  599. labelStyle = '';
  600. // Calculate label styles up front rather than in the Field layout for speed; this
  601. // is safe because label alignment/width/pad are not expected to change.
  602. if (me.labelAlign !== 'top') {
  603. if (me.labelWidth) {
  604. labelStyle = 'width:' + me.labelWidth + 'px;';
  605. }
  606. labelStyle += 'margin-right:' + labelPad + 'px;';
  607. }
  608. return labelStyle + (me.labelStyle || '');
  609. },
  610. <span id='Ext-form-Labelable-method-getSubTplMarkup'> /**
  611. </span> * Gets the markup to be inserted into the outer template's bodyEl. Defaults to empty string, should be implemented
  612. * by classes including this mixin as needed.
  613. * @return {String} The markup to be inserted
  614. * @protected
  615. */
  616. getSubTplMarkup: function() {
  617. return '';
  618. },
  619. <span id='Ext-form-Labelable-method-getInputId'> /**
  620. </span> * Get the input id, if any, for this component. This is used as the &quot;for&quot; attribute on the label element.
  621. * Implementing subclasses may also use this as e.g. the id for their own input element.
  622. * @return {String} The input id
  623. */
  624. getInputId: function() {
  625. return '';
  626. },
  627. <span id='Ext-form-Labelable-method-getActiveError'> /**
  628. </span> * Gets the active error message for this component, if any. This does not trigger validation on its own, it merely
  629. * returns any message that the component may already hold.
  630. * @return {String} The active error message on the component; if there is no error, an empty string is returned.
  631. */
  632. getActiveError : function() {
  633. return this.activeError || '';
  634. },
  635. <span id='Ext-form-Labelable-method-hasActiveError'> /**
  636. </span> * Tells whether the field currently has an active error message. This does not trigger validation on its own, it
  637. * merely looks for any message that the component may already hold.
  638. * @return {Boolean}
  639. */
  640. hasActiveError: function() {
  641. return !!this.getActiveError();
  642. },
  643. <span id='Ext-form-Labelable-method-setActiveError'> /**
  644. </span> * Sets the active error message to the given string. This replaces the entire error message contents with the given
  645. * string. Also see {@link #setActiveErrors} which accepts an Array of messages and formats them according to the
  646. * {@link #activeErrorsTpl}. Note that this only updates the error message element's text and attributes, you'll
  647. * have to call doComponentLayout to actually update the field's layout to match. If the field extends {@link
  648. * Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
  649. * @param {String} msg The error message
  650. */
  651. setActiveError: function(msg) {
  652. this.setActiveErrors(msg);
  653. },
  654. <span id='Ext-form-Labelable-method-getActiveErrors'> /**
  655. </span> * Gets an Array of any active error messages currently applied to the field. This does not trigger validation on
  656. * its own, it merely returns any messages that the component may already hold.
  657. * @return {String[]} The active error messages on the component; if there are no errors, an empty Array is
  658. * returned.
  659. */
  660. getActiveErrors: function() {
  661. return this.activeErrors || [];
  662. },
  663. <span id='Ext-form-Labelable-method-setActiveErrors'> /**
  664. </span> * Set the active error message to an Array of error messages. The messages are formatted into a single message
  665. * string using the {@link #activeErrorsTpl}. Also see {@link #setActiveError} which allows setting the entire error
  666. * contents with a single string. Note that this only updates the error message element's text and attributes,
  667. * you'll have to call doComponentLayout to actually update the field's layout to match. If the field extends
  668. * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
  669. * @param {String[]} errors The error messages
  670. */
  671. setActiveErrors: function(errors) {
  672. errors = Ext.Array.from(errors);
  673. this.activeError = errors[0];
  674. this.activeErrors = errors;
  675. this.activeError = this.getTpl('activeErrorsTpl').apply({errors: errors});
  676. this.renderActiveError();
  677. },
  678. <span id='Ext-form-Labelable-method-unsetActiveError'> /**
  679. </span> * Clears the active error message(s). Note that this only clears the error message element's text and attributes,
  680. * you'll have to call doComponentLayout to actually update the field's layout to match. If the field extends {@link
  681. * Ext.form.field.Base} you should call {@link Ext.form.field.Base#clearInvalid clearInvalid} instead.
  682. */
  683. unsetActiveError: function() {
  684. delete this.activeError;
  685. delete this.activeErrors;
  686. this.renderActiveError();
  687. },
  688. <span id='Ext-form-Labelable-method-renderActiveError'> /**
  689. </span> * @private
  690. * Updates the rendered DOM to match the current activeError. This only updates the content and
  691. * attributes, you'll have to call doComponentLayout to actually update the display.
  692. */
  693. renderActiveError: function() {
  694. var me = this,
  695. activeError = me.getActiveError(),
  696. hasError = !!activeError;
  697. if (activeError !== me.lastActiveError) {
  698. me.fireEvent('errorchange', me, activeError);
  699. me.lastActiveError = activeError;
  700. }
  701. if (me.rendered &amp;&amp; !me.isDestroyed &amp;&amp; !me.preventMark) {
  702. // Add/remove invalid class
  703. me.el[hasError ? 'addCls' : 'removeCls'](me.invalidCls);
  704. // Update the aria-invalid attribute
  705. me.getActionEl().dom.setAttribute('aria-invalid', hasError);
  706. // Update the errorEl (There will only be one if msgTarget is 'side' or 'under') with the error message text
  707. if (me.errorEl) {
  708. me.errorEl.dom.innerHTML = activeError;
  709. }
  710. }
  711. },
  712. <span id='Ext-form-Labelable-method-setFieldDefaults'> /**
  713. </span> * Applies a set of default configuration values to this Labelable instance. For each of the properties in the given
  714. * object, check if this component hasOwnProperty that config; if not then it's inheriting a default value from its
  715. * prototype and we should apply the default value.
  716. * @param {Object} defaults The defaults to apply to the object.
  717. */
  718. setFieldDefaults: function(defaults) {
  719. var me = this,
  720. val, key;
  721. for (key in defaults) {
  722. if (defaults.hasOwnProperty(key)) {
  723. val = defaults[key];
  724. if (!me.hasOwnProperty(key)) {
  725. me[key] = val;
  726. }
  727. }
  728. }
  729. }
  730. });
  731. </pre>
  732. </body>
  733. </html>