最近项目接到一个需求,要求用拖拽实现在两个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 border="0" 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/