/**
* 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. 安卓-PC-Arduino3方通信实现

    请仔细理解相关参数,如端口设置.IP设置.COM口设置......等等.....不要盲目COPY.....这涉及手机.电脑和一个单片机,其中一台电脑作为服务器并与单片机相连,负责通过网络与客户端通信( ...

  2. JsRender for object 语法说明

    JsRender 作为一款JavaScript模版引擎,必不可少的会有循环功能,也就是for,但由于JsRender过于灵活,for竟然可以接受object作为循环对象. {{for Array}}和 ...

  3. jQuery Ztree基本用法

    1.首先在页面上有<ul/>标签 <ul id="tree" class="ztree"></ul> 2.定义ztree的配 ...

  4. 【Android】Android内存机制,了解Android堆和栈

    1.dalvik的Heap和Stack 这里说的只是dalvik java部分的内存,实际上除了dalvik部分,还有native.     下面针对上面列出的数据类型进行说明,只有了解了我们申请的数 ...

  5. paip.信用卡账单处理系统功能vO22

    paip.信用卡账单处理系统功能vO22 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/att ...

  6. iOS之富文本

    之前做项目时遇到一个问题: 使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结果在XCode中查 ...

  7. 解决用navicate远程连接数据库出现1045 access denied for user 'root'@'localhost' using password yes

    在mysql命令行中执行 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');  GRANT ALL PRIVILEGES ON *.*  ...

  8. android 5.0 webview坑

    http://www.heapoverflow.me/question-webview-loadurlurl-headers-not-working-in-android-31203905 It's ...

  9. NoteExpress 自定义参考文献输出样式

    最近在写硕士论文,样式中没有符合要求的,于是就自己来编辑下样式文件,下文是网上搜集的关于自定义参考文献的一篇教程,可以参考. 一.分隔符|和连接符*的使用 (1)连接符 * 主要作用是“建立依赖关系” ...

  10. IIS下使用appcmd批量搭建网站

    使用 cmd 运行如下命令 > %windir%\system32\inetsrv\appcmd list site /config /xml > d:\sites.xml 修改 d 盘 ...