最近项目接到一个需求,要求用拖拽实现在两个Panel之间实现拖拽添加和删除元素的功能.
首先想到的是EXTJS提供的View组件,View组件绑定一个Store和Template就可以得到预期的UI显示效果,再加上EXTJS提供的DD(Drag and Drop)功能,则可以实现两个View组件之前的元素拖拽添加以及删除.
效果如下:
Demo代码实例如下:
Ext.onReady(function(){
var columnData = [
["Consignee", "1001"],["PO#", "1002"],["Cargo Origin", "1003"],["Cargo Origin Country", "1004"],
["Cargo Dest.", "1005"],["Cargo Destination Country", "1006"],["PO Status", "1007"],
["PO Vendor", "1008"],["Buyers", "1009"],["Bill to", "1010"],["Earliest Ship Date", "1011"],
["Latest Ship Date", "1012"]
];
var columnStore = new Ext.data.ArrayStore({
fields: ['fieldName','fieldOid'],
data: columnData
});
var selectedColumnStore = new Ext.data.ArrayStore({
fields: ['fieldName','fieldOid'],
data: []
});
var columnsView = Ext.create('Ext.view.View', {
store: columnStore,
id: 'columnsViewOid',
xtype: 'dataview',
tpl: [
'<tpl for=".">',
'<div class="thumb-wrap1" id="{fieldOid}">',
'<div style="padding-left: 3px;">{fieldName}</div></div>',
'</tpl>',
'<div class="x-clear"></div>',
],
trackOver: true,
itemSelector: '.thumb-wrap1'
});
var selectedColumnsView = Ext.create('Ext.view.View', {
store: selectedColumnStore,
id: 'selectedColumnsViewOid',
xtype: 'dataview',
tpl: [
'<tpl for=".">',
'<div class="thumb-wrap1" id="{fieldOid}">',
'<div style="padding-left: 3px;">{fieldName} <img src="images/del.gif" onclick = "deleteViewItem({fieldOid})"/></div></div>',
'</tpl>',
'<div class="x-clear"></div>',
],
trackOver: true,
itemSelector: '.thumb-wrap1'
});
Ext.create('Ext.Panel', {
id: 'columnsDispPanelOid',
autoScroll:true,
width: 600,
height:350,
renderTo: 'columnsDispPanel',
bodyPadding: 5,
layout:'border',
defaults: {
split: true
},
items:[
{
xtype:'panel', region:'west', margin: '0 2 0 0', flex:1, items: columnsView,
tbar:[
{xtype:'displayfield', value:'<span style="color:#04408c;font-weight:bolder;height:20px;line-height:19px;margin-left:3px"> Columns </span>', margin: '0 2 0 0'}
]
},
{
xtype:'panel', region:'center', items: selectedColumnsView,
tbar:[
{xtype:'displayfield', value:'<span style="color:#04408c;font-weight:bolder;height:20px;line-height:15px;margin-left:3px"> Selected Columns </span>', margin: '0 2 0 0'},
'-',
{
xtype: 'button',
icon: 'images/rpt_reset.png',
text: 'Reset',
id: 'selectedColumnResetID',
textAlign: 'right',
listeners:{
click: function() {
Ext.getCmp('selectedColumnsViewOid').getStore().loadData([]);
}
}
}
],
}
]
});
/**
* Drag zone overrides
*/
var dragZoneOverrides = {
containerScroll : true,
scroll : false,
getDragData : function(evtObj) {
var columnsDataView = Ext.getCmp('columnsViewOid');
var sourceEl = evtObj.getTarget(columnsDataView.itemSelector, 10);
if (sourceEl) {
var selectedNodes = columnsDataView.getSelectedNodes();
var dragDropEl = document.createElement('div');
if (selectedNodes.length < 1) {
selectedNodes.push(sourceEl);
}
Ext.each(selectedNodes, function(node) {
dragDropEl.appendChild(node.cloneNode(true));
});
return {
ddel : dragDropEl,
repairXY : Ext.fly(sourceEl).getXY(),
dragRecords : columnsDataView.getRecord(sourceEl),
sourceDataView : columnsDataView
};
}
},
getRepairXY: function() {
return this.dragData.repairXY;
}
};
var onDragZoneCfg = Ext.apply({}, {
ddGroup : 'columnDDGrp',
dataView : Ext.getCmp('columnsViewOid')
}, dragZoneOverrides);
new Ext.dd.DragZone(Ext.getCmp('columnsViewOid').getEl(), onDragZoneCfg);
/**
* Drop zone overrides
*/
var dropZoneOverrides = {
onContainerOver : function() {
return this.dropAllowed;
},
onContainerDrop : function(dropZone, evtObj, dragData) {
var selectedColumnDataView = Ext.getCmp('selectedColumnsViewOid');
var dragRecords = dragData.dragRecords;
var store = selectedColumnDataView.store;
var dupFound = false;
Ext.each(dragRecords, function(record) {
var found = store.findBy(function(r) {
return r.data.fieldName === record.data.fieldName;
});
if (found > -1 ) {
dupFound = true;
}
});
if (!dupFound) {
selectedColumnDataView.store.add(dragRecords.data);
} else {
Ext.MessageBox.alert('Warning', dragRecords.data.fieldName + ' already exist.');
}
return true;
}
};
var onDropZoneCfg = Ext.apply({}, {
ddGroup : 'columnDDGrp',
dataView : Ext.getCmp('selectedColumnsViewOid')
}, dropZoneOverrides);
var onDropZone = new Ext.dd.DropZone(Ext.getCmp('selectedColumnsViewOid').ownerCt.el, onDropZoneCfg);
deleteViewItem = function (oid) {
var viewName = 'selectedColumnsViewOid';
var delItems = [];
var currentSelectedColumns = Ext.getCmp(viewName).store.data.items;
Ext.Array.forEach (currentSelectedColumns, function(currentSelectedColumn, index) {
if (currentSelectedColumn.data.fieldOid == oid) {
delItems.push(currentSelectedColumn);
Ext.getCmp(viewName).store.remove(delItems);
}
})
}
});
jsfiddle 预览: http://jsfiddle.net/8L0keqd7/