Base.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. Ext.define('uas.override.form.field.Base', {
  2. override: 'Ext.form.field.Base',
  3. labelSeparator: '',
  4. labelAlign: 'right',
  5. // 支持labelclick事件
  6. enableLabelClick: false,
  7. labelClickCls: Ext.baseCSSPrefix + 'form-item-label-click',
  8. /**
  9. * @cfg {String/String[]/Ext.XTemplate} labelableRenderTpl
  10. * The rendering template for the field decorations. Component classes using this mixin
  11. * should include logic to use this as their {@link Ext.Component#renderTpl renderTpl},
  12. * and implement the {@link #getSubTplMarkup} method to generate the field body content.
  13. * @private
  14. */
  15. labelableRenderTpl: [
  16. '{beforeLabelTpl}',
  17. '<label id="{id}-labelEl" data-ref="labelEl" class="{labelCls} {labelCls}-{ui} {labelClsExtra} ',
  18. '<tpl if="enableLabelClick">{labelClickCls} </tpl>',
  19. '{childElCls} {unselectableCls}" style="{labelStyle}"',
  20. '<tpl if="inputId && !skipLabelForAttribute"> for="{inputId}"</tpl>',
  21. ' {labelAttrTpl}>',
  22. '<span class="{labelInnerCls} {labelInnerCls}-{ui}" style="{labelInnerStyle}">',
  23. '{beforeLabelTextTpl}',
  24. '<span id="{id}-labelTextEl" data-ref="labelTextEl" class="{labelTextCls}">',
  25. '<tpl if="fieldLabel">{fieldLabel}',
  26. '<tpl if="labelSeparator">{labelSeparator}</tpl>',
  27. '</tpl>',
  28. '</span>',
  29. '{afterLabelTextTpl}',
  30. '</span>',
  31. '</label>',
  32. '{afterLabelTpl}',
  33. '<div id="{id}-bodyEl" data-ref="bodyEl" role="presentation"',
  34. ' class="{baseBodyCls} {baseBodyCls}-{ui}<tpl if="fieldBodyCls">',
  35. ' {fieldBodyCls} {fieldBodyCls}-{ui}</tpl> {growCls} {extraFieldBodyCls}"',
  36. '<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>>',
  37. '{beforeBodyEl}',
  38. '{beforeSubTpl}',
  39. '{[values.$comp.getSubTplMarkup(values)]}',
  40. '{afterSubTpl}',
  41. '{afterBodyEl}',
  42. // ARIA elements serve different purposes:
  43. // - ariaHelpEl may contain optional hints about the field, such as
  44. // expected format. This text is static and usually does not change
  45. // once rendered. It is also optional.
  46. // - ariaStatusEl is used to convey status of the field. Validation errors
  47. // are rendered here, as well as other information that might be helpful
  48. // to Assistive Technology users exploring the app in browse mode.
  49. // - ariaErrorEl is used for announcing dynamic changes in the field state,
  50. // so that AT users receive updates while in forms mode.
  51. //
  52. // Both ariaHelpEl and ariaStatusEl are referenced by the field's input element
  53. // via aria-describedby.
  54. '<tpl if="renderAriaElements">',
  55. '<tpl if="ariaHelp">',
  56. '<span id="{id}-ariaHelpEl" data-ref="ariaHelpEl"',
  57. ' class="' + Ext.baseCSSPrefix + 'hidden-offsets">',
  58. '{ariaHelp}',
  59. '</span>',
  60. '</tpl>',
  61. '<span id="{id}-ariaStatusEl" data-ref="ariaStatusEl" aria-hidden="true"',
  62. ' class="' + Ext.baseCSSPrefix + 'hidden-offsets">',
  63. '{ariaStatus}',
  64. '</span>',
  65. '<span id="{id}-ariaErrorEl" data-ref="ariaErrorEl" aria-hidden="true" aria-live="assertive"',
  66. ' class="' + Ext.baseCSSPrefix + 'hidden-clip">',
  67. '</span>',
  68. '</tpl>',
  69. '</div>',
  70. '<tpl if="renderError">',
  71. '<div id="{id}-errorWrapEl" data-ref="errorWrapEl" class="{errorWrapCls} {errorWrapCls}-{ui}',
  72. ' {errorWrapExtraCls}" style="{errorWrapStyle}">',
  73. '<div role="presentation" id="{id}-errorEl" data-ref="errorEl" ',
  74. 'class="{errorMsgCls} {invalidMsgCls} {invalidMsgCls}-{ui}" ',
  75. 'data-anchorTarget="{tipAnchorTarget}">',
  76. '</div>',
  77. '</div>',
  78. '</tpl>',
  79. {
  80. disableFormats: true
  81. }
  82. ],
  83. getLabelableRenderData: function() {
  84. var me = this,
  85. labelAlign = me.labelAlign,
  86. topLabel = (labelAlign === 'top'),
  87. rightLabel = (labelAlign === 'right'),
  88. sideError = (me.msgTarget === 'side'),
  89. underError = (me.msgTarget === 'under'),
  90. errorMsgCls = me.errorMsgCls,
  91. labelPad = me.labelPad,
  92. labelWidth = me.labelWidth,
  93. labelClsExtra = me.labelClsExtra || '',
  94. errorWrapExtraCls = sideError ? me.errorWrapSideCls : me.errorWrapUnderCls,
  95. labelStyle = '',
  96. labelInnerStyle = '',
  97. labelVisible = me.hasVisibleLabel(),
  98. autoFitErrors = me.autoFitErrors,
  99. defaultBodyWidth = me.defaultBodyWidth,
  100. bodyStyle, data;
  101. if (topLabel) {
  102. labelClsExtra += ' ' + me.topLabelCls;
  103. if (labelPad) {
  104. labelInnerStyle = 'padding-bottom:' + labelPad + 'px;';
  105. }
  106. if (sideError && !autoFitErrors) {
  107. labelClsExtra += ' ' + me.topLabelSideErrorCls;
  108. }
  109. } else {
  110. if (rightLabel) {
  111. labelClsExtra += ' ' + me.rightLabelCls;
  112. }
  113. if (labelPad) {
  114. labelStyle += me.getHorizontalPaddingStyle() + labelPad + 'px;';
  115. }
  116. labelStyle += 'width:' + (labelWidth + (labelPad ? labelPad : 0)) + 'px;';
  117. // inner label needs width as well so that setting width on the outside
  118. // that is smaller than the natural width, will be ensured to take width
  119. // away from the body, and not the label.
  120. labelInnerStyle = 'width:' + labelWidth + 'px';
  121. }
  122. if (labelVisible) {
  123. if (!topLabel && underError) {
  124. errorWrapExtraCls += ' ' + me.errorWrapUnderSideLabelCls;
  125. }
  126. }
  127. if (defaultBodyWidth) {
  128. // This is here to support textfield's deprecated "size" config
  129. bodyStyle = 'min-width:' + defaultBodyWidth + 'px;max-width:' + defaultBodyWidth + 'px;';
  130. }
  131. data = {
  132. id: me.id,
  133. inputId: me.getInputId(),
  134. labelCls: me.labelCls,
  135. labelClsExtra: labelClsExtra,
  136. labelStyle: labelStyle + (me.labelStyle || ''),
  137. labelInnerStyle: labelInnerStyle,
  138. labelInnerCls: me.labelInnerCls,
  139. labelTextCls: me.labelTextCls,
  140. skipLabelForAttribute: !!me.skipLabelForAttribute,
  141. unselectableCls: Ext.Element.unselectableCls,
  142. bodyStyle: bodyStyle,
  143. baseBodyCls: me.baseBodyCls,
  144. fieldBodyCls: me.fieldBodyCls,
  145. extraFieldBodyCls: me.extraFieldBodyCls,
  146. errorWrapCls: me.errorWrapCls,
  147. errorWrapExtraCls: errorWrapExtraCls,
  148. renderError: sideError || underError,
  149. invalidMsgCls: sideError ? me.invalidIconCls : underError ? me.invalidUnderCls : '',
  150. errorMsgCls: errorMsgCls,
  151. growCls: me.grow ? me.growCls : '',
  152. tipAnchorTarget: me.id + '-inputEl',
  153. errorWrapStyle: (sideError && !autoFitErrors) ? 'visibility:hidden' : 'display:none',
  154. fieldLabel: me.getFieldLabel(),
  155. labelSeparator: me.labelSeparator,
  156. renderAriaElements: !!me.renderAriaElements,
  157. ariaStatus: '',
  158. enableLabelClick: !!me.enableLabelClick,
  159. labelClickCls: me.labelClickCls
  160. };
  161. if (me.ariaHelp) {
  162. data.ariaHelp = Ext.String.htmlEncode(me.ariaHelp);
  163. }
  164. me.getInsertionRenderData(data, me.labelableInsertions);
  165. return data;
  166. },
  167. onLabelClick: function(e, eOpts) {
  168. this.fireEvent('labelclick', this, e, eOpts);
  169. },
  170. constructor: function(config) {
  171. var me = this;
  172. if (config && config.bind) {
  173. var fieldName = config.bind.match(/\{(.*)\}/)[1];
  174. if (!config.name) {
  175. config.name = fieldName;
  176. }
  177. if (!config.itemId) {
  178. config.itemId = fieldName.replace(/\./g, "_");
  179. }
  180. }
  181. me.callParent(arguments);
  182. },
  183. initEvents: function() {
  184. var me = this,
  185. labelEl = me.labelEl,
  186. inputEl = me.inputEl,
  187. onFieldMutation = me.onFieldMutation,
  188. events = me.checkChangeEvents,
  189. len = events.length,
  190. i, event;
  191. if (labelEl && me.enableLabelClick) {
  192. me.mon(labelEl, 'mousedown', me.onLabelClick, me);
  193. }
  194. if (inputEl) {
  195. me.mon(inputEl, Ext.supports.SpecialKeyDownRepeat ? 'keydown' : 'keypress', me.fireKey, me);
  196. for (i = 0; i < len; ++i) {
  197. event = events[i];
  198. if (event === 'propertychange') {
  199. me.usesPropertychange = true;
  200. }
  201. if (event === 'textInput') {
  202. me.usesTextInput = true;
  203. }
  204. me.mon(inputEl, event, onFieldMutation, me);
  205. }
  206. }
  207. me.callParent();
  208. }
  209. });