]> git.proxmox.com Git - extjs.git/blame - extjs/modern/modern/src/plugin/SortableList.js
add extjs 6.0.1 sources
[extjs.git] / extjs / modern / modern / src / plugin / SortableList.js
CommitLineData
6527f429
DM
1/**\r
2 * @class Ext.plugin.SortableList\r
3 * @extends Ext.Component\r
4 * The SortableList plugin gives your list items the ability to be reordered by tapping and \r
5 * dragging elements within the item. \r
6 *\r
7 * The list-sortablehandle is not added to your tpl by default, so it's important that you \r
8 * manually include it. It's also important to recognize that list-items are not draggable \r
9 * themselves. You must add an element to the itemTpl for it to be dragged.\r
10 *\r
11 * Ext.Viewport.add({\r
12 * xtype: 'list',\r
13 * infinite: true,\r
14 * plugins: 'sortablelist',\r
15 * itemTpl: '<span class="myStyle ' + Ext.baseCSSPrefix + 'list-sortablehandle"></span>{text}',\r
16 * data: [{\r
17 * text: 'Item 1'\r
18 * }, {\r
19 * text: 'Item 2'\r
20 * }, {\r
21 * text: 'Item 3'\r
22 * }]\r
23 * });\r
24 *\r
25 * The CSS for MyStyle can be anything that creates an element to tap and drag. For this \r
26 * example we made a simple rectangle like so:\r
27 *\r
28 * .myStyle{\r
29 * width:30px;\r
30 * height:20px;\r
31 * background:gray;\r
32 * float:left;\r
33 * }\r
34 * \r
35 * Note: You must have infinite set to 'true' when using the SortableList plugin.\r
36 * \r
37 */\r
38Ext.define('Ext.plugin.SortableList', {\r
39 extend: 'Ext.Component',\r
40\r
41 alias: 'plugin.sortablelist',\r
42\r
43 mixins: ['Ext.mixin.Hookable'],\r
44\r
45 config: {\r
46 list: null,\r
47 handleSelector: '.' + Ext.baseCSSPrefix + 'list-sortablehandle'\r
48 },\r
49\r
50 init: function(list) {\r
51 this.setList(list);\r
52 },\r
53\r
54 updateList: function(list) {\r
55 if (list) {\r
56 if (list.initialized) {\r
57 this.attachListeners();\r
58 }\r
59 else {\r
60 list.on({\r
61 initialize: 'attachListeners',\r
62 scope: this,\r
63 single: true\r
64 });\r
65 }\r
66 }\r
67 },\r
68\r
69 attachListeners: function() {\r
70 var list = this.getList(),\r
71 scrollerElement = list.getScrollable().getElement();\r
72\r
73 this.scrollerElement = scrollerElement;\r
74\r
75 scrollerElement.onBefore({\r
76 dragstart: 'onScrollerDragStart',\r
77 scope: this\r
78 });\r
79 },\r
80\r
81 onScrollerDragStart: function(e, target) {\r
82 if (Ext.DomQuery.is(target, this.getHandleSelector())) {\r
83 if (!this.animating) {\r
84 this.onDragStart(e, target);\r
85 }\r
86 return false;\r
87 }\r
88 },\r
89\r
90 onDragStart: function(e) {\r
91 var row = Ext.getCmp(e.getTarget('.' + Ext.baseCSSPrefix + 'list-item').id),\r
92 list = this.getList(),\r
93 store = list.getStore();\r
94\r
95 this.scrollerElement.on({\r
96 drag: 'onDrag',\r
97 dragend: 'onDragEnd',\r
98 scope: this\r
99 });\r
100\r
101 this.positionMap = list.getItemMap();\r
102 this.listStore = store;\r
103 this.previousIndexDistance = 0;\r
104\r
105 this.dragRow = row;\r
106 this.dragRecord = row.getRecord();\r
107\r
108 this.dragRowIndex = this.currentDragRowIndex = row.$dataIndex;\r
109 this.dragRowHeight = this.positionMap.getItemHeight(this.dragRowIndex);\r
110\r
111 if (list.getInfinite()) {\r
112 this.startTranslate = this.positionMap.map[this.dragRowIndex];\r
113 } else {\r
114 row.translate(0, 0);\r
115 this.startTranslate = 0;\r
116 }\r
117\r
118 row.addCls(Ext.baseCSSPrefix + 'list-item-dragging');\r
119 },\r
120\r
121 onDrag: function(e) {\r
122 var list = this.getList(),\r
123 listItems = list.listItems,\r
124 store = list.getStore(),\r
125 collection = list.getStore().data,\r
126 dragRow = this.dragRow,\r
127 dragRecordKey = dragRow.id,\r
128 listItemInfo = list.getListItemInfo(),\r
129 positionMap = this.positionMap,\r
130 distance = 0,\r
131 i, item, ln, targetItem, targetIndex, itemIndex,\r
132 swapIndex, swapPosition, record, swapKey, draggingUp;\r
133\r
134 this.dragRowPosition = this.startTranslate + e.deltaY;\r
135 dragRow.translate(0, this.dragRowPosition);\r
136\r
137 targetIndex = positionMap.findIndex(this.dragRowPosition + (this.dragRowHeight / 2));\r
138 targetItem = list.getItemAt(targetIndex);\r
139\r
140 if (targetItem) {\r
141 distance = targetIndex - this.currentDragRowIndex;\r
142\r
143 if (distance !== 0) {\r
144 draggingUp = distance < 0;\r
145\r
146 for (i = 0, ln = Math.abs(distance); i < ln; i++) {\r
147 if (draggingUp) {\r
148 swapIndex = this.currentDragRowIndex - i;\r
149 item = list.getItemAt(swapIndex - 1);\r
150 } else {\r
151 swapIndex = this.currentDragRowIndex + i;\r
152 item = list.getItemAt(swapIndex + 1);\r
153 }\r
154\r
155 swapPosition = positionMap.map[swapIndex];\r
156\r
157 item.translate(0, swapPosition);\r
158\r
159 record = item.getRecord();\r
160 swapKey = record.id;\r
161\r
162 Ext.Array.remove(collection.items, record);\r
163 collection.items.splice(swapIndex, 0, record);\r
164 collection.indices[dragRecordKey] = collection.indices[swapKey];\r
165 collection.indices[swapKey] = swapIndex;\r
166\r
167 list.updateListItem(item, swapIndex, listItemInfo);\r
168 item.$position = swapPosition;\r
169 }\r
170\r
171 itemIndex = listItems.indexOf(dragRow);\r
172 Ext.Array.remove(listItems, dragRow);\r
173 listItems.splice(itemIndex + distance, 0, dragRow);\r
174\r
175 dragRow.$dataIndex = targetIndex;\r
176 dragRow.$position = positionMap.map[targetIndex];\r
177\r
178 this.currentDragRowIndex = targetIndex;\r
179 }\r
180 }\r
181 },\r
182\r
183 onDragEnd: function() {\r
184 var me = this,\r
185 row = me.dragRow,\r
186 list = me.getList(),\r
187 listItemInfo = list.getListItemInfo(),\r
188 position = row.$position;\r
189\r
190 me.scrollerElement.un({\r
191 drag: 'onDrag',\r
192 dragend: 'onDragEnd',\r
193 scope: me\r
194 });\r
195\r
196 me.animating = true;\r
197\r
198 row.getTranslatable().on('animationend', function() {\r
199 row.removeCls(Ext.baseCSSPrefix + 'list-item-dragging');\r
200\r
201 var currentIdx = this.currentDragRowIndex,\r
202 dragIdx = this.dragRowIndex;\r
203\r
204 if (currentIdx !== dragIdx) {\r
205 list.updateListItem(row, row.$dataIndex, listItemInfo);\r
206 row.$position = position;\r
207\r
208 list.fireEvent('dragsort', list, row, currentIdx, dragIdx);\r
209 }\r
210 me.animating = false;\r
211 }, me, {single: true});\r
212\r
213 row.translate(0, position, {duration: 100});\r
214 }\r
215});\r