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

Posted 魔狼再世

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 });

 

以上是关于ux.form.field.TreePicker 扩展,修复火狐不能展开bug的主要内容,如果未能解决你的问题,请参考以下文章