| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/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-form-field-Picker'>/**</span> * An abstract class for fields that have a single trigger which opens a "picker" popup below the field, e.g. a combobox * menu list or a date picker. It provides a base implementation for toggling the picker's visibility when the trigger * is clicked, as well as keyboard navigation and some basic events. Sizing and alignment of the picker can be * controlled via the {@link #matchFieldWidth} and {@link #pickerAlign}/{@link #pickerOffset} config properties * respectively. * * You would not normally use this class directly, but instead use it as the parent class for a specific picker field * implementation. Subclasses must implement the {@link #createPicker} method to create a picker component appropriate * for the field. */Ext.define('Ext.form.field.Picker', {    extend: 'Ext.form.field.Trigger',    alias: 'widget.pickerfield',    alternateClassName: 'Ext.form.Picker',    requires: ['Ext.util.KeyNav'],<span id='Ext-form-field-Picker-cfg-matchFieldWidth'>    /**</span>     * @cfg {Boolean} matchFieldWidth     * Whether the picker dropdown's width should be explicitly set to match the width of the field. Defaults to true.     */    matchFieldWidth: true,<span id='Ext-form-field-Picker-cfg-pickerAlign'>    /**</span>     * @cfg {String} pickerAlign     * The {@link Ext.Element#alignTo alignment position} with which to align the picker. Defaults to "tl-bl?"     */    pickerAlign: 'tl-bl?',<span id='Ext-form-field-Picker-cfg-pickerOffset'>    /**</span>     * @cfg {Number[]} pickerOffset     * An offset [x,y] to use in addition to the {@link #pickerAlign} when positioning the picker.     * Defaults to undefined.     */<span id='Ext-form-field-Picker-cfg-openCls'>    /**</span>     * @cfg {String} [openCls='x-pickerfield-open']     * A class to be added to the field's {@link #bodyEl} element when the picker is opened.     */    openCls: Ext.baseCSSPrefix + 'pickerfield-open',<span id='Ext-form-field-Picker-property-isExpanded'>    /**</span>     * @property {Boolean} isExpanded     * True if the picker is currently expanded, false if not.     */<span id='Ext-form-field-Picker-cfg-editable'>    /**</span>     * @cfg {Boolean} editable     * False to prevent the user from typing text directly into the field; the field can only have its value set via     * selecting a value from the picker. In this state, the picker can also be opened by clicking directly on the input     * field itself.     */    editable: true,    initComponent: function() {        this.callParent();        // Custom events        this.addEvents(<span id='Ext-form-field-Picker-event-expand'>            /**</span>             * @event expand             * Fires when the field's picker is expanded.             * @param {Ext.form.field.Picker} field This field instance             */            'expand',<span id='Ext-form-field-Picker-event-collapse'>            /**</span>             * @event collapse             * Fires when the field's picker is collapsed.             * @param {Ext.form.field.Picker} field This field instance             */            'collapse',<span id='Ext-form-field-Picker-event-select'>            /**</span>             * @event select             * Fires when a value is selected via the picker.             * @param {Ext.form.field.Picker} field This field instance             * @param {Object} value The value that was selected. The exact type of this value is dependent on             * the individual field and picker implementations.             */            'select'        );    },    initEvents: function() {        var me = this;        me.callParent();        // Add handlers for keys to expand/collapse the picker        me.keyNav = new Ext.util.KeyNav(me.inputEl, {            down: me.onDownArrow,            esc: {                handler: me.onEsc,                scope: me,                defaultEventAction: false            },            scope: me,            forceKeyDown: true        });        // Non-editable allows opening the picker by clicking the field        if (!me.editable) {            me.mon(me.inputEl, 'click', me.onTriggerClick, me);        }        // Disable native browser autocomplete        if (Ext.isGecko) {            me.inputEl.dom.setAttribute('autocomplete', 'off');        }    },    // private    onEsc: function(e) {        var me = this;        if (me.isExpanded) {            me.collapse();            e.stopEvent();        } else {            // If there's an ancestor Window which will see the ESC event and hide, ensure this Field blurs            // so that a down arrow will not pop up a disembodied dropdown list.            if (me.up('window')) {                me.blur();            }            // Otherwise, only stop the ESC key event if it's not going to bubble up to the FocusManager            else if ((!Ext.FocusManager || !Ext.FocusManager.enabled)) {                e.stopEvent();            }        }    },    onDownArrow: function(e) {        if (!this.isExpanded) {            // Don't call expand() directly as there may be additional processing involved before            // expanding, e.g. in the case of a ComboBox query.            this.onTriggerClick();        }    },<span id='Ext-form-field-Picker-method-expand'>    /**</span>     * Expands this field's picker dropdown.     */    expand: function() {        var me = this,            bodyEl, picker, collapseIf;        if (me.rendered && !me.isExpanded && !me.isDestroyed) {            bodyEl = me.bodyEl;            picker = me.getPicker();            collapseIf = me.collapseIf;            // show the picker and set isExpanded flag            picker.show();            me.isExpanded = true;            me.alignPicker();            bodyEl.addCls(me.openCls);            // monitor clicking and mousewheel            me.mon(Ext.getDoc(), {                mousewheel: collapseIf,                mousedown: collapseIf,                scope: me            });            Ext.EventManager.onWindowResize(me.alignPicker, me);            me.fireEvent('expand', me);            me.onExpand();        }    },    onExpand: Ext.emptyFn,<span id='Ext-form-field-Picker-method-alignPicker'>    /**</span>     * Aligns the picker to the input element     * @protected     */    alignPicker: function() {        var me = this,            picker = me.getPicker();        if (me.isExpanded) {            if (me.matchFieldWidth) {                // Auto the height (it will be constrained by min and max width) unless there are no records to display.                picker.setWidth(me.bodyEl.getWidth());            }            if (picker.isFloating()) {                me.doAlign();            }        }    },<span id='Ext-form-field-Picker-method-doAlign'>    /**</span>     * Performs the alignment on the picker using the class defaults     * @private     */    doAlign: function(){        var me = this,            picker = me.picker,            aboveSfx = '-above',            isAbove;        me.picker.alignTo(me.inputEl, me.pickerAlign, me.pickerOffset);        // add the {openCls}-above class if the picker was aligned above        // the field due to hitting the bottom of the viewport        isAbove = picker.el.getY() < me.inputEl.getY();        me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);        picker[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);    },<span id='Ext-form-field-Picker-method-collapse'>    /**</span>     * Collapses this field's picker dropdown.     */    collapse: function() {        if (this.isExpanded && !this.isDestroyed) {            var me = this,                openCls = me.openCls,                picker = me.picker,                doc = Ext.getDoc(),                collapseIf = me.collapseIf,                aboveSfx = '-above';            // hide the picker and set isExpanded flag            picker.hide();            me.isExpanded = false;            // remove the openCls            me.bodyEl.removeCls([openCls, openCls + aboveSfx]);            picker.el.removeCls(picker.baseCls + aboveSfx);            // remove event listeners            doc.un('mousewheel', collapseIf, me);            doc.un('mousedown', collapseIf, me);            Ext.EventManager.removeResizeListener(me.alignPicker, me);            me.fireEvent('collapse', me);            me.onCollapse();        }    },    onCollapse: Ext.emptyFn,<span id='Ext-form-field-Picker-method-collapseIf'>    /**</span>     * @private     * Runs on mousewheel and mousedown of doc to check to see if we should collapse the picker     */    collapseIf: function(e) {        var me = this;        if (!me.isDestroyed && !e.within(me.bodyEl, false, true) && !e.within(me.picker.el, false, true) && !me.isEventWithinPickerLoadMask(e)) {            me.collapse();        }    },<span id='Ext-form-field-Picker-method-getPicker'>    /**</span>     * Returns a reference to the picker component for this field, creating it if necessary by     * calling {@link #createPicker}.     * @return {Ext.Component} The picker component     */    getPicker: function() {        var me = this;        return me.picker || (me.picker = me.createPicker());    },<span id='Ext-form-field-Picker-method-createPicker'>    /**</span>     * @method     * Creates and returns the component to be used as this field's picker. Must be implemented by subclasses of Picker.     * The current field should also be passed as a configuration option to the picker component as the pickerField     * property.     */    createPicker: Ext.emptyFn,<span id='Ext-form-field-Picker-method-onTriggerClick'>    /**</span>     * Handles the trigger click; by default toggles between expanding and collapsing the picker component.     * @protected     */    onTriggerClick: function() {        var me = this;        if (!me.readOnly && !me.disabled) {            if (me.isExpanded) {                me.collapse();            } else {                me.expand();            }            me.inputEl.focus();        }    },    mimicBlur: function(e) {        var me = this,            picker = me.picker;        // ignore mousedown events within the picker element        if (!picker || !e.within(picker.el, false, true) && !me.isEventWithinPickerLoadMask(e)) {            me.callParent(arguments);        }    },    onDestroy : function(){        var me = this,            picker = me.picker;        Ext.EventManager.removeResizeListener(me.alignPicker, me);        Ext.destroy(me.keyNav);        if (picker) {            delete picker.pickerField;            picker.destroy();        }        me.callParent();    },<span id='Ext-form-field-Picker-method-isEventWithinPickerLoadMask'>    /**</span>     * returns true if the picker has a load mask and the passed event is within the load mask     * @private     * @param {Ext.EventObject} e     * @return {Boolean}     */    isEventWithinPickerLoadMask: function(e) {        var loadMask = this.picker.loadMask;        return loadMask ? e.within(loadMask.maskEl, false, true) || e.within(loadMask.el, false, true) : false;    }});</pre></body></html>
 |