/**
* A Picker field that contains a tree panel on its popup, enabling selection of tree nodes.
* 动态绑定store,修复火狐点击穿透bug
* 水平有限,可能有新坑
*/
Ext.define('ux.form.field.TreePicker', {
extend: 'Ext.form.field.Picker',
xtype: 'uxTreepicker',
mixins: ['Ext.util.StoreHolder'],
uses: ['Ext.tree.Panel'],
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
},
rootVisible:false,
editable: false,
/**
* @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
*/ initComponent: function () {
var me = this,
store = me.store; me.callParent(arguments);
me.delayhide = Ext.create('Ext.util.DelayedTask',
function () {
//console.log('鼠标离开');
me.collapse(true);
});
//如果store是string类型,寻找对应的store
if (Ext.isString(store)) {
store = me.store = Ext.data.StoreManager.lookup(store);
}
//绑定store
if (store) {
me.setStore(store);
} else {
//动态绑定store
me.bindStore(me.store, true);
}
}, /**
* Creates and returns the tree panel to be used as this field's picker.
*/
createPicker: function () {
var me = this,
picker = new Ext.tree.Panel({
baseCls: Ext.baseCSSPrefix + 'boundlist',
shrinkWrapDock: 2,
store: me.store,
floating: true,
displayField: me.displayField,
columns: me.columns,
rootVisible:me.rootVisible,
minHeight: me.minPickerHeight,
//maxHeight: me.maxPickerHeight,
//固定高度,防止展开树后滚动到顶部
height: me.maxPickerHeight,
manageHeight: false,
shadow: false,
cls: 'uxTreepicker',
listeners: {
scope: me,
itemclick: me.onItemClick,
itemkeydown: me.onPickerKeyDown,
focusenter: function () {
me.delayhide.cancel();
//console.log('鼠标进入');
}
}
}),
view = picker.getView(); 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({
scope: me,
highlightitem: me.repaintPickerView,
unhighlightitem: me.repaintPickerView,
afteritemexpand: me.repaintPickerView,
afteritemcollapse: me.repaintPickerView
});
}
return picker;
}, /**
* 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;
}, /**
* 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.event.Event} e
*/
onItemClick: function (view, record, node, rowIndex, e) {
this.selectItem(record);
}, /**
* Handles a keypress event on the picker element
* @private
* @param {Ext.event.Event} e
* @param {HTMLElement} el
*/
onPickerKeyDown: function (treeView, record, item, index, e) {
var key = e.getKey(); if (key === e.ENTER || (key === e.TAB && this.selectOnTab)) {
this.selectItem(record);
}
}, /**
* 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.getId());
me.fireEvent('select', me, record);
me.collapse(true);
}, /**
* 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 picker = this.picker,
store = picker.store,
value = this.value,
node; if (value) {
node = store.getNodeById(value);
} if (!node) {
//这里顶级节点被隐藏了不能选中它,否则会出错
// node = store.getRoot();
} else {
picker.ensureVisible(node, {
select: true,
focus: true
});
}
}, /**
* 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;
//针对动态绑定的情况,这里判断store是否存在
if (!me.store || 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.getRoot();
if (value === undefined) {
record = me.store.getRoot();
me.value = record.getId();
} else {
record = me.store.getNodeById(value);
} // set the raw value to the record's display field if a record was found
me.setRawValue(record ? record.get(me.displayField) : ''); return me;
}, getSubmitValue: function () {
return this.value;
}, /**
* Returns the current data value of the field (the idProperty of the record)
* @return {Number}
*/
getValue: function () {
return this.value;
}, /**
* 数据加载成功时
* @private
*/
onLoad: function () {
var value = this.value;
if (value||value==0) {
this.setValue(value);
}
}, onUpdate: function (store, rec, type, modifiedFieldNames) {
var display = this.displayField;
console.log(store);
if (type === 'edit' && modifiedFieldNames && Ext.Array.contains(modifiedFieldNames, display) && this.value === rec.getId()) {
this.setRawValue(rec.get(display));
}
},
onFocusLeave: function (e) {
this.collapse();
this.delayhide.delay(100);
},
collapse: function (is) {
var me = this; if (me.isExpanded && !me.destroyed && !me.destroying && is) {
var openCls = me.openCls,
picker = me.picker,
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); if (me.ariaRole) {
me.ariaEl.dom.setAttribute('aria-expanded', false);
} // remove event listeners
me.touchListeners.destroy();
me.scrollListeners.destroy();
Ext.un('resize', me.alignPicker, me);
me.fireEvent('collapse', me);
me.onCollapse();
}
},
setStore: function (store) {
if (store) {
this.store = store;
this.onLoad();
}
},
bindStore: function (store, initial) {
this.mixins.storeholder.bindStore.apply(this, arguments);
}
});

