改造自MultiselectItemSelector(http://extjs.com/learn/Extension:Multiselect)。
原有代码在关闭该控件以后,会遗留大量无效代码,因此,自己用一个 panel + 2个grid来实现,暂不支持拖拽。
Ext.namespace('Ext.ux')
Ext.ux.IconPanel = function(config){
Ext.apply(this,config);
Ext.ux.IconPanel.superclass.constructor.call(this,config);
}
Ext.extend(Ext.ux.IconPanel,Ext.Panel,{
imagePath:'',
drawUpIcon:true,
drawDownIcon:true,
drawLeftIcon:true,
drawRightIcon:true,
drawTopIcon:true,
drawBotIcon:true,
//style: 'padding-left:5px;padding-right:5px',
initComponent: function(){
Ext.ux.IconPanel.superclass.initComponent.call(this);
this.addEvents(
''
)
},
onRender: function(ct, position){
Ext.ux.IconPanel.superclass.onRender.call(this,ct,position);
if (this.imagePath!="" && this.imagePath.charAt(this.imagePath.length-1)!="/")
this.imagePath+="/";
this.iconUp = this.imagePath + (this.iconUp || 'up2.gif');
this.iconDown = this.imagePath + (this.iconDown || 'down2.gif');
this.iconLeft = this.imagePath + (this.iconLeft || 'left2.gif');
this.iconRight = this.imagePath + (this.iconRight || 'right2.gif');
this.iconTop = this.imagePath + (this.iconTop || 'top2.gif');
this.iconBottom = this.imagePath + (this.iconBottom || 'bottom2.gif');
var el= this.getEl();
if (!this.toSortField) {
this.toTopIcon = el.createChild({tag:'img', src:this.iconTop, style:{cursor:'pointer', margin:'2px'}});
el.createChild({tag: 'br'});
this.upIcon = el.createChild({tag:'img', src:this.iconUp, style:{cursor:'pointer', margin:'2px'}});
el.createChild({tag: 'br'});
}
this.addIcon = el.createChild({tag:'img', src:this.switchToFrom?this.iconLeft:this.iconRight, style:{cursor:'pointer', margin:'2px'}});
el.createChild({tag: 'br'});
this.removeIcon = el.createChild({tag:'img', src:this.switchToFrom?this.iconRight:this.iconLeft, style:{cursor:'pointer', margin:'2px'}});
el.createChild({tag: 'br'});
if (!this.toSortField) {
this.downIcon = el.createChild({tag:'img', src:this.iconDown, style:{cursor:'pointer', margin:'2px'}});
el.createChild({tag: 'br'});
this.toBottomIcon = el.createChild({tag:'img', src:this.iconBottom, style:{cursor:'pointer', margin:'2px'}});
}
if (!this.readOnly) {
if (!this.toSortField) {
this.toTopIcon.on('click', this.toTop, this);
this.upIcon.on('click', this.up, this);
this.downIcon.on('click', this.down, this);
this.toBottomIcon.on('click', this.toBottom, this);
}
this.addIcon.on('click', this.fromTo, this);
this.removeIcon.on('click', this.toFrom, this);
}
if (!this.drawUpIcon || this.hideNavIcons) { this.upIcon.dom.style.display='none'; }
if (!this.drawDownIcon || this.hideNavIcons) { this.downIcon.dom.style.display='none'; }
if (!this.drawLeftIcon || this.hideNavIcons) { this.addIcon.dom.style.display='none'; }
if (!this.drawRightIcon || this.hideNavIcons) { this.removeIcon.dom.style.display='none'; }
if (!this.drawTopIcon || this.hideNavIcons) { this.toTopIcon.dom.style.display='none'; }
if (!this.drawBotIcon || this.hideNavIcons) { this.toBottomIcon.dom.style.display='none'; }
},
toTop:function(){
this.gridsHolder.fireEvent('toTop');
},
toBottom: function(){
this.gridsHolder.fireEvent('toBottom');
},
up: function(){
this.gridsHolder.fireEvent('up');
},
down: function(){
this.gridsHolder.fireEvent('down');
},
fromTo: function(){
this.gridsHolder.fireEvent('fromTo');
},
toFrom: function(){
this.gridsHolder.fireEvent('toFrom');
},
setGridsHoder: function(gridsHolder){
this.gridsHolder = gridsHolder;
}
});
Ext.ux.MultiSelectWin = function(config){
Ext.apply(this,config);
Ext.ux.MultiSelectWin.superclass.constructor.call(this, config);
this.init();
};
Ext.extend(Ext.ux.MultiSelectWin, Ext.util.Observable,{
title : '选择窗口',
from_legend:'可选',
to_legend: '已选',
valueField: 'id',
displayField: 'name',
warningTitle: '提示',
minLength:0,
maxLength:Number.MAX_VALUE,
minLengthText:'至少应选择{0}项',
maxLengthText:'最多只能选择 {0}项',
/**
* 图标面板的config
* @type {}
*/
iconConfig:{},
targetItem: null,
localData:[],
selectedData: [],
saveFn: Ext.emptyFn,
searchFn: Ext.emptyFn,
baseParams: null,
fieldName: null,
toSortField:null,
fromSortField:null,
toSortDir:'ASC',
fromSortDir:'ASC',
allowDup: false,
switchToFrom:false,
openHeight:320,
openWidth:460,
ms_height:220,
ms_width:200,
init: function(){
this.initDataStore();
this.initComponent();
},
initDataStore: function(){
var record = Ext.data.Record.create([
{
name: this.valueField,
type: 'string'
},{
name: this.displayField,
type: 'string'
}]);
if (this.localMode == true){
this.fromStore = new Ext.data.SimpleStore({
fields:[this.valueField, this.displayField]
});
}
else{
var baseParams = {
dir : 'asc',
start : 0,
limit : 0
};
if (this.baseParams)
baseParams = this.baseParams;
this.fromStore = new Ext.data.Store({
proxy: new Ext.data.DWRProxy(this.searchFn, true),
reader: new Ext.data.ListRangeReader({
totalProperty : 'total',
id : 'id'
},record),
sortInfo:{field:this.displayField,direction:'ASC'},
baseParams : baseParams
});
}
this.selectedData = this.targetItem.getArrayValue();
this.toStore = new Ext.data.SimpleStore({
fields:[this.valueField, this.displayField],
data: this.selectedData
});
if(this.allowDup == false){
this.fromStore.on('load',function(){
this.fromStore.filterBy(function(record){
for (var i=0;i < this.selectedData.length;i++){
if(this.selectedData[i][0] == record.get(this.valueField))
return false;
}
return true;
},this);
},this);
}
if(this.localMode == true)
this.fromStore.loadData(this.localData);
else
this.fromStore.load();
},
reComputeWH: function(){
this.openHeight = this.openHeight;
this.openWidth = this.openWidth;
this.ms_height = this.openHeight - 100;
this.ms_width = (this.openWidth-60)/2;
},
createIconsPanel: function(){
this.iconsPanel = new Ext.ux.IconPanel(this.iconConfig);
this.iconsPanel.setGridsHoder(this);
},
initComponent: function(){
if(this.openHeight || this.openWidth){
this.reComputeWH();
}
this.addEvents(
/**
* @event
*/
'destroy',
/**
* @event
*/
'toTop',
/**
* @event
*/
'toBottom',
/**
* @event
*/
'up',
/**
* @event
*/
'down',
/**
* @event
*/
'fromTo',
/**
* @event
*/
'toFrom');
this.on('destroy', this.onDestroy, this);
this.on('up', this.onUp, this);
this.on('down', this.onDown, this);
this.on('toTop', this.onToTop, this);
this.on('toBottom', this.onToBottom, this);
this.on('fromTo', this.onFromTo, this);
this.on('toFrom', this.onToFrom, this);
this.fromGrid = new Ext.grid.GridPanel({
title : '可选',
hideHeaders:true,
width : this.ms_width,
height: this.ms_height,
autoExpandColumn:'name',
layout : 'fit',
sm : new Ext.grid.RowSelectionModel(),
ds : this.fromStore,
cm : new Ext.grid.ColumnModel([{
header : "header",
sortable : true,
dataIndex : this.displayField
}]),
viewConfig:{forceFit:true}
})
this.fromGrid.on('rowdblclick', this.onFromGriddblclick, this);
this.toGrid = new Ext.grid.GridPanel({
title : '已选',
hideHeaders:true,
width : this.ms_width,
height: this.ms_height,
autoExpandColumn:'name',
layout : 'fit',
sm : new Ext.grid.RowSelectionModel(),
ds : this.toStore,
cm : new Ext.grid.ColumnModel([{
header : "header",
sortable : true,
dataIndex : this.displayField
}]),
viewConfig:{forceFit:true}
})
this.toGrid.on('rowdblclick', this.onToGriddblclick, this);
this.createIconsPanel();
this.parentPanel = new Ext.Panel({
layout:"table",
layoutConfig:{columns:3},
items: [this.fromGrid,this.iconsPanel,this.toGrid],
frame: true
});
this.selectorWin = new Ext.Window({
frame: true,
resizable:false,
title : this.title,
layout:'fit',
modal: true,
items : [this.parentPanel],
width: this.openWidth,
height: this.openHeight,
buttonAlign:'center',
buttons:[{
text: '确定',
handler: function(){
var records = this.toStore.getRange();
if(this.validateValue(records) == false)
return;
var values = [];
var selectedValue = '';
var selectedText = '';
for (var i=0; i < records.length; i++){
var temp = [];
var v = records[i].get(this.valueField);
var t = records[i].get(this.displayField);
temp.push(v);
temp.push(t);
values.push(temp);
if(selectedValue == ''){
selectedValue = v;
selectedText = t;
}
else{
selectedValue = selectedValue + ',' + v;
selectedText = selectedText + ',' + t;
}
}
this.targetItem.setValue(values);
var formValues = queryPanel.getFormValues();
Ext.apply(formValues,this.baseParams);
formValues.selectedValue = selectedValue;
formValues.selectedText = selectedText;
var fn = this.saveFn.createSequence(function(returnData){});
fn(formValues);
this.selectorWin.close();
},
scope:this
},{
text:'取消',
handler: function(){
this.selectorWin.close();
},
scope: this
}]
})
this.selectorWin.show();
},
validateValue : function(value){
if (value.length < this.minLength) {
Ext.Msg.show({
title: this.warningTitle,
msg: String.format(this.minLengthText, this.minLength),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
return false;
}
if (value.length > this.maxLength) {
Ext.Msg.show({
title: this.warningTitle,
msg: String.format(this.maxLengthText, this.maxLength),
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.INFO
});
return false;
}
return true;
},
onFromGriddblclick: function(){
this.fireEvent('fromTo');
},
onToGriddblclick: function(){
this.fireEvent('toFrom');
},
onUp:function(){
var store = this.toStore;
var sm = this.toGrid.getSelectionModel();
var data = sm.getSelections();
var selectionsArray = [];
for (var i=0; i < data.length; i++){
selectionsArray.push(store.indexOf(data[i]));
}
var record = null;
selectionsArray.sort();
var newSelectionsArray = [];
if (selectionsArray.length > 0) {
for (var i=0; i<selectionsArray.length; i++) {
record = store.getAt(selectionsArray[i]);
if ((selectionsArray[i] - 1) >= 0) {
store.remove(record);
store.insert(selectionsArray[i] - 1, record);
newSelectionsArray.push(selectionsArray[i] - 1);
}
}
this.toGrid.getView().refresh();
sm.selectRows(newSelectionsArray);
}
},
onDown: function(){
var store = this.toStore;
var sm = this.toGrid.getSelectionModel();
var data = sm.getSelections();
var selectionsArray = [];
for (var i=0; i < data.length; i++){
selectionsArray.push(store.indexOf(data[i]));
}
var record = null;
selectionsArray.sort();
selectionsArray.reverse();
var newSelectionsArray = [];
if (selectionsArray.length > 0) {
for (var i=0; i<selectionsArray.length; i++) {
record = store.getAt(selectionsArray[i]);
if ((selectionsArray[i] + 1) < store.getCount()) {
store.remove(record);
store.insert(selectionsArray[i] + 1, record);
newSelectionsArray.push(selectionsArray[i] + 1);
}
}
this.toGrid.getView().refresh();
sm.selectRows(newSelectionsArray);
}
},
onToTop: function(){
var store = this.toStore;
var sm = this.toGrid.getSelectionModel();
var data = sm.getSelections();
var selectionsArray = [];
for (var i=0; i < data.length; i++){
selectionsArray.push(store.indexOf(data[i]));
}
var records = [];
if (selectionsArray.length > 0) {
selectionsArray.sort();
for (var i=0; i<selectionsArray.length; i++) {
record = store.getAt(selectionsArray[i]);
records.push(record);
}
selectionsArray = [];
for (var i=records.length-1; i>-1; i--) {
record = records[i];
store.remove(record);
store.insert(0, record);
selectionsArray.push(((records.length - 1) - i));
}
}
this.toGrid.getView().refresh();
sm.selectRows(selectionsArray);
},
onToBottom: function(){
var store = this.toStore;
var sm = this.toGrid.getSelectionModel();
var data = sm.getSelections();
var selectionsArray = [];
for (var i=0; i < data.length; i++){
selectionsArray.push(store.indexOf(data[i]));
}
var records = [];
if (selectionsArray.length > 0) {
selectionsArray.sort();
for (var i=0; i<selectionsArray.length; i++) {
record = store.getAt(selectionsArray[i]);
records.push(record);
}
selectionsArray = [];
for (var i=0; i<records.length; i++) {
record = records[i];
store.remove(record);
store.add(record);
selectionsArray.push((store.getCount()) - (records.length - i));
}
}
this.toGrid.getView().refresh();
sm.selectRows(selectionsArray);
},
onFromTo: function(){
var records = this.fromGrid.getSelectionModel().getSelections();
var selectionsArray = [];
for (var i=0; i < records.length; i++){
selectionsArray.push(this.fromStore.indexOf(records[i]));
}
if (selectionsArray.length > 0) {
if(!this.allowDup)
selectionsArray = [];
for (var i=0; i<records.length; i++) {
record = records[i];
if(this.allowDup){
var x=new Ext.data.Record();
record.id=x.id;
delete x;
this.toStore.add([record]);
}else{
this.fromStore.remove(record);
this.toStore.add([record]);
selectionsArray.push((this.toStore.getCount() - 1));
}
}
}
this.toGrid.getView().refresh();
this.fromGrid.getView().refresh();
if(this.toSortField)
this.toStore.sort(this.toSortField, this.toSortDir);
if(this.allowDup)
this.fromGrid.getSelectionModel().selectRows(selectionsArray);
else
this.toGrid.getSelectionModel().selectRows(selectionsArray);
},
onToFrom: function(){
var records = this.toGrid.getSelectionModel().getSelections();
var selectionsArray = [];
if (records.length > 0) {
for (var i=0; i<records.length; i++) {
record = records[i];
this.toStore.remove(record);
if(!this.allowDup){
this.fromStore.add([record]);
selectionsArray.push((this.fromStore.getCount() - 1));
}
}
}
this.fromGrid.getView().refresh();
this.toGrid.getView().refresh();
if(this.fromSortField)
this.fromStore.sort(this.fromSortField, this.fromSortDir);
this.fromGrid.getSelectionModel().selectRows(selectionsArray);
},
onDestroy:function(){
this.toStore = null;
this.toGrid = null;
this.fromStore = null;
this.fromGrid = null;
}
});
Ext.reg('multiSelectWin',Ext.ux.MultiSelectWin);
截图