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