Field3.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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-layout-component-field-Field'>/**
  19. </span> * Layout class for components with {@link Ext.form.Labelable field labeling}, handling the sizing and alignment of
  20. * the form control, label, and error message treatment.
  21. * @private
  22. */
  23. Ext.define('Ext.layout.component.field.Field', {
  24. /* Begin Definitions */
  25. extend: 'Ext.layout.component.Auto',
  26. alias: 'layout.field',
  27. uses: ['Ext.tip.QuickTip', 'Ext.util.TextMetrics', 'Ext.util.CSS'],
  28. /* End Definitions */
  29. type: 'field',
  30. naturalSizingProp: 'size',
  31. beginLayout: function(ownerContext) {
  32. var me = this,
  33. owner = me.owner,
  34. widthModel = ownerContext.widthModel,
  35. ownerNaturalSize = owner[me.naturalSizingProp],
  36. width;
  37. me.callParent(arguments);
  38. ownerContext.labelStrategy = me.getLabelStrategy();
  39. ownerContext.errorStrategy = me.getErrorStrategy();
  40. ownerContext.labelContext = ownerContext.getEl('labelEl');
  41. ownerContext.bodyCellContext = ownerContext.getEl('bodyEl');
  42. ownerContext.inputContext = ownerContext.getEl('inputEl');
  43. ownerContext.errorContext = ownerContext.getEl('errorEl');
  44. // width:100% on an element inside a table in IE6/7 &quot;strict&quot; sizes the content box.
  45. // store the input element's border and padding info so that subclasses can take it into consideration if needed
  46. if ((Ext.isIE6 || Ext.isIE7) &amp;&amp; Ext.isStrict &amp;&amp; ownerContext.inputContext) {
  47. me.ieInputWidthAdjustment = ownerContext.inputContext.getPaddingInfo().width + ownerContext.inputContext.getBorderInfo().width;
  48. }
  49. // perform preparation on the label and error (setting css classes, qtips, etc.)
  50. ownerContext.labelStrategy.prepare(ownerContext, owner);
  51. ownerContext.errorStrategy.prepare(ownerContext, owner);
  52. // Body cell must stretch to use up available width unless the field is auto width
  53. if (widthModel.shrinkWrap) {
  54. // When the width needs to be auto, table-layout cannot be fixed
  55. me.beginLayoutShrinkWrap(ownerContext);
  56. } else if (widthModel.natural) {
  57. // When a size specified, natural becomes fixed width unless the inpiutWidth is specified - we shrinkwrap that
  58. if (typeof ownerNaturalSize == 'number' &amp;&amp; !owner.inputWidth) {
  59. me.beginLayoutFixed(ownerContext, (width = ownerNaturalSize * 6.5 + 20), 'px');
  60. }
  61. // Otherwise it is the same as shrinkWrap
  62. else {
  63. me.beginLayoutShrinkWrap(ownerContext);
  64. }
  65. ownerContext.setWidth(width, false);
  66. } else {
  67. me.beginLayoutFixed(ownerContext, '100', '%');
  68. }
  69. },
  70. beginLayoutFixed: function (ownerContext, width, suffix) {
  71. var owner = ownerContext.target,
  72. inputEl = owner.inputEl,
  73. inputWidth = owner.inputWidth;
  74. owner.el.setStyle('table-layout', 'fixed');
  75. owner.bodyEl.setStyle('width', width + suffix);
  76. if (inputEl &amp;&amp; inputWidth) {
  77. inputEl.setStyle('width', inputWidth + 'px');
  78. }
  79. ownerContext.isFixed = true;
  80. },
  81. beginLayoutShrinkWrap: function (ownerContext) {
  82. var owner = ownerContext.target,
  83. inputEl = owner.inputEl,
  84. inputWidth = owner.inputWidth;
  85. if (inputEl &amp;&amp; inputEl.dom) {
  86. inputEl.dom.removeAttribute('size');
  87. if (inputWidth) {
  88. inputEl.setStyle('width', inputWidth + 'px');
  89. }
  90. }
  91. owner.el.setStyle('table-layout', 'auto');
  92. owner.bodyEl.setStyle('width', '');
  93. },
  94. finishedLayout: function(ownerContext){
  95. var owner = this.owner;
  96. this.callParent(arguments);
  97. ownerContext.labelStrategy.finishedLayout(ownerContext, owner);
  98. ownerContext.errorStrategy.finishedLayout(ownerContext, owner);
  99. },
  100. calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) {
  101. return contentHeight;
  102. },
  103. measureContentHeight: function (ownerContext) {
  104. return ownerContext.el.getHeight();
  105. },
  106. measureContentWidth: function (ownerContext) {
  107. return ownerContext.el.getWidth();
  108. },
  109. measureLabelErrorHeight: function (ownerContext) {
  110. return ownerContext.labelStrategy.getHeight(ownerContext) +
  111. ownerContext.errorStrategy.getHeight(ownerContext);
  112. },
  113. onFocus: function() {
  114. this.getErrorStrategy().onFocus(this.owner);
  115. },
  116. <span id='Ext-layout-component-field-Field-method-getLabelStrategy'> /**
  117. </span> * Return the set of strategy functions from the {@link #labelStrategies labelStrategies collection}
  118. * that is appropriate for the field's {@link Ext.form.Labelable#labelAlign labelAlign} config.
  119. */
  120. getLabelStrategy: function() {
  121. var me = this,
  122. strategies = me.labelStrategies,
  123. labelAlign = me.owner.labelAlign;
  124. return strategies[labelAlign] || strategies.base;
  125. },
  126. <span id='Ext-layout-component-field-Field-method-getErrorStrategy'> /**
  127. </span> * Return the set of strategy functions from the {@link #errorStrategies errorStrategies collection}
  128. * that is appropriate for the field's {@link Ext.form.Labelable#msgTarget msgTarget} config.
  129. */
  130. getErrorStrategy: function() {
  131. var me = this,
  132. owner = me.owner,
  133. strategies = me.errorStrategies,
  134. msgTarget = owner.msgTarget;
  135. return !owner.preventMark &amp;&amp; Ext.isString(msgTarget) ?
  136. (strategies[msgTarget] || strategies.elementId) :
  137. strategies.none;
  138. },
  139. <span id='Ext-layout-component-field-Field-property-labelStrategies'> /**
  140. </span> * Collection of named strategies for laying out and adjusting labels to accommodate error messages.
  141. * An appropriate one will be chosen based on the owner field's {@link Ext.form.Labelable#labelAlign} config.
  142. */
  143. labelStrategies: (function() {
  144. var base = {
  145. prepare: function(ownerContext, owner) {
  146. var cls = owner.labelCls + '-' + owner.labelAlign,
  147. labelEl = owner.labelEl;
  148. if (labelEl) {
  149. labelEl.addCls(cls);
  150. }
  151. },
  152. getHeight: function () {
  153. return 0;
  154. },
  155. finishedLayout: Ext.emptyFn
  156. };
  157. return {
  158. base: base,
  159. <span id='Ext-layout-component-field-Field-property-top'> /**
  160. </span> * Label displayed above the bodyEl
  161. */
  162. top: Ext.applyIf({
  163. getHeight: function (ownerContext) {
  164. var labelContext = ownerContext.labelContext,
  165. props = labelContext.props,
  166. height = props.height;
  167. if (height === undefined) {
  168. props.height = height = labelContext.el.getHeight();
  169. }
  170. return height;
  171. }
  172. }, base),
  173. <span id='Ext-layout-component-field-Field-property-left'> /**
  174. </span> * Label displayed to the left of the bodyEl
  175. */
  176. left: base,
  177. <span id='Ext-layout-component-field-Field-property-right'> /**
  178. </span> * Same as left, only difference is text-align in CSS
  179. */
  180. right: base
  181. };
  182. }()),
  183. <span id='Ext-layout-component-field-Field-property-errorStrategies'> /**
  184. </span> * Collection of named strategies for laying out and adjusting insets to accommodate error messages.
  185. * An appropriate one will be chosen based on the owner field's {@link Ext.form.Labelable#msgTarget} config.
  186. */
  187. errorStrategies: (function() {
  188. function showTip(owner) {
  189. var tip = Ext.layout.component.field.Field.tip,
  190. target;
  191. if (tip &amp;&amp; tip.isVisible()) {
  192. target = tip.activeTarget;
  193. if (target &amp;&amp; target.el === owner.getActionEl().dom) {
  194. tip.toFront(true);
  195. }
  196. }
  197. }
  198. var applyIf = Ext.applyIf,
  199. emptyFn = Ext.emptyFn,
  200. iconCls = Ext.baseCSSPrefix + 'form-invalid-icon',
  201. iconWidth,
  202. base = {
  203. prepare: function(ownerContext, owner) {
  204. var el = owner.errorEl;
  205. if (el) {
  206. el.setDisplayed(false);
  207. }
  208. },
  209. getHeight: function () {
  210. return 0;
  211. },
  212. onFocus: emptyFn,
  213. finishedLayout: emptyFn
  214. };
  215. return {
  216. none: base,
  217. <span id='Ext-layout-component-field-Field-property-side'> /**
  218. </span> * Error displayed as icon (with QuickTip on hover) to right of the bodyEl
  219. */
  220. side: applyIf({
  221. prepare: function(ownerContext, owner) {
  222. var errorEl = owner.errorEl,
  223. sideErrorCell = owner.sideErrorCell,
  224. displayError = owner.hasActiveError(),
  225. tempEl;
  226. // Capture error icon width once
  227. if (!iconWidth) {
  228. iconWidth = (tempEl = Ext.getBody().createChild({style: 'position:absolute', cls: iconCls})).getWidth();
  229. tempEl.remove();
  230. }
  231. errorEl.addCls(iconCls);
  232. errorEl.set({'data-errorqtip': owner.getActiveError() || ''});
  233. if (owner.autoFitErrors) {
  234. errorEl.setDisplayed(displayError);
  235. }
  236. // Not autofitting, the space must still be allocated.
  237. else {
  238. errorEl.setVisible(displayError);
  239. }
  240. // If we are auto fitting, then hide and show the entire cell
  241. if (sideErrorCell &amp;&amp; owner.autoFitErrors) {
  242. sideErrorCell.setDisplayed(displayError);
  243. }
  244. owner.bodyEl.dom.colSpan = owner.getBodyColspan();
  245. // TODO: defer the tip call until after the layout to avoid immediate DOM reads now
  246. Ext.layout.component.field.Field.initTip();
  247. },
  248. onFocus: showTip
  249. }, base),
  250. <span id='Ext-layout-component-field-Field-property-under'> /**
  251. </span> * Error message displayed underneath the bodyEl
  252. */
  253. under: applyIf({
  254. prepare: function(ownerContext, owner) {
  255. var errorEl = owner.errorEl,
  256. cls = Ext.baseCSSPrefix + 'form-invalid-under';
  257. errorEl.addCls(cls);
  258. errorEl.setDisplayed(owner.hasActiveError());
  259. },
  260. getHeight: function (ownerContext) {
  261. var height = 0,
  262. errorContext, props;
  263. if (ownerContext.target.hasActiveError()) {
  264. errorContext = ownerContext.errorContext;
  265. props = errorContext.props;
  266. height = props.height;
  267. if (height === undefined) {
  268. props.height = height = errorContext.el.getHeight();
  269. }
  270. }
  271. return height;
  272. }
  273. }, base),
  274. <span id='Ext-layout-component-field-Field-property-qtip'> /**
  275. </span> * Error displayed as QuickTip on hover of the field container
  276. */
  277. qtip: applyIf({
  278. prepare: function(ownerContext, owner) {
  279. Ext.layout.component.field.Field.initTip();
  280. owner.getActionEl().set({'data-errorqtip': owner.getActiveError() || ''});
  281. },
  282. onFocus: showTip
  283. }, base),
  284. <span id='Ext-layout-component-field-Field-property-title'> /**
  285. </span> * Error displayed as title tip on hover of the field container
  286. */
  287. title: applyIf({
  288. prepare: function(ownerContext, owner) {
  289. owner.el.set({'title': owner.getActiveError() || ''});
  290. }
  291. }, base),
  292. <span id='Ext-layout-component-field-Field-property-elementId'> /**
  293. </span> * Error message displayed as content of an element with a given id elsewhere in the app
  294. */
  295. elementId: applyIf({
  296. prepare: function(ownerContext, owner) {
  297. var targetEl = Ext.fly(owner.msgTarget);
  298. if (targetEl) {
  299. targetEl.dom.innerHTML = owner.getActiveError() || '';
  300. targetEl.setDisplayed(owner.hasActiveError());
  301. }
  302. }
  303. }, base)
  304. };
  305. }()),
  306. statics: {
  307. <span id='Ext-layout-component-field-Field-static-method-initTip'> /**
  308. </span> * Use a custom QuickTip instance separate from the main QuickTips singleton, so that we
  309. * can give it a custom frame style. Responds to errorqtip rather than the qtip property.
  310. * @static
  311. */
  312. initTip: function() {
  313. var tip = this.tip;
  314. if (!tip) {
  315. tip = this.tip = Ext.create('Ext.tip.QuickTip', {
  316. baseCls: Ext.baseCSSPrefix + 'form-invalid-tip'
  317. });
  318. tip.tagConfig = Ext.apply({}, {attribute: 'errorqtip'}, tip.tagConfig);
  319. }
  320. },
  321. <span id='Ext-layout-component-field-Field-static-method-destroyTip'> /**
  322. </span> * Destroy the error tip instance.
  323. * @static
  324. */
  325. destroyTip: function() {
  326. var tip = this.tip;
  327. if (tip) {
  328. tip.destroy();
  329. delete this.tip;
  330. }
  331. }
  332. }
  333. });</pre>
  334. </body>
  335. </html>