| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 | /** * @class Ext.ux.TreePicker * @extends Ext.form.field.Picker *  * A Picker field that contains a tree panel on its popup, enabling selection of tree nodes. */Ext.define('Ext.ux.TreePicker', {    extend: 'Ext.form.field.Picker',    xtype: 'treepicker',    triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',    config: {        /**         * @cfg {Ext.data.TreeStore} store         * A tree store that the tree picker will be bound to         */        store: null,        /**         * @cfg {String} displayField         * The field inside the model that will be used as the node's text.         * Defaults to the default value of {@link Ext.tree.Panel}'s `displayField` configuration.         */        displayField: null,        /**         * @cfg {Array} columns         * An optional array of columns for multi-column trees         */        columns: null,        /**         * @cfg {Boolean} selectOnTab         * Whether the Tab key should select the currently highlighted item. Defaults to `true`.         */        selectOnTab: true,        /**         * @cfg {Number} maxPickerHeight         * The maximum height of the tree dropdown. Defaults to 300.         */        maxPickerHeight: 300,        /**         * @cfg {Number} minPickerHeight         * The minimum height of the tree dropdown. Defaults to 100.         */        minPickerHeight: 100    },       editable: false,    initComponent: function() {        var me = this;        me.callParent(arguments);        this.addEvents(            /**             * @event select             * Fires when a tree node is selected             * @param {Ext.ux.TreePicker} picker        This tree picker             * @param {Ext.data.Model} record           The selected record             */            'select'        );        me.store.on('load', me.onLoad, me);    },    /**     * Creates and returns the tree panel to be used as this field's picker.     * @private     */    createPicker: function() {        var me = this,            picker = Ext.create('Ext.tree.Panel', {                store: me.store,                floating: true,                hidden: true,                displayField: me.displayField,                columns: me.columns,                maxHeight: me.maxTreeHeight,                shadow: false,                manageHeight: false,                listeners: {                    itemclick: Ext.bind(me.onItemClick, me)                },                viewConfig: {                    listeners: {                        render: function(view) {                            view.getEl().on('keypress', me.onPickerKeypress, me);                        }                    }                }            }),            view = picker.getView();        view.on('render', me.setPickerViewStyles, me);        if (Ext.isIE9 && Ext.isStrict) {            // In IE9 strict mode, the tree view grows by the height of the horizontal scroll bar when the items are highlighted or unhighlighted.            // Also when items are collapsed or expanded the height of the view is off. Forcing a repaint fixes the problem.            view.on('highlightitem', me.repaintPickerView, me);            view.on('unhighlightitem', me.repaintPickerView, me);            view.on('afteritemexpand', me.repaintPickerView, me);            view.on('afteritemcollapse', me.repaintPickerView, me);        }        return picker;    },    /**     * Sets min/max height styles on the tree picker's view element after it is rendered.     * @param {Ext.tree.View} view     * @private     */    setPickerViewStyles: function(view) {        view.getEl().setStyle({            'min-height': this.minPickerHeight + 'px',            'max-height': this.maxPickerHeight + 'px'        });    },    /**     * repaints the tree view     */    repaintPickerView: function() {        var style = this.picker.getView().getEl().dom.style;        // can't use Element.repaint because it contains a setTimeout, which results in a flicker effect        style.display = style.display;    },    /**     * Aligns the picker to the input element     * @private     */    alignPicker: function() {        var me = this,            picker;        if (me.isExpanded) {            picker = me.getPicker();            if (me.matchFieldWidth) {                // Auto the height (it will be constrained by max height)                picker.setWidth(me.bodyEl.getWidth());            }            if (picker.isFloating()) {                me.doAlign();            }        }    },    /**     * Handles a click even on a tree node     * @private     * @param {Ext.tree.View} view     * @param {Ext.data.Model} record     * @param {HTMLElement} node     * @param {Number} rowIndex     * @param {Ext.EventObject} e     */    onItemClick: function(view, record, node, rowIndex, e) {        this.selectItem(record);    },    /**     * Handles a keypress event on the picker element     * @private     * @param {Ext.EventObject} e     * @param {HTMLElement} el     */    onPickerKeypress: function(e, el) {        var key = e.getKey();        if(key === e.ENTER || (key === e.TAB && this.selectOnTab)) {            this.selectItem(this.picker.getSelectionModel().getSelection()[0]);        }    },    /**     * Changes the selection to a given record and closes the picker     * @private     * @param {Ext.data.Model} record     */    selectItem: function(record) {        var me = this;        me.setValue(record.get('id'));        me.picker.hide();        me.inputEl.focus();        me.fireEvent('select', me, record)    },    /**     * Runs when the picker is expanded.  Selects the appropriate tree node based on the value of the input element,     * and focuses the picker so that keyboard navigation will work.     * @private     */    onExpand: function() {        var me = this,            picker = me.picker,            store = picker.store,            value = me.value;        if(value) {            picker.selectPath(store.getNodeById(value).getPath());        } else {            picker.getSelectionModel().select(store.getRootNode());        }        Ext.defer(function() {            picker.getView().focus();        }, 1);    },    /**     * Sets the specified value into the field     * @param {Mixed} value     * @return {Ext.ux.TreePicker} this     */    setValue: function(value) {        var me = this,            record;        me.value = value;        if (me.store.loading) {            // Called while the Store is loading. Ensure it is processed by the onLoad method.            return me;        }                    // try to find a record in the store that matches the value        record = value ? me.store.getNodeById(value) : me.store.getRootNode();        // set the raw value to the record's display field if a record was found        me.setRawValue(record ? record.get(this.displayField) : '');        return me;    },    /**     * Returns the current data value of the field (the idProperty of the record)     * @return {Number}     */    getValue: function() {        return this.value;    },    /**     * Handles the store's load event.     * @private     */    onLoad: function() {        var value = this.value;        if (value) {            this.setValue(value);        }    }});
 |