ux.form.field.TreePicker 扩展,修复火狐不能展开bug的更多相关文章

  1. ux.form.field.SearchField 列表、树形菜单查询扩展

    //支持bind绑定store //列表搜索扩展,支持本地查询 //支持树形菜单本地一级菜单查询 Ext.define('ux.form.field.SearchField', { extend: ' ...

  2. ux.form.field.Month 只能选年、月的时间扩展

    效果如图,亲测6.2.1版本可用,用法同时间选择控件 //月弹窗扩展 //只选月 Ext.define('ux.picker.Month', { extend: 'Ext.picker.Month', ...

  3. ux.form.field.Year 只能选年的时间扩展

    效果如图,亲测6.2.1版本可用,用法同时间选择控件 //只选择年的控件 Ext.define('ux.picker.Year', { extend: 'Ext.Component', alias: ...

  4. ux.form.field.Password 密码与非密码状态切换

    效果如图: 扩展源码: //扩展 //密码按钮扩展 //支持在密码与非密码之间切换 Ext.define('ux.form.field.Password', { extend: 'Ext.form.f ...

  5. ux.form.field.KindEditor 所见所得编辑器

    注意需要引入KindEditor相关资源 //所见所得编辑器 Ext.define('ux.form.field.KindEditor', { extend: 'Ext.form.field.Text ...

  6. ux.form.field.Verify 验证码控件

    //验证码控件 Ext.define('ux.form.field.Verify', { extend: 'Ext.container.Container', alias: ['widget.fiel ...

  7. ux.form.field.GridDate 支持快速选择日期的日期控件

    效果如图,亲测6.2.1版本可用 /** *支持快速选择日期的日期控件 */ Ext.define('ux.form.field.GridDate', { extend: 'Ext.form.fiel ...

  8. Ext.form.field.Picker (ComboBox、Date、TreePicker、colorpick.Field)竖向滚动导致布局错误

    ComboBox.Date.TreePicker.colorpick.Field这些继承了Ext.form.field.Picker的控件. 在6.0.0和6.0.1中,在界面中存在竖向滚动条时,点击 ...

  9. ExtJs Ext.form.field.TextArea+Ckeditor 扩展富文本编辑器

    Ext.define("MyApp.base.BaseTextArea", { extend: "Ext.form.field.TextArea", xtype ...

随机推荐

  1. [翻译]-马丁·福勒-page对象

    译者注:这篇文章翻译自马丁·福勒(Martin Flower,对,没错,就是软件教父)官网的一篇文章,原文出处在文底.如果你正在做WEB自动化测试,那么我强烈推荐你看这篇文章.另外透露Martin F ...

  2. html5之canvas画图

    导航 前言 基本知识 绘制矩形 清除矩形区域 圆弧 路径 绘制线段 绘制贝塞尔曲线 线性渐变 径向渐变(发散) 图形变形(平移.旋转.缩放) 矩阵变换(图形变形的机制) 图形组合 给图形绘制阴影 绘制 ...

  3. Atitit.人力资源管理原理与概论

    Atitit.人力资源管理原理与概论 1. 人力资源管理 第一章 人力资源管理概述 第二章 人力资源理论基础与发展演变 第三章 人力资源规划 第四章工作分析与工作设计 第五章 员工招聘与录用 第六章 ...

  4. Atitit.软件的建模种类and 建模语言选型and UML???

    Atitit.软件的建模种类and  建模语言选型and UML??? 1. 4大的建模种类:ui建模,业务流程建模 , 业务对象建模, 数据库建模 1 2. 文本还是图片化(推荐)的建模 1 3.  ...

  5. 菜鸟学习WCF笔记-契约(Contract)

    契约,契约确保了服务的正常调用,客户端以契约的方式进行服务端调用,而服务则需要按照契约规定的方式提供服务. 契约是服务提供的一组操作的描述 功能上讲:每个操作对应着某个具体的功能实现,以及调用这个操作 ...

  6. Comet技术详解:基于HTTP长连接的Web端实时通信技术

    前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...

  7. ES6类与模块

    class Animal { // 构造方法,实例化的时候会被调用,如果不指定,那么会有一个不带参数的默认构造函数 constructor(name, color) { this.name = nam ...

  8. JQ中 trigger()和triggerHandler()区别

    既然使用了trigger和triggerHandler,那么你应该了解了他们的差别了. trigger():在每一个匹配的元素上触发某类事件. triggerHandler():这个特别的方法将会触发 ...

  9. Winform TreeView 查找下一个节点

    转载:http://www.cnblogs.com/Ruiky/archive/2013/02/01/2888674.html public static class TreeViewHelper { ...

  10. 报错:LINQ to Entities 不识别方法

    大致是: var products = db.Products.Select(new ProductVm{Name=SomeMethod() }); 针对IQueryable集合的查询操作会被LINQ ...