Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / Field2.html
diff --git a/docs/source/Field2.html b/docs/source/Field2.html
new file mode 100644 (file)
index 0000000..2c70439
--- /dev/null
@@ -0,0 +1,412 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>The source code</title>
+  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
+  <script type="text/javascript" src="../prettify/prettify.js"></script>
+  <style type="text/css">
+    .highlight { display: block; background-color: #ddd; }
+  </style>
+  <script type="text/javascript">
+    function highlight() {
+      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+    }
+  </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+  <pre class="prettyprint lang-js"><span id='Ext-layout-component-field-Field'>/**
+</span> * @class Ext.layout.component.field.Field
+ * @extends Ext.layout.component.Component
+ * Layout class for components with {@link Ext.form.Labelable field labeling}, handling the sizing and alignment of
+ * the form control, label, and error message treatment.
+ * @private
+ */
+Ext.define('Ext.layout.component.field.Field', {
+
+    /* Begin Definitions */
+
+    alias: ['layout.field'],
+
+    extend: 'Ext.layout.component.Component',
+
+    uses: ['Ext.tip.QuickTip', 'Ext.util.TextMetrics'],
+
+    /* End Definitions */
+
+    type: 'field',
+
+    beforeLayout: function(width, height) {
+        var me = this;
+        return me.callParent(arguments) || (!me.owner.preventMark &amp;&amp; me.activeError !== me.owner.getActiveError());
+    },
+
+    onLayout: function(width, height) {
+        var me = this,
+            owner = me.owner,
+            labelStrategy = me.getLabelStrategy(),
+            errorStrategy = me.getErrorStrategy(),
+            isDefined = Ext.isDefined,
+            isNumber = Ext.isNumber,
+            lastSize, autoWidth, autoHeight, info, undef;
+
+        lastSize = me.lastComponentSize || {};
+        if (!isDefined(width)) {
+            width = lastSize.width;
+            if (width &lt; 0) { //first pass lastComponentSize.width is -Infinity
+                width = undef;
+            }
+        }
+        if (!isDefined(height)) {
+            height = lastSize.height;
+            if (height &lt; 0) { //first pass lastComponentSize.height is -Infinity
+                height = undef;
+            }
+        }
+        autoWidth = !isNumber(width);
+        autoHeight = !isNumber(height);
+
+        info = {
+            autoWidth: autoWidth,
+            autoHeight: autoHeight,
+            width: autoWidth ? owner.getBodyNaturalWidth() : width, //always give a pixel width
+            height: height,
+            setOuterWidth: false, //whether the outer el width should be set to the calculated width
+
+            // insets for the bodyEl from each side of the component layout area
+            insets: {
+                top: 0,
+                right: 0,
+                bottom: 0,
+                left: 0
+            }
+        };
+
+        // NOTE the order of calculating insets and setting styles here is very important; we must first
+        // calculate and set horizontal layout alone, as the horizontal sizing of elements can have an impact
+        // on the vertical sizes due to wrapping, then calculate and set the vertical layout.
+
+        // perform preparation on the label and error (setting css classes, qtips, etc.)
+        labelStrategy.prepare(owner, info);
+        errorStrategy.prepare(owner, info);
+
+        // calculate the horizontal insets for the label and error
+        labelStrategy.adjustHorizInsets(owner, info);
+        errorStrategy.adjustHorizInsets(owner, info);
+
+        // set horizontal styles for label and error based on the current insets
+        labelStrategy.layoutHoriz(owner, info);
+        errorStrategy.layoutHoriz(owner, info);
+
+        // calculate the vertical insets for the label and error
+        labelStrategy.adjustVertInsets(owner, info);
+        errorStrategy.adjustVertInsets(owner, info);
+
+        // set vertical styles for label and error based on the current insets
+        labelStrategy.layoutVert(owner, info);
+        errorStrategy.layoutVert(owner, info);
+
+        // perform sizing of the elements based on the final dimensions and insets
+        if (autoWidth &amp;&amp; autoHeight) {
+            // Don't use setTargetSize if auto-sized, so the calculated size is not reused next time
+            me.setElementSize(owner.el, (info.setOuterWidth ? info.width : undef), info.height);
+        } else {
+            me.setTargetSize((!autoWidth || info.setOuterWidth ? info.width : undef), info.height);
+        }
+        me.sizeBody(info);
+
+        me.activeError = owner.getActiveError();
+    },
+
+
+<span id='Ext-layout-component-field-Field-method-sizeBody'>    /**
+</span>     * Perform sizing and alignment of the bodyEl (and children) to match the calculated insets.
+     */
+    sizeBody: function(info) {
+        var me = this,
+            owner = me.owner,
+            insets = info.insets,
+            totalWidth = info.width,
+            totalHeight = info.height,
+            width = Ext.isNumber(totalWidth) ? totalWidth - insets.left - insets.right : totalWidth,
+            height = Ext.isNumber(totalHeight) ? totalHeight - insets.top - insets.bottom : totalHeight;
+
+        // size the bodyEl
+        me.setElementSize(owner.bodyEl, width, height);
+
+        // size the bodyEl's inner contents if necessary
+        me.sizeBodyContents(width, height);
+    },
+
+<span id='Ext-layout-component-field-Field-property-sizeBodyContents'>    /**
+</span>     * Size the contents of the field body, given the full dimensions of the bodyEl. Does nothing by
+     * default, subclasses can override to handle their specific contents.
+     * @param {Number} width The bodyEl width
+     * @param {Number} height The bodyEl height
+     */
+    sizeBodyContents: Ext.emptyFn,
+
+
+<span id='Ext-layout-component-field-Field-method-getLabelStrategy'>    /**
+</span>     * Return the set of strategy functions from the {@link #labelStrategies labelStrategies collection}
+     * that is appropriate for the field's {@link Ext.form.field.Field#labelAlign labelAlign} config.
+     */
+    getLabelStrategy: function() {
+        var me = this,
+            strategies = me.labelStrategies,
+            labelAlign = me.owner.labelAlign;
+        return strategies[labelAlign] || strategies.base;
+    },
+
+<span id='Ext-layout-component-field-Field-method-getErrorStrategy'>    /**
+</span>     * Return the set of strategy functions from the {@link #errorStrategies errorStrategies collection}
+     * that is appropriate for the field's {@link Ext.form.field.Field#msgTarget msgTarget} config.
+     */
+    getErrorStrategy: function() {
+        var me = this,
+            owner = me.owner,
+            strategies = me.errorStrategies,
+            msgTarget = owner.msgTarget;
+        return !owner.preventMark &amp;&amp; Ext.isString(msgTarget) ?
+                (strategies[msgTarget] || strategies.elementId) :
+                strategies.none;
+    },
+
+
+
+<span id='Ext-layout-component-field-Field-property-labelStrategies'>    /**
+</span>     * Collection of named strategies for laying out and adjusting labels to accommodate error messages.
+     * An appropriate one will be chosen based on the owner field's {@link Ext.form.field.Field#labelAlign} config.
+     */
+    labelStrategies: (function() {
+        var applyIf = Ext.applyIf,
+            emptyFn = Ext.emptyFn,
+            base = {
+                prepare: function(owner, info) {
+                    var cls = owner.labelCls + '-' + owner.labelAlign,
+                        labelEl = owner.labelEl;
+                    if (labelEl &amp;&amp; !labelEl.hasCls(cls)) {
+                        labelEl.addCls(cls);
+                    }
+                },
+                adjustHorizInsets: emptyFn,
+                adjustVertInsets: emptyFn,
+                layoutHoriz: emptyFn,
+                layoutVert: emptyFn
+            },
+            left = applyIf({
+                prepare: function(owner, info) {
+                    base.prepare(owner, info);
+                    // If auto width, add the label width to the body's natural width.
+                    if (info.autoWidth) {
+                        info.width += (!owner.labelEl ? 0 : owner.labelWidth + owner.labelPad);
+                    }
+                    // Must set outer width to prevent field from wrapping below floated label
+                    info.setOuterWidth = true;
+                },
+                adjustHorizInsets: function(owner, info) {
+                    if (owner.labelEl) {
+                        info.insets.left += owner.labelWidth + owner.labelPad;
+                    }
+                },
+                layoutHoriz: function(owner, info) {
+                    // For content-box browsers we can't rely on Labelable.js#getLabelableRenderData
+                    // setting the width style because it needs to account for the final calculated
+                    // padding/border styles for the label. So we set the width programmatically here to
+                    // normalize content-box sizing, while letting border-box browsers use the original
+                    // width style.
+                    var labelEl = owner.labelEl;
+                    if (labelEl &amp;&amp; !owner.isLabelSized &amp;&amp; !Ext.isBorderBox) {
+                        labelEl.setWidth(owner.labelWidth);
+                        owner.isLabelSized = true;
+                    }
+                }
+            }, base);
+
+
+        return {
+            base: base,
+
+<span id='Ext-layout-component-field-Field-property-top'>            /**
+</span>             * Label displayed above the bodyEl
+             */
+            top: applyIf({
+                adjustVertInsets: function(owner, info) {
+                    var labelEl = owner.labelEl;
+                    if (labelEl) {
+                        info.insets.top += Ext.util.TextMetrics.measure(labelEl, owner.fieldLabel, info.width).height +
+                                           labelEl.getFrameWidth('tb') + owner.labelPad;
+                    }
+                }
+            }, base),
+
+<span id='Ext-layout-component-field-Field-property-left'>            /**
+</span>             * Label displayed to the left of the bodyEl
+             */
+            left: left,
+
+<span id='Ext-layout-component-field-Field-property-right'>            /**
+</span>             * Same as left, only difference is text-align in CSS
+             */
+            right: left
+        };
+    })(),
+
+
+
+<span id='Ext-layout-component-field-Field-property-errorStrategies'>    /**
+</span>     * Collection of named strategies for laying out and adjusting insets to accommodate error messages.
+     * An appropriate one will be chosen based on the owner field's {@link Ext.form.field.Field#msgTarget} config.
+     */
+    errorStrategies: (function() {
+        function setDisplayed(el, displayed) {
+            var wasDisplayed = el.getStyle('display') !== 'none';
+            if (displayed !== wasDisplayed) {
+                el.setDisplayed(displayed);
+            }
+        }
+
+        function setStyle(el, name, value) {
+            if (el.getStyle(name) !== value) {
+                el.setStyle(name, value);
+            }
+        }
+
+        var applyIf = Ext.applyIf,
+            emptyFn = Ext.emptyFn,
+            base = {
+                prepare: function(owner) {
+                    setDisplayed(owner.errorEl, false);
+                },
+                adjustHorizInsets: emptyFn,
+                adjustVertInsets: emptyFn,
+                layoutHoriz: emptyFn,
+                layoutVert: emptyFn
+            };
+
+        return {
+            none: base,
+
+<span id='Ext-layout-component-field-Field-property-side'>            /**
+</span>             * Error displayed as icon (with QuickTip on hover) to right of the bodyEl
+             */
+            side: applyIf({
+                prepare: function(owner) {
+                    var errorEl = owner.errorEl;
+                    errorEl.addCls(Ext.baseCSSPrefix + 'form-invalid-icon');
+                    Ext.layout.component.field.Field.initTip();
+                    errorEl.dom.setAttribute('data-errorqtip', owner.getActiveError() || '');
+                    setDisplayed(errorEl, owner.hasActiveError());
+                },
+                adjustHorizInsets: function(owner, info) {
+                    if (owner.autoFitErrors &amp;&amp; owner.hasActiveError()) {
+                        info.insets.right += owner.errorEl.getWidth();
+                    }
+                },
+                layoutHoriz: function(owner, info) {
+                    if (owner.hasActiveError()) {
+                        setStyle(owner.errorEl, 'left', info.width - info.insets.right + 'px');
+                    }
+                },
+                layoutVert: function(owner, info) {
+                    if (owner.hasActiveError()) {
+                        setStyle(owner.errorEl, 'top', info.insets.top + 'px');
+                    }
+                }
+            }, base),
+
+<span id='Ext-layout-component-field-Field-property-under'>            /**
+</span>             * Error message displayed underneath the bodyEl
+             */
+            under: applyIf({
+                prepare: function(owner) {
+                    var errorEl = owner.errorEl,
+                        cls = Ext.baseCSSPrefix + 'form-invalid-under';
+                    if (!errorEl.hasCls(cls)) {
+                        errorEl.addCls(cls);
+                    }
+                    setDisplayed(errorEl, owner.hasActiveError());
+                },
+                adjustVertInsets: function(owner, info) {
+                    if (owner.autoFitErrors) {
+                        info.insets.bottom += owner.errorEl.getHeight();
+                    }
+                },
+                layoutHoriz: function(owner, info) {
+                    var errorEl = owner.errorEl,
+                        insets = info.insets;
+
+                    setStyle(errorEl, 'width', info.width - insets.right - insets.left + 'px');
+                    setStyle(errorEl, 'marginLeft', insets.left + 'px');
+                }
+            }, base),
+
+<span id='Ext-layout-component-field-Field-property-qtip'>            /**
+</span>             * Error displayed as QuickTip on hover of the field container
+             */
+            qtip: applyIf({
+                prepare: function(owner) {
+                    setDisplayed(owner.errorEl, false);
+                    Ext.layout.component.field.Field.initTip();
+                    owner.getActionEl().dom.setAttribute('data-errorqtip', owner.getActiveError() || '');
+                }
+            }, base),
+
+<span id='Ext-layout-component-field-Field-property-title'>            /**
+</span>             * Error displayed as title tip on hover of the field container
+             */
+            title: applyIf({
+                prepare: function(owner) {
+                    setDisplayed(owner.errorEl, false);
+                    owner.el.dom.title = owner.getActiveError() || '';
+                }
+            }, base),
+
+<span id='Ext-layout-component-field-Field-property-elementId'>            /**
+</span>             * Error message displayed as content of an element with a given id elsewhere in the app
+             */
+            elementId: applyIf({
+                prepare: function(owner) {
+                    setDisplayed(owner.errorEl, false);
+                    var targetEl = Ext.fly(owner.msgTarget);
+                    if (targetEl) {
+                        targetEl.dom.innerHTML = owner.getActiveError() || '';
+                        targetEl.setDisplayed(owner.hasActiveError());
+                    }
+                }
+            }, base)
+        };
+    })(),
+
+    statics: {
+<span id='Ext-layout-component-field-Field-method-initTip'>        /**
+</span>         * Use a custom QuickTip instance separate from the main QuickTips singleton, so that we
+         * can give it a custom frame style. Responds to errorqtip rather than the qtip property.
+         */
+        initTip: function() {
+            var tip = this.tip;
+            if (!tip) {
+                tip = this.tip = Ext.create('Ext.tip.QuickTip', {
+                    baseCls: Ext.baseCSSPrefix + 'form-invalid-tip',
+                    renderTo: Ext.getBody()
+                });
+                tip.tagConfig = Ext.apply({}, {attribute: 'errorqtip'}, tip.tagConfig);
+            }
+        },
+
+<span id='Ext-layout-component-field-Field-method-destroyTip'>        /**
+</span>         * Destroy the error tip instance.
+         */
+        destroyTip: function() {
+            var tip = this.tip;
+            if (tip) {
+                tip.destroy();
+                delete this.tip;
+            }
+        }
+    }
+
+});
+</pre>
+</body>
+</html>