引入扩展文件
Extjs4.2根目录下:
examples ux css images (这是选择按钮的图片资源)
examples ux css ItemSelector.css
examples ux form MultiSelect.js
examples ux form ItemSelector.js
examples ux css ItemSelector.css
examples ux form MultiSelect.js
examples ux form ItemSelector.js
我是将以上文件取出来打包到我项目中自己创建的ux目录,没有全部使用ExtJs的包,然后引入以上文件:
<script src="/ExtJs/ux/MultiSelect.js"></script>
<script src="/ExtJs/ux/ItemSelector.js"></script>
<link href="/ExtJs/ux/css/ItemSelector.css" rel="stylesheet" />
<script src="/ExtJs/ux/ItemSelector.js"></script>
<link href="/ExtJs/ux/css/ItemSelector.css" rel="stylesheet" />
{
xtype: "fieldset",
title: "选择仓库管理员",
columnWidth: .100,
style: "padding:10px;",
items: [
{
xtype: "panel",
layout: "fit",
cls: "panelBoder",
height:220,
items: [
{
xtype: 'itemselector',
anchor: '100%',
id: 'UserManagerItemselector',
style:"margin-bottom:10px;",
//fieldLabel: 'ItemSelector',
imagePath: '/ExtJs/ux/css/images/', //这是选择按钮的图片资源
store: "UserManagerStore",
displayField: 'UserName',
valueField: 'UserId',
//value: ['3', '4', '6'], //默认选中项
allowBlank: false,
blankText: "必须选择至少一项",
msgTarget: "title",
fromTitle: '可选', //左边的选择框
toTitle: '已选' //右边的选择框
}
],
bbar: [
{
xtype: "pagingtoolbar",
store: "UserManagerStore",
displayInfo: true,//是否显示分页的额外信息
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',//displayInfo为true时,此属性才能生效
emptyMsg: "没有记录",
listeners: {
beforechange: function () {
var cmp = Ext.getCmp("UserManagerItemselector");
var selectedRecords = cmp.toField.store.getRange();
if (!window.UserManagerItemselectorOldVal) { window.UserManagerItemselectorOldVal = [] };//将翻页前已经选中的记录存入临时的全局变量中
window.UserManagerItemselectorOldVal = selectedRecords;
cmp.fromField.store.removeAll(); //清空左侧选择框所对应的存储器存储的全部数据以便点击下一页时左侧选择框可以重新加载新数据而不是默认的追加新数据
//Ext.getCmp("UserManagerItemselector").clearValue(); //清空已经选择好的项
//Ext.getCmp("UserManagerItemselector").toField.store.removeAll(); //直接清空右侧选择框中所对应的存储器存储的全部数据,这个存储器是隐藏的
}
}
},
{
xtype: "panel",
items: [
{
xtype: "button", text: "撤回", style: "background:red;border:none;margin:10px 0;", icon: "../img/ico/expand-down.png", handler: function () {
var cmp = Ext.getCmp("UserManagerItemselector");
var oldVal = window.UserManagerItemselectorOldVal;
if (oldVal) {
cmp.getStore().add(oldVal);
window.UserManagerItemselectorOldVal = null;
}
cmp.clearValue();
}
}
],
}
]
}
]
}
/*提交表单取多选框的值*/
buttons: [
{
text: '仓库信息登记',
handler: function () {
var cmp = Ext.getCmp("UserManagerItemselector");
var StockUserIDs = cmp.getValue(); //选中的值
//无值则将多选框的边框描红 自行设置panelRedBoder的css
if (StockUserIDs.length == 0) {
cmp.up("panel").addCls("panelRedBoder");
}
else {
cmp.up("panel").removeCls("panelRedBoder");
}
if (!form.isValid()) { return; }
StockUserIDs=StockUserIDs.join(",")
//……
}
}
]
xtype: "fieldset",
title: "选择仓库管理员",
columnWidth: .100,
style: "padding:10px;",
items: [
{
xtype: "panel",
layout: "fit",
cls: "panelBoder",
height:220,
items: [
{
xtype: 'itemselector',
anchor: '100%',
id: 'UserManagerItemselector',
style:"margin-bottom:10px;",
//fieldLabel: 'ItemSelector',
imagePath: '/ExtJs/ux/css/images/', //这是选择按钮的图片资源
store: "UserManagerStore",
displayField: 'UserName',
valueField: 'UserId',
//value: ['3', '4', '6'], //默认选中项
allowBlank: false,
blankText: "必须选择至少一项",
msgTarget: "title",
fromTitle: '可选', //左边的选择框
toTitle: '已选' //右边的选择框
}
],
bbar: [
{
xtype: "pagingtoolbar",
store: "UserManagerStore",
displayInfo: true,//是否显示分页的额外信息
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',//displayInfo为true时,此属性才能生效
emptyMsg: "没有记录",
listeners: {
beforechange: function () {
var cmp = Ext.getCmp("UserManagerItemselector");
var selectedRecords = cmp.toField.store.getRange();
if (!window.UserManagerItemselectorOldVal) { window.UserManagerItemselectorOldVal = [] };//将翻页前已经选中的记录存入临时的全局变量中
window.UserManagerItemselectorOldVal = selectedRecords;
cmp.fromField.store.removeAll(); //清空左侧选择框所对应的存储器存储的全部数据以便点击下一页时左侧选择框可以重新加载新数据而不是默认的追加新数据
//Ext.getCmp("UserManagerItemselector").clearValue(); //清空已经选择好的项
//Ext.getCmp("UserManagerItemselector").toField.store.removeAll(); //直接清空右侧选择框中所对应的存储器存储的全部数据,这个存储器是隐藏的
}
}
},
{
xtype: "panel",
items: [
{
xtype: "button", text: "撤回", style: "background:red;border:none;margin:10px 0;", icon: "../img/ico/expand-down.png", handler: function () {
var cmp = Ext.getCmp("UserManagerItemselector");
var oldVal = window.UserManagerItemselectorOldVal;
if (oldVal) {
cmp.getStore().add(oldVal);
window.UserManagerItemselectorOldVal = null;
}
cmp.clearValue();
}
}
],
}
]
}
]
}
/*提交表单取多选框的值*/
buttons: [
{
text: '仓库信息登记',
handler: function () {
var cmp = Ext.getCmp("UserManagerItemselector");
var StockUserIDs = cmp.getValue(); //选中的值
//无值则将多选框的边框描红 自行设置panelRedBoder的css
if (StockUserIDs.length == 0) {
cmp.up("panel").addCls("panelRedBoder");
}
else {
cmp.up("panel").removeCls("panelRedBoder");
}
if (!form.isValid()) { return; }
StockUserIDs=StockUserIDs.join(",")
//……
}
}
]
选择框边框样式
<style>
#DrugsErpCompanyItemselector { border: 1px solid #B5B8C8; }
#DrugsErpCompanyItemselector .x-boundlist { /*background: #DFEAF2;*/}
#DrugsErpCompanyItemselector * { border: none; }
.panelBoder * { border: none; }
.panelRedBoder { border: 1px solid red; }
</style>
#DrugsErpCompanyItemselector { border: 1px solid #B5B8C8; }
#DrugsErpCompanyItemselector .x-boundlist { /*background: #DFEAF2;*/}
#DrugsErpCompanyItemselector * { border: none; }
.panelBoder * { border: none; }
.panelRedBoder { border: 1px solid red; }
</style>
在GridPanel列编辑状态下的Itemselector
比如在上面的表格中双击某个列,要对该列记录进行编辑,这要注意以下几点:
1.如果将Itemselector置于window组件中,因为window的遮罩的缘故,存储器中的数据只能够被访问一次,解决办法是将存储器置于创建window的函数中。
2.通过编辑器的beforeedit事件使用context.record获得当前编辑的记录,然后将该记录插入到Itemselector的存储器中,在Itemselector渲染后再模拟Itemselector的add select按钮的方法将记录从左侧移动到右侧
3.该列的数据存储器去服务端拿数据的时候要排除当前列(比如张飞、刘备)的ID,这样当前列的数据就只会出现在右侧(已选择)的框中,属于默认选中项。
4.因为从服务端取数据的时候排除了当前列的数据的ID,所以假如右侧的默认选中项丢失了,还得将它们找回来,比如定义一个还原的按钮,用户点击后随时可以还原默认选中项。
5.双击张飞、刘备一列,会弹出window,这列里有两个数据,他们有各自的ID,而这两个ID是一个数组,通过查询表格数据的时候该行记录对应的多个管理员的ID放入了数组中。模型如下:
// #region 仓库数据模型
Ext.define("StockTableModel", {
extend: "Ext.data.Model",
fields: [
{ name: "StockTableId", type: "int" },
{ name: "StockName", type: "string" },
{ name: "CompanyName", type: "string" },
{ name: "StockAddress", type: "string" },
{ name: "UserIDs", type: "auto" }, //仓库管理员名称存储在数组中
{ name: "UserNames", type: "auto" } //仓库管理员ID存储在数组中
]
});
// #endregion
extend: "Ext.data.Model",
fields: [
{ name: "StockTableId", type: "int" },
{ name: "StockName", type: "string" },
{ name: "CompanyName", type: "string" },
{ name: "StockAddress", type: "string" },
{ name: "UserIDs", type: "auto" }, //仓库管理员名称存储在数组中
{ name: "UserNames", type: "auto" } //仓库管理员ID存储在数组中
]
});
// #endregion
GridPanel编辑状态下弹出多选框,读取默认值。打包
//多选框打包
function CreateItemselectorEditWindow(options) {
var windowTitle = options.windowTitle;
var fieldsetTitle = options.fieldsetTitle;
var storeId = options.storeId;
var editRecord = options.editRecord;
var tableModelFieldText = options.tableModelFieldText;
var tableModelFieldKey = options.tableModelFieldKey;
var cellModelFieldText = options.cellModelFieldText;
var cellModelFieldKey = options.cellModelFieldKey;
//将当前要编辑的记录取出来存入oldRec
var oldRecs = [];
var Keys = editRecord.get(tableModelFieldKey);
var Texts = editRecord.get(tableModelFieldText);
for (var i = 0; i < Keys.length; i++) {
var obj = {
[cellModelFieldKey]: Keys[i],
[cellModelFieldText]: Texts[i]
};
oldRecs.push(obj);
}
Ext.create("Ext.window.Window", {
id: "EditWin",
title: windowTitle,
autoShow: true,
forceFit: true,
width: 800,
style: "border:none;padding:10px;",
border: false,
modal: true,
layout: "anchor",
items: [
//创建表单
Ext.create("Ext.form.Panel", {
id: "EditForm",
forceFit: true,
style: "border:none;padding:10px;",
border: false,
items: [
{
xtype: "fieldset",
title: fieldsetTitle,
columnWidth: .100,
style: "padding:10px;",
items: [
{
xtype: "panel",
layout: "fit",
cls: "panelBoder",
height: 220,
items: [
{
xtype: 'itemselector',
anchor: '100%',
id: 'xItemSelector',
style: "margin-bottom:10px;",
imagePath: '/ExtJs/ux/css/images/',
store: storeId,
displayField: cellModelFieldText,
valueField: cellModelFieldKey,
allowBlank: false,
blankText: "必须选择至少一项",
msgTarget: "title",
fromTitle: '可选',
toTitle: '已选',
listeners: {
afterrender: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var store = Ext.getStore(storeId);
store.add(oldRecs);//将当前编辑的记录插入存储器
var newRecs = store.getNewRecords();//获取刚插入的记录
xItemSelector.bindStore(store); //刷新数据存储器
xItemSelector.moveRec(true, newRecs); //将参数指定的记录插入到右侧选择框
var selectedRecords = xItemSelector.toField.store.getRange();
if (!window.xItemSelectorOldVal) { window.xItemSelectorOldVal = [] };
window.xItemSelectorOldVal = selectedRecords;
if (!window.xItemSelectorDefaultVal) { window.xItemSelectorDefaultVal = [] };//存储当前编辑的记录,以便还原为默认选中项
window.xItemSelectorDefaultVal = newRecs;
}
}
}
],
bbar: [
{
xtype: "pagingtoolbar",
store: storeId,
displayInfo: true,
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
emptyMsg: "没有记录",
listeners: {
beforechange: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var selectedRecords = xItemSelector.toField.store.getRange();
if (!window.xItemSelectorOldVal) { window.xItemSelectorOldVal = [] };
window.xItemSelectorOldVal = selectedRecords;
xItemSelector.fromField.store.removeAll();
}
}
},
{
xtype: "panel",
items: [
{
xtype: "button", text: "撤回所选", style: "background:red;border:none;margin:10px 0;", handler: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var oldVal = window.xItemSelectorOldVal;
if (oldVal) {
xItemSelector.getStore().add(oldVal);
window.xItemSelectorOldVal = null;
}
xItemSelector.clearValue();
}
},
{
xtype: "button",
text: "还原默认选中项",
style: "background:red;border:none;margin:10px 10px;",
handler: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
xItemSelector.fromField.store.removeAll();
xItemSelector.bindStore(xItemSelector.getStore());
xItemSelector.getStore().add(window.xItemSelectorDefaultVal);
xItemSelector.moveRec(true, window.xItemSelectorDefaultVal);//还原默认选择项
}
}
],
}
]
}
]
}
],
buttons: [
{
text: "确定", handler: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var xItemSelectorVal = Ext.getCmp("xItemSelector").getValue();
if (xItemSelectorVal.length == 0) {
xItemSelector.up("panel").addCls("panelRedBoder");
}
else {
xItemSelector.up("panel").removeCls("panelRedBoder");
}
}
}
]
})
],
listeners: {
beforeclose: function () { //销毁所有组件和存储器
var store = Ext.getStore(storeId);
this.destroy();
Ext.StoreManager.remove(store);
if (window.xItemSelectorDefaultVal) { window.xItemSelectorDefaultVal = null };
},
close: function () { }
}
});
}
function CreateItemselectorEditWindow(options) {
var windowTitle = options.windowTitle;
var fieldsetTitle = options.fieldsetTitle;
var storeId = options.storeId;
var editRecord = options.editRecord;
var tableModelFieldText = options.tableModelFieldText;
var tableModelFieldKey = options.tableModelFieldKey;
var cellModelFieldText = options.cellModelFieldText;
var cellModelFieldKey = options.cellModelFieldKey;
//将当前要编辑的记录取出来存入oldRec
var oldRecs = [];
var Keys = editRecord.get(tableModelFieldKey);
var Texts = editRecord.get(tableModelFieldText);
for (var i = 0; i < Keys.length; i++) {
var obj = {
[cellModelFieldKey]: Keys[i],
[cellModelFieldText]: Texts[i]
};
oldRecs.push(obj);
}
Ext.create("Ext.window.Window", {
id: "EditWin",
title: windowTitle,
autoShow: true,
forceFit: true,
width: 800,
style: "border:none;padding:10px;",
border: false,
modal: true,
layout: "anchor",
items: [
//创建表单
Ext.create("Ext.form.Panel", {
id: "EditForm",
forceFit: true,
style: "border:none;padding:10px;",
border: false,
items: [
{
xtype: "fieldset",
title: fieldsetTitle,
columnWidth: .100,
style: "padding:10px;",
items: [
{
xtype: "panel",
layout: "fit",
cls: "panelBoder",
height: 220,
items: [
{
xtype: 'itemselector',
anchor: '100%',
id: 'xItemSelector',
style: "margin-bottom:10px;",
imagePath: '/ExtJs/ux/css/images/',
store: storeId,
displayField: cellModelFieldText,
valueField: cellModelFieldKey,
allowBlank: false,
blankText: "必须选择至少一项",
msgTarget: "title",
fromTitle: '可选',
toTitle: '已选',
listeners: {
afterrender: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var store = Ext.getStore(storeId);
store.add(oldRecs);//将当前编辑的记录插入存储器
var newRecs = store.getNewRecords();//获取刚插入的记录
xItemSelector.bindStore(store); //刷新数据存储器
xItemSelector.moveRec(true, newRecs); //将参数指定的记录插入到右侧选择框
var selectedRecords = xItemSelector.toField.store.getRange();
if (!window.xItemSelectorOldVal) { window.xItemSelectorOldVal = [] };
window.xItemSelectorOldVal = selectedRecords;
if (!window.xItemSelectorDefaultVal) { window.xItemSelectorDefaultVal = [] };//存储当前编辑的记录,以便还原为默认选中项
window.xItemSelectorDefaultVal = newRecs;
}
}
}
],
bbar: [
{
xtype: "pagingtoolbar",
store: storeId,
displayInfo: true,
displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
emptyMsg: "没有记录",
listeners: {
beforechange: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var selectedRecords = xItemSelector.toField.store.getRange();
if (!window.xItemSelectorOldVal) { window.xItemSelectorOldVal = [] };
window.xItemSelectorOldVal = selectedRecords;
xItemSelector.fromField.store.removeAll();
}
}
},
{
xtype: "panel",
items: [
{
xtype: "button", text: "撤回所选", style: "background:red;border:none;margin:10px 0;", handler: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var oldVal = window.xItemSelectorOldVal;
if (oldVal) {
xItemSelector.getStore().add(oldVal);
window.xItemSelectorOldVal = null;
}
xItemSelector.clearValue();
}
},
{
xtype: "button",
text: "还原默认选中项",
style: "background:red;border:none;margin:10px 10px;",
handler: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
xItemSelector.fromField.store.removeAll();
xItemSelector.bindStore(xItemSelector.getStore());
xItemSelector.getStore().add(window.xItemSelectorDefaultVal);
xItemSelector.moveRec(true, window.xItemSelectorDefaultVal);//还原默认选择项
}
}
],
}
]
}
]
}
],
buttons: [
{
text: "确定", handler: function () {
var xItemSelector = Ext.getCmp("xItemSelector");
var xItemSelectorVal = Ext.getCmp("xItemSelector").getValue();
if (xItemSelectorVal.length == 0) {
xItemSelector.up("panel").addCls("panelRedBoder");
}
else {
xItemSelector.up("panel").removeCls("panelRedBoder");
}
}
}
]
})
],
listeners: {
beforeclose: function () { //销毁所有组件和存储器
var store = Ext.getStore(storeId);
this.destroy();
Ext.StoreManager.remove(store);
if (window.xItemSelectorDefaultVal) { window.xItemSelectorDefaultVal = null };
},
close: function () { }
}
});
}
以下是在Grid表格中编写的列编辑器的双击列事件,将使用上面打包好的CreateItemselectorEditWindow函数创建Itemselector
plugins: [
{
ptype: "cellediting",
clicksToEdit: 2,
listeners: {
//编辑某记录时在函数中创建弹出窗口同时定义记录所对应的模型和存储器
beforeedit: function (editor, context) {
if (context.colIdx == 5) {
// #region 员工数据模型
Ext.define("UserManagerModel", {
extend: "Ext.data.Model",
fields: [
{ name: "UserId", type: "int" },
{ name: "UserName", type: "string" }
]
});
// #endregion
// #region 员工数据存储器
Ext.create("Ext.data.Store", {
storeId: "UserManagerStore",
model: "UserManagerModel",
autoLoad: true,
pageSize: 5,//每页显示5条记录
proxy: {
type: "ajax",
url: "/Ashx/ComboboxHandler.ashx",
extraParams: { params: { start: 0, limit: 5 }, comboboxType: "userManagerModel", editExcludeID: Ext.encode(context.record.get("UserIDs")) }, //排除当前列数据的ID
reader: {
type: "json",
totalProperty: 'totalProperty', //此为默认,表示记录总数
idProperty: 'UserId', //数据模型的主键
root: "root"
}
}
});
// #endregion
//创建多选框
CreateItemselectorEditWindow({
windowTitle: "正在编辑……",
fieldsetTitle:"选择仓库管理员",
storeId: "UserManagerStore",
tableModelFieldText: "UserNames",//GridPanel的Store所绑定的数据模型(DataModel)中的数组(auto)字段,显示在表格列上的多个文本所代表的字段名
tableModelFieldKey: "UserIDs",//GridPanel的Store所绑定的数据模型(Model)中的数组(auto)字段,显示在表格列上的多个文本所对应的键的字段名
cellModelFieldText: "UserName", //被编辑的列所对应的数据模型(DataModel)中的key
cellModelFieldKey: "UserId",//被编辑的列所对应的数据模型(DataModel)中的Value
editRecord: context.record
});
return false;
}
}
}
}
]
{
ptype: "cellediting",
clicksToEdit: 2,
listeners: {
//编辑某记录时在函数中创建弹出窗口同时定义记录所对应的模型和存储器
beforeedit: function (editor, context) {
if (context.colIdx == 5) {
// #region 员工数据模型
Ext.define("UserManagerModel", {
extend: "Ext.data.Model",
fields: [
{ name: "UserId", type: "int" },
{ name: "UserName", type: "string" }
]
});
// #endregion
// #region 员工数据存储器
Ext.create("Ext.data.Store", {
storeId: "UserManagerStore",
model: "UserManagerModel",
autoLoad: true,
pageSize: 5,//每页显示5条记录
proxy: {
type: "ajax",
url: "/Ashx/ComboboxHandler.ashx",
extraParams: { params: { start: 0, limit: 5 }, comboboxType: "userManagerModel", editExcludeID: Ext.encode(context.record.get("UserIDs")) }, //排除当前列数据的ID
reader: {
type: "json",
totalProperty: 'totalProperty', //此为默认,表示记录总数
idProperty: 'UserId', //数据模型的主键
root: "root"
}
}
});
// #endregion
//创建多选框
CreateItemselectorEditWindow({
windowTitle: "正在编辑……",
fieldsetTitle:"选择仓库管理员",
storeId: "UserManagerStore",
tableModelFieldText: "UserNames",//GridPanel的Store所绑定的数据模型(DataModel)中的数组(auto)字段,显示在表格列上的多个文本所代表的字段名
tableModelFieldKey: "UserIDs",//GridPanel的Store所绑定的数据模型(Model)中的数组(auto)字段,显示在表格列上的多个文本所对应的键的字段名
cellModelFieldText: "UserName", //被编辑的列所对应的数据模型(DataModel)中的key
cellModelFieldKey: "UserId",//被编辑的列所对应的数据模型(DataModel)中的Value
editRecord: context.record
});
return false;
}
}
}
}
]
demo参看ext包的ext-4.2.1.883examplesmultiselect