• ux.form.field.TreePicker 扩展,修复火狐不能展开bug


      1 /**
      2  * A Picker field that contains a tree panel on its popup, enabling selection of tree nodes.
      3  * 动态绑定store,修复火狐点击穿透bug
      4  * 水平有限,可能有新坑
      5  */
      6 Ext.define('ux.form.field.TreePicker', {
      7     extend: 'Ext.form.field.Picker',
      8     xtype: 'uxTreepicker',
      9     mixins: ['Ext.util.StoreHolder'],
     10     uses: ['Ext.tree.Panel'],
     11     triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
     12 
     13     config: {
     14         /**
     15          * @cfg {Ext.data.TreeStore} store
     16          * A tree store that the tree picker will be bound to
     17          */
     18         store: null,
     19 
     20         /**
     21          * @cfg {String} displayField
     22          * The field inside the model that will be used as the node's text.
     23          * Defaults to the default value of {@link Ext.tree.Panel}'s `displayField` configuration.
     24          */
     25         displayField: null,
     26 
     27         /**
     28          * @cfg {Array} columns
     29          * An optional array of columns for multi-column trees
     30          */
     31         columns: null,
     32 
     33         /**
     34          * @cfg {Boolean} selectOnTab
     35          * Whether the Tab key should select the currently highlighted item. Defaults to `true`.
     36          */
     37         selectOnTab: true,
     38 
     39         /**
     40          * @cfg {Number} maxPickerHeight
     41          * The maximum height of the tree dropdown. Defaults to 300.
     42          */
     43         maxPickerHeight: 300,
     44 
     45         /**
     46          * @cfg {Number} minPickerHeight
     47          * The minimum height of the tree dropdown. Defaults to 100.
     48          */
     49         minPickerHeight: 100
     50     },
     51     rootVisible:false,
     52     editable: false,
     53     /**
     54      * @event select
     55      * Fires when a tree node is selected
     56      * @param {Ext.ux.TreePicker} picker        This tree picker
     57      * @param {Ext.data.Model} record           The selected record
     58      */
     59 
     60     initComponent: function () {
     61         var me = this,
     62         store = me.store;
     63 
     64         me.callParent(arguments);
     65         me.delayhide = Ext.create('Ext.util.DelayedTask',
     66         function () {
     67             //console.log('鼠标离开');
     68             me.collapse(true);
     69         });
     70         //如果store是string类型,寻找对应的store
     71         if (Ext.isString(store)) {
     72             store = me.store = Ext.data.StoreManager.lookup(store);
     73         }
     74         //绑定store
     75         if (store) {
     76             me.setStore(store);
     77         } else {
     78             //动态绑定store
     79             me.bindStore(me.store, true);
     80         }
     81     },
     82 
     83     /**
     84      * Creates and returns the tree panel to be used as this field's picker.
     85      */
     86     createPicker: function () {
     87         var me = this,
     88         picker = new Ext.tree.Panel({
     89             baseCls: Ext.baseCSSPrefix + 'boundlist',
     90             shrinkWrapDock: 2,
     91             store: me.store,
     92             floating: true,
     93             displayField: me.displayField,
     94             columns: me.columns,
     95             rootVisible:me.rootVisible,
     96             minHeight: me.minPickerHeight,
     97             //maxHeight: me.maxPickerHeight,
     98             //固定高度,防止展开树后滚动到顶部
     99             height: me.maxPickerHeight,
    100             manageHeight: false,
    101             shadow: false,
    102             cls: 'uxTreepicker',
    103             listeners: {
    104                 scope: me,
    105                 itemclick: me.onItemClick,
    106                 itemkeydown: me.onPickerKeyDown,
    107                 focusenter: function () {
    108                     me.delayhide.cancel();
    109                     //console.log('鼠标进入');
    110                 }
    111             }
    112         }),
    113         view = picker.getView();
    114 
    115         if (Ext.isIE9 && Ext.isStrict) {
    116             // In IE9 strict mode, the tree view grows by the height of the horizontal scroll bar when the items are highlighted or unhighlighted.
    117             // Also when items are collapsed or expanded the height of the view is off. Forcing a repaint fixes the problem.
    118             view.on({
    119                 scope: me,
    120                 highlightitem: me.repaintPickerView,
    121                 unhighlightitem: me.repaintPickerView,
    122                 afteritemexpand: me.repaintPickerView,
    123                 afteritemcollapse: me.repaintPickerView
    124             });
    125         }
    126         return picker;
    127     },
    128 
    129     /**
    130  * repaints the tree view
    131  */
    132     repaintPickerView: function () {
    133         var style = this.picker.getView().getEl().dom.style;
    134 
    135         // can't use Element.repaint because it contains a setTimeout, which results in a flicker effect
    136         style.display = style.display;
    137     },
    138 
    139     /**
    140  * Handles a click even on a tree node
    141  * @private
    142  * @param {Ext.tree.View} view
    143  * @param {Ext.data.Model} record
    144  * @param {HTMLElement} node
    145  * @param {Number} rowIndex
    146  * @param {Ext.event.Event} e
    147  */
    148     onItemClick: function (view, record, node, rowIndex, e) {
    149         this.selectItem(record);
    150     },
    151 
    152     /**
    153  * Handles a keypress event on the picker element
    154  * @private
    155  * @param {Ext.event.Event} e
    156  * @param {HTMLElement} el
    157  */
    158     onPickerKeyDown: function (treeView, record, item, index, e) {
    159         var key = e.getKey();
    160 
    161         if (key === e.ENTER || (key === e.TAB && this.selectOnTab)) {
    162             this.selectItem(record);
    163         }
    164     },
    165 
    166     /**
    167  * Changes the selection to a given record and closes the picker
    168  * @private
    169  * @param {Ext.data.Model} record
    170  */
    171     selectItem: function (record) {
    172         var me = this;
    173         me.setValue(record.getId());
    174         me.fireEvent('select', me, record);
    175         me.collapse(true);
    176     },
    177 
    178     /**
    179  * Runs when the picker is expanded.  Selects the appropriate tree node based on the value of the input element,
    180  * and focuses the picker so that keyboard navigation will work.
    181  * @private
    182  */
    183     onExpand: function () {
    184         var picker = this.picker,
    185         store = picker.store,
    186         value = this.value,
    187         node;
    188 
    189         if (value) {
    190             node = store.getNodeById(value);
    191         }
    192 
    193         if (!node) {
    194             //这里顶级节点被隐藏了不能选中它,否则会出错
    195             // node = store.getRoot();
    196         } else {
    197             picker.ensureVisible(node, {
    198                 select: true,
    199                 focus: true
    200             });
    201         }
    202     },
    203 
    204     /**
    205  * Sets the specified value into the field
    206  * @param {Mixed} value
    207  * @return {Ext.ux.TreePicker} this
    208  */
    209     setValue: function (value) {
    210         var me = this,
    211         record;
    212         me.value = value;
    213         //针对动态绑定的情况,这里判断store是否存在
    214         if (!me.store || me.store.loading) {
    215             // Called while the Store is loading. Ensure it is processed by the onLoad method.
    216             return me;
    217         }
    218 
    219         // try to find a record in the store that matches the value
    220         record = value ? me.store.getNodeById(value) : me.store.getRoot();
    221         if (value === undefined) {
    222             record = me.store.getRoot();
    223             me.value = record.getId();
    224         } else {
    225             record = me.store.getNodeById(value);
    226         }
    227 
    228         // set the raw value to the record's display field if a record was found
    229         me.setRawValue(record ? record.get(me.displayField) : '');
    230 
    231         return me;
    232     },
    233 
    234     getSubmitValue: function () {
    235         return this.value;
    236     },
    237 
    238     /**
    239  * Returns the current data value of the field (the idProperty of the record)
    240  * @return {Number}
    241  */
    242     getValue: function () {
    243         return this.value;
    244     },
    245 
    246     /**
    247  * 数据加载成功时
    248  * @private
    249  */
    250     onLoad: function () {
    251         var value = this.value;
    252         if (value||value==0) {
    253             this.setValue(value);
    254         }
    255     },
    256 
    257     onUpdate: function (store, rec, type, modifiedFieldNames) {
    258         var display = this.displayField;
    259         console.log(store);
    260         if (type === 'edit' && modifiedFieldNames && Ext.Array.contains(modifiedFieldNames, display) && this.value === rec.getId()) {
    261             this.setRawValue(rec.get(display));
    262         }
    263     },
    264     onFocusLeave: function (e) {
    265         this.collapse();
    266         this.delayhide.delay(100);
    267     },
    268     collapse: function (is) {
    269         var me = this;
    270 
    271         if (me.isExpanded && !me.destroyed && !me.destroying && is) {
    272             var openCls = me.openCls,
    273             picker = me.picker,
    274             aboveSfx = '-above';
    275 
    276             // hide the picker and set isExpanded flag
    277             picker.hide();
    278             me.isExpanded = false;
    279 
    280             // remove the openCls
    281             me.bodyEl.removeCls([openCls, openCls + aboveSfx]);
    282             picker.el.removeCls(picker.baseCls + aboveSfx);
    283 
    284             if (me.ariaRole) {
    285                 me.ariaEl.dom.setAttribute('aria-expanded', false);
    286             }
    287 
    288             // remove event listeners
    289             me.touchListeners.destroy();
    290             me.scrollListeners.destroy();
    291             Ext.un('resize', me.alignPicker, me);
    292             me.fireEvent('collapse', me);
    293             me.onCollapse();
    294         }
    295     },
    296     setStore: function (store) {
    297         if (store) {
    298             this.store = store;
    299             this.onLoad();
    300         }
    301     },
    302     bindStore: function (store, initial) {
    303         this.mixins.storeholder.bindStore.apply(this, arguments);
    304     }
    305 });
  • 相关阅读:
    关于unittest框架的传参问题
    爬虫的框架:Scarpy
    Robot Frameworke在python3上搭建环境以及快捷方式的创建
    安装第三方模块报错:read time out
    操作正则表达式遇到的问题
    gil锁 线程队列 线程池
    并发编程
    网络编程传输文件
    粘包现象
    UDP协议下的socket
  • 原文地址:https://www.cnblogs.com/mlzs/p/5595780.html
Copyright © 2020-2023  润新知