最近项目接到一个需求,要求用拖拽实现在两个Panel之间实现拖拽添加和删除元素的功能.
首先想到的是EXTJS提供的View组件,View组件绑定一个Store和Template就可以得到预期的UI显示效果,再加上EXTJS提供的DD(Drag and Drop)功能,则可以实现两个View组件之前的元素拖拽添加以及删除.
效果如下:
Demo代码实例如下:
1 Ext.onReady(function(){ 2 3 var columnData = [ 4 ["Consignee", "1001"],["PO#", "1002"],["Cargo Origin", "1003"],["Cargo Origin Country", "1004"], 5 ["Cargo Dest.", "1005"],["Cargo Destination Country", "1006"],["PO Status", "1007"], 6 ["PO Vendor", "1008"],["Buyers", "1009"],["Bill to", "1010"],["Earliest Ship Date", "1011"], 7 ["Latest Ship Date", "1012"] 8 ]; 9 10 var columnStore = new Ext.data.ArrayStore({ 11 fields: ['fieldName','fieldOid'], 12 data: columnData 13 }); 14 15 var selectedColumnStore = new Ext.data.ArrayStore({ 16 fields: ['fieldName','fieldOid'], 17 data: [] 18 }); 19 20 var columnsView = Ext.create('Ext.view.View', { 21 store: columnStore, 22 id: 'columnsViewOid', 23 xtype: 'dataview', 24 tpl: [ 25 '<tpl for=".">', 26 '<div class="thumb-wrap1" id="{fieldOid}">', 27 '<div style="padding-left: 3px;">{fieldName}</div></div>', 28 '</tpl>', 29 '<div class="x-clear"></div>', 30 ], 31 trackOver: true, 32 itemSelector: '.thumb-wrap1' 33 }); 34 35 var selectedColumnsView = Ext.create('Ext.view.View', { 36 store: selectedColumnStore, 37 id: 'selectedColumnsViewOid', 38 xtype: 'dataview', 39 tpl: [ 40 '<tpl for=".">', 41 '<div class="thumb-wrap1" id="{fieldOid}">', 42 '<div style="padding-left: 3px;">{fieldName} <img border="0" src="images/del.gif" onclick = "deleteViewItem({fieldOid})"/></div></div>', 43 '</tpl>', 44 '<div class="x-clear"></div>', 45 ], 46 trackOver: true, 47 itemSelector: '.thumb-wrap1' 48 }); 49 50 51 Ext.create('Ext.Panel', { 52 id: 'columnsDispPanelOid', 53 autoScroll:true, 54 width: 600, 55 height:350, 56 renderTo: 'columnsDispPanel', 57 bodyPadding: 5, 58 layout:'border', 59 defaults: { 60 split: true 61 }, 62 items:[ 63 { 64 xtype:'panel', region:'west', margin: '0 2 0 0', flex:1, items: columnsView, 65 tbar:[ 66 {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'} 67 ] 68 }, 69 { 70 xtype:'panel', region:'center', items: selectedColumnsView, 71 tbar:[ 72 {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'}, 73 '-', 74 { 75 xtype: 'button', 76 icon: 'images/rpt_reset.png', 77 text: 'Reset', 78 id: 'selectedColumnResetID', 79 textAlign: 'right', 80 listeners:{ 81 click: function() { 82 Ext.getCmp('selectedColumnsViewOid').getStore().loadData([]); 83 } 84 } 85 } 86 ], 87 } 88 ] 89 }); 90 91 92 /** 93 * Drag zone overrides 94 */ 95 var dragZoneOverrides = { 96 containerScroll : true, 97 scroll : false, 98 getDragData : function(evtObj) { 99 var columnsDataView = Ext.getCmp('columnsViewOid'); 100 var sourceEl = evtObj.getTarget(columnsDataView.itemSelector, 10); 101 if (sourceEl) { 102 var selectedNodes = columnsDataView.getSelectedNodes(); 103 var dragDropEl = document.createElement('div'); 104 if (selectedNodes.length < 1) { 105 selectedNodes.push(sourceEl); 106 } 107 Ext.each(selectedNodes, function(node) { 108 dragDropEl.appendChild(node.cloneNode(true)); 109 }); 110 return { 111 ddel : dragDropEl, 112 repairXY : Ext.fly(sourceEl).getXY(), 113 dragRecords : columnsDataView.getRecord(sourceEl), 114 sourceDataView : columnsDataView 115 }; 116 } 117 118 }, 119 getRepairXY: function() { 120 return this.dragData.repairXY; 121 } 122 }; 123 124 125 var onDragZoneCfg = Ext.apply({}, { 126 ddGroup : 'columnDDGrp', 127 dataView : Ext.getCmp('columnsViewOid') 128 }, dragZoneOverrides); 129 130 new Ext.dd.DragZone(Ext.getCmp('columnsViewOid').getEl(), onDragZoneCfg); 131 132 133 /** 134 * Drop zone overrides 135 */ 136 var dropZoneOverrides = { 137 onContainerOver : function() { 138 return this.dropAllowed; 139 }, 140 onContainerDrop : function(dropZone, evtObj, dragData) { 141 var selectedColumnDataView = Ext.getCmp('selectedColumnsViewOid'); 142 var dragRecords = dragData.dragRecords; 143 var store = selectedColumnDataView.store; 144 var dupFound = false; 145 Ext.each(dragRecords, function(record) { 146 var found = store.findBy(function(r) { 147 return r.data.fieldName === record.data.fieldName; 148 }); 149 if (found > -1 ) { 150 dupFound = true; 151 } 152 }); 153 154 if (!dupFound) { 155 selectedColumnDataView.store.add(dragRecords.data); 156 } else { 157 Ext.MessageBox.alert('Warning', dragRecords.data.fieldName + ' already exist.'); 158 } 159 return true; 160 } 161 }; 162 163 var onDropZoneCfg = Ext.apply({}, { 164 ddGroup : 'columnDDGrp', 165 dataView : Ext.getCmp('selectedColumnsViewOid') 166 }, dropZoneOverrides); 167 168 var onDropZone = new Ext.dd.DropZone(Ext.getCmp('selectedColumnsViewOid').ownerCt.el, onDropZoneCfg); 169 170 deleteViewItem = function (oid) { 171 var viewName = 'selectedColumnsViewOid'; 172 var delItems = []; 173 var currentSelectedColumns = Ext.getCmp(viewName).store.data.items; 174 Ext.Array.forEach (currentSelectedColumns, function(currentSelectedColumn, index) { 175 if (currentSelectedColumn.data.fieldOid == oid) { 176 delItems.push(currentSelectedColumn); 177 Ext.getCmp(viewName).store.remove(delItems); 178 } 179 }) 180 } 181 182 });
jsfiddle 预览: http://jsfiddle.net/8L0keqd7/