/**
* 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. python os&shutil 文件操作

    python os&shutil 文件操作 # os 模块 os.sep 可以取代操作系统特定的路径分隔符.windows下为 '\\' os.name 字符串指示你正在使用的平台.比如对于W ...

  2. grunt使用小记之开篇:grunt概述

    Grunt是什么? Grunt是一个自动化的项目构建工具.如果你需要重复的执行像压缩,编译,单元测试,代码检查以及打包发布的任务.那么你可以使用Grunt来处理这些任务,你所需要做的只是配置好Grun ...

  3. [ACM_几何] Metal Cutting(POJ1514)半平面割与全排暴力切割方案

    Description In order to build a ship to travel to Eindhoven, The Netherlands, various sheet metal pa ...

  4. 《介绍一款开源的类Excel电子表格软件》续:七牛云存储实战(C#)

    两个月前的发布的博客<介绍一款开源的类Excel电子表格软件>引起了热议:在博客园有近2000个View.超过20个评论. 同时有热心读者电话咨询如何能够在SpreadDesing中实现存 ...

  5. HTML5实战与剖析之原生拖拽(四可拖动dragable属性和其他成员)

    可拖动dragable属性 之前我们已经为大家介绍过几篇有关HTML5中原生拖拽的相关知识了.今天为大家介绍HTML5拖拽中的其他一些小东东,闲话不多说赶快一起看看吧. 在默认情况下,链接.文本和图像 ...

  6. javascript图片懒加载与预加载的分析

    javascript图片懒加载与预加载的分析 懒加载与预加载的基本概念.  懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片, ...

  7. paip.sqlite 管理最好的工具 SQLite Expert 最佳实践总结

    paip.sqlite 管理最好的工具 SQLite Expert 最佳实践总结 一般的管理工具斗可以...就是要是sqlite没正常地关闭哈,有shm跟wal文件..例如ff的place.sqlit ...

  8. hdu4508 完全背包,湫湫系列故事——减肥记I

    湫湫系列故事——减肥记I 对于01背包和完全背包,昨晚快睡着的时候,突然就来了灵感 区别:dp[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值 在第二重循环,01 是倒着循环的,因 ...

  9. 详解Bootstrap媒体对象

    在web页面中,图片居左,内容居右排列,是非常常见的效果,它也就是媒体对象,它是一种抽象的样式,可以用来构建不同类型的组件,在bootstrap框架中其对应的版本文件如下: LESS: media.l ...

  10. navigationBar设置透明

    //设置全透明方式 一.完全不用图片(iOS7之后有效)[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBar ...