/**
* 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. 使用VS2013在WIN8.1上运行gaclib的hello world

    首先:gaclib的官网是http://www.gaclib.net/ 需要了解更多信息的请自己去官网,我也是刚刚研究   第一步 下载gaclib的源码   这些文件是运行程序所必须的   第二步 ...

  2. [学习笔记] Dispose模式

    Dispose模式是.NET中很基础也很重要的一个模式,今天重新复习一下相关的东西并记录下来. 什么是Dispose模式? 什么时候我们该为一个类型实现Dispose模式 使用Dispose模式时应该 ...

  3. [自娱自乐] 4、超声波测距模块DIY笔记(四)——终结篇·基于C#上位机软件开发

    前言 上一节我们已经基本上把超声波硬件的发射和接收模块全部做好了,接下来我们着手开发一个软硬结合的基于C#的平面定位软件! 目录 一.整体思路 二.效果提前展示 2-1.软件部分展示 2-2.硬件部分 ...

  4. phoneGap2.9+eclipse开发环境和helloword案例

    不同机器安装和使用各不相同,这里也只是记录一下自己机器上面的使用过程. android安装环境前面的文章有些,这里不再说,直接上phoneGap的过程.因为phoneGap2.9.1需要安装nodej ...

  5. Spring 依赖注入控制反转实现,及编码解析(自制容器)

    定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...

  6. 【原】《Git教程》学习笔记

    [TOC] 1 创建版本库 1.1 初始化 初始化一个Git仓库,使用 git init 命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file> ,注意,可反 ...

  7. paip.mysql 全文索引查询空白解决

    paip.mysql 全文索引查询空白解决   或者  Incorrect key file for table: \'%s\'. Try to repair it    作者Attilax  艾龙, ...

  8. Spring MVC 文件上传下载

    本文基于Spring MVC 注解,让Spring跑起来. (1) 导入jar包:ant.jar.commons-fileupload.jar.connom-io.jar. (2) 在src/cont ...

  9. SQL Server 2008 删除数据库帐号失败问题

    SQL Server 2008 中单独为一个项目建立了一个账号zdhsa,结果发现无法删除. 问题:删除zdhsa失败. 解决:首先从"安全性"-"架构"中删除 ...

  10. GO語言基礎教程:Hello world!

    首先簡單地說一下GO語言的環境安裝,從 http://golang.org/dl/ 針對自己的操作系統選擇合適的安裝包,然後下載安裝即可,下載的時候注意別選錯了的操作系統,例如go1.3.1.darw ...