UNPKG

7.31 kBJavaScriptView Raw
1/**
2 * Row Move Manager options:
3 * cssClass: A CSS class to be added to the menu item container.
4 * columnId: Column definition id (defaults to "_move")
5 * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)
6 * disableRowSelection: Do we want to disable the row selection? (defaults to false)
7 * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)
8 * width: Width of the column
9 * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not
10 *
11 */
12(function ($) {
13 // register namespace
14 $.extend(true, window, {
15 "Slick": {
16 "RowMoveManager": RowMoveManager
17 }
18 });
19
20 function RowMoveManager(options) {
21 var _grid;
22 var _canvas;
23 var _dragging;
24 var _self = this;
25 var _usabilityOverride = null;
26 var _handler = new Slick.EventHandler();
27 var _defaults = {
28 columnId: "_move",
29 cssClass: null,
30 cancelEditOnDrag: false,
31 disableRowSelection: false,
32 singleRowMove: false,
33 width: 40,
34 };
35
36 // user could override the expandable icon logic from within the options or after instantiating the plugin
37 if (options && typeof options.usabilityOverride === 'function') {
38 usabilityOverride(options.usabilityOverride);
39 }
40
41 function init(grid) {
42 options = $.extend(true, {}, _defaults, options);
43 _grid = grid;
44 _canvas = _grid.getCanvasNode();
45 _handler
46 .subscribe(_grid.onDragInit, handleDragInit)
47 .subscribe(_grid.onDragStart, handleDragStart)
48 .subscribe(_grid.onDrag, handleDrag)
49 .subscribe(_grid.onDragEnd, handleDragEnd);
50 }
51
52 function destroy() {
53 _handler.unsubscribeAll();
54 }
55
56 function setOptions(newOptions) {
57 options = $.extend({}, options, newOptions);
58 }
59
60 function handleDragInit(e) {
61 // prevent the grid from cancelling drag'n'drop by default
62 e.stopImmediatePropagation();
63 }
64
65 function handleDragStart(e, dd) {
66 var cell = _grid.getCellFromEvent(e);
67 var currentRow = cell && cell.row;
68 var dataContext = _grid.getDataItem(currentRow);
69
70 if (!checkUsabilityOverride(currentRow, dataContext, _grid)) {
71 return;
72 }
73
74 if (options.cancelEditOnDrag && _grid.getEditorLock().isActive()) {
75 _grid.getEditorLock().cancelCurrentEdit();
76 }
77
78 if (_grid.getEditorLock().isActive() || !/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) {
79 return false;
80 }
81
82 _dragging = true;
83 e.stopImmediatePropagation();
84
85 var selectedRows = options.singleRowMove ? [cell.row] : _grid.getSelectedRows();
86
87 if (selectedRows.length === 0 || $.inArray(cell.row, selectedRows) == -1) {
88 selectedRows = [cell.row];
89 if (!options.disableRowSelection) {
90 _grid.setSelectedRows(selectedRows);
91 }
92 }
93
94 var rowHeight = _grid.getOptions().rowHeight;
95
96 dd.selectedRows = selectedRows;
97
98 dd.selectionProxy = $("<div class='slick-reorder-proxy'/>")
99 .css("position", "absolute")
100 .css("zIndex", "99999")
101 .css("width", $(_canvas).innerWidth())
102 .css("height", rowHeight * selectedRows.length)
103 .appendTo(_canvas);
104
105 dd.guide = $("<div class='slick-reorder-guide'/>")
106 .css("position", "absolute")
107 .css("zIndex", "99998")
108 .css("width", $(_canvas).innerWidth())
109 .css("top", -1000)
110 .appendTo(_canvas);
111
112 dd.insertBefore = -1;
113 }
114
115 function handleDrag(e, dd) {
116 if (!_dragging) {
117 return;
118 }
119
120 e.stopImmediatePropagation();
121
122 var top = e.pageY - $(_canvas).offset().top;
123 dd.selectionProxy.css("top", top - 5);
124
125 var insertBefore = Math.max(0, Math.min(Math.round(top / _grid.getOptions().rowHeight), _grid.getDataLength()));
126 if (insertBefore !== dd.insertBefore) {
127 var eventData = {
128 "grid": _grid,
129 "rows": dd.selectedRows,
130 "insertBefore": insertBefore
131 };
132
133 if (_self.onBeforeMoveRows.notify(eventData) === false) {
134 dd.canMove = false;
135 } else {
136 dd.canMove = true;
137 }
138
139 // if there's a UsabilityOverride defined, we also need to verify that the condition is valid
140 if (_usabilityOverride) {
141 var insertBeforeDataContext = _grid.getDataItem(insertBefore);
142 dd.canMove = checkUsabilityOverride(insertBefore, insertBeforeDataContext, _grid);
143 }
144
145 // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position
146 // else it won't show up (it will be off the screen)
147 if (!dd.canMove) {
148 dd.guide.css("top", -1000);
149 } else {
150 dd.guide.css("top", insertBefore * _grid.getOptions().rowHeight);
151 }
152
153 dd.insertBefore = insertBefore;
154 }
155 }
156
157 function handleDragEnd(e, dd) {
158 if (!_dragging) {
159 return;
160 }
161 _dragging = false;
162 e.stopImmediatePropagation();
163
164 dd.guide.remove();
165 dd.selectionProxy.remove();
166
167 if (dd.canMove) {
168 var eventData = {
169 "grid": _grid,
170 "rows": dd.selectedRows,
171 "insertBefore": dd.insertBefore
172 };
173 // TODO: _grid.remapCellCssClasses ?
174 _self.onMoveRows.notify(eventData);
175 }
176 }
177
178 function getColumnDefinition() {
179 return {
180 id: options.columnId || "_move",
181 name: "",
182 field: "move",
183 width: options.width || 40,
184 behavior: "selectAndMove",
185 selectable: false,
186 resizable: false,
187 cssClass: options.cssClass,
188 formatter: moveIconFormatter
189 };
190 }
191
192 function moveIconFormatter(row, cell, value, columnDef, dataContext, grid) {
193 if (!checkUsabilityOverride(row, dataContext, grid)) {
194 return null;
195 } else {
196 return { addClasses: "cell-reorder dnd", text: "" };
197 }
198 }
199
200 function checkUsabilityOverride(row, dataContext, grid) {
201 if (typeof _usabilityOverride === 'function') {
202 return _usabilityOverride(row, dataContext, grid);
203 }
204 return true;
205 }
206
207 /**
208 * Method that user can pass to override the default behavior or making every row moveable.
209 * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.
210 * @param overrideFn: override function callback
211 */
212 function usabilityOverride(overrideFn) {
213 _usabilityOverride = overrideFn;
214 }
215
216 $.extend(this, {
217 "onBeforeMoveRows": new Slick.Event(),
218 "onMoveRows": new Slick.Event(),
219
220 "init": init,
221 "destroy": destroy,
222 "getColumnDefinition": getColumnDefinition,
223 "setOptions": setOptions,
224 "usabilityOverride": usabilityOverride,
225 "pluginName": "RowMoveManager"
226 });
227 }
228})(jQuery);
\No newline at end of file