1 var MoveRows =
function(table){
4 this.placeholderElement = this.createPlaceholderElement();
5 this.hoverElement =
false;
6 this.checkTimeout =
false;
7 this.checkPeriod = 150;
10 this.toRowAfter =
false;
11 this.hasHandle =
false;
15 this.moveHover = this.moveHover.bind(
this);
16 this.endMove = this.endMove.bind(
this);
17 this.tableRowDropEvent =
false;
19 this.touchMove =
false;
21 this.connection =
false;
22 this.connections = [];
24 this.connectedTable =
false;
25 this.connectedRow =
false;
28 MoveRows.prototype.createPlaceholderElement =
function(){
29 var el = document.createElement(
"div");
31 el.classList.add(
"tabulator-row");
32 el.classList.add(
"tabulator-row-placeholder");
38 MoveRows.prototype.initialize =
function(handle){
39 this.connection = this.table.options.movableRowsConnectedTables;
42 MoveRows.prototype.setHandle =
function(handle){
43 this.hasHandle = handle;
46 MoveRows.prototype.initializeGroupHeader =
function(group){
52 config.mouseup =
function(e){
53 self.tableRowDrop(e, row);
57 config.mousemove =
function(e){
58 if(((e.pageY - Tabulator.prototype.helpers.elOffset(group.element).top) +
self.table.rowManager.element.scrollTop) > (group.getHeight() / 2)){
59 if(
self.toRow !== group || !
self.toRowAfter){
60 var rowEl = group.getElement();
61 rowEl.parentNode.insertBefore(
self.placeholderElement, rowEl.nextSibling);
62 self.moveRow(group,
true);
65 if(
self.toRow !== group ||
self.toRowAfter){
66 var rowEl = group.getElement();
67 if(rowEl.previousSibling){
68 rowEl.parentNode.insertBefore(
self.placeholderElement, rowEl);
69 self.moveRow(group,
false);
75 group.modules.moveRow = config;
78 MoveRows.prototype.initializeRow =
function(row){
84 config.mouseup =
function(e){
85 self.tableRowDrop(e, row);
89 config.mousemove =
function(e){
90 if(((e.pageY - Tabulator.prototype.helpers.elOffset(row.element).top) +
self.table.rowManager.element.scrollTop) > (row.getHeight() / 2)){
91 if(
self.toRow !== row || !
self.toRowAfter){
92 var rowEl = row.getElement();
93 rowEl.parentNode.insertBefore(
self.placeholderElement, rowEl.nextSibling);
94 self.moveRow(row,
true);
97 if(
self.toRow !== row ||
self.toRowAfter){
98 var rowEl = row.getElement();
99 rowEl.parentNode.insertBefore(
self.placeholderElement, rowEl);
100 self.moveRow(row,
false);
108 rowEl = row.getElement();
110 rowEl.addEventListener(
"mousedown",
function(e){
112 self.checkTimeout = setTimeout(
function(){
113 self.startMove(e, row);
114 },
self.checkPeriod);
118 rowEl.addEventListener(
"mouseup",
function(e){
120 if(
self.checkTimeout){
121 clearTimeout(
self.checkTimeout);
126 this.bindTouchEvents(row, row.getElement());
129 row.modules.moveRow = config;
132 MoveRows.prototype.initializeCell =
function(cell){
134 cellEl = cell.getElement();
136 cellEl.addEventListener(
"mousedown",
function(e){
138 self.checkTimeout = setTimeout(
function(){
139 self.startMove(e, cell.row);
140 },
self.checkPeriod);
144 cellEl.addEventListener(
"mouseup",
function(e){
146 if(
self.checkTimeout){
147 clearTimeout(
self.checkTimeout);
152 this.bindTouchEvents(cell.row, cell.getElement());
155 MoveRows.prototype.bindTouchEvents =
function(row, element){
159 currentRow, nextRow, prevRow, nextRowHeight, prevRowHeight, nextRowHeightLast, prevRowHeightLast;
161 element.addEventListener(
"touchstart",
function(e){
162 self.checkTimeout = setTimeout(
function(){
163 self.touchMove =
true;
165 nextRow = row.nextRow();
166 nextRowHeight = nextRow ? nextRow.getHeight()/2 : 0;
167 prevRow = row.prevRow();
168 prevRowHeight = prevRow ? prevRow.getHeight()/2 : 0;
169 nextRowHeightLast = 0;
170 prevRowHeightLast = 0;
173 self.startMove(e, row);
174 },
self.checkPeriod);
176 this.moving, this.toRow, this.toRowAfter
177 element.addEventListener(
"touchmove",
function(e){
179 var halfCol, diff, moveToRow;
187 startYMove = e.touches[0].pageY;
190 diff = e.touches[0].pageY - startYMove;
193 if(nextRow && diff - nextRowHeightLast > nextRowHeight){
196 if(moveToRow !== row){
197 startYMove = e.touches[0].pageY
198 moveToRow.getElement().parentNode.insertBefore(
self.placeholderElement, moveToRow.getElement().nextSibling);
199 self.moveRow(moveToRow,
true);
203 if(prevRow && -diff - prevRowHeightLast > prevRowHeight){
206 if(moveToRow !== row){
207 startYMove = e.touches[0].pageY;
208 moveToRow.getElement().parentNode.insertBefore(
self.placeholderElement, moveToRow.getElement());
209 self.moveRow(moveToRow,
false);
215 currentRow = moveToRow;
216 nextRow = moveToRow.nextRow();
217 nextRowHeightLast = nextRowHeight;
218 nextRowHeight = nextRow ? nextRow.getHeight() / 2 : 0;
219 prevRow = moveToRow.prevRow();
220 prevRowHeightLast = prevRowHeight;
221 prevRowHeight = prevRow ? prevRow.getHeight() / 2 : 0;
226 element.addEventListener(
"touchend",
function(e){
227 if(
self.checkTimeout){
228 clearTimeout(
self.checkTimeout);
232 self.touchMove =
false;
237 MoveRows.prototype._bindMouseMove =
function(){
240 self.table.rowManager.getDisplayRows().forEach(
function(row){
241 if((row.type ===
"row" || row.type ===
"group") && row.modules.moveRow.mousemove){
242 row.getElement().addEventListener(
"mousemove", row.modules.moveRow.mousemove);
247 MoveRows.prototype._unbindMouseMove =
function(){
250 self.table.rowManager.getDisplayRows().forEach(
function(row){
251 if((row.type ===
"row" || row.type ===
"group") && row.modules.moveRow.mousemove){
252 row.getElement().removeEventListener(
"mousemove", row.modules.moveRow.mousemove);
257 MoveRows.prototype.startMove =
function(e, row){
258 var element = row.getElement();
260 this.setStartPosition(e, row);
264 this.table.element.classList.add(
"tabulator-block-select");
267 this.placeholderElement.style.width = row.getWidth() +
"px";
268 this.placeholderElement.style.height = row.getHeight() +
"px";
270 if(!this.connection){
271 element.parentNode.insertBefore(this.placeholderElement, element);
272 element.parentNode.removeChild(element);
274 this.table.element.classList.add(
"tabulator-movingrow-sending");
275 this.connectToTables(row);
279 this.hoverElement = element.cloneNode(
true);
280 this.hoverElement.classList.add(
"tabulator-moving");
283 document.body.appendChild(this.hoverElement);
284 this.hoverElement.style.left =
"0";
285 this.hoverElement.style.top =
"0";
286 this.hoverElement.style.width = this.table.element.clientWidth +
"px";
287 this.hoverElement.style.whiteSpace =
"nowrap";
288 this.hoverElement.style.overflow =
"hidden";
289 this.hoverElement.style.pointerEvents =
"none";
291 this.table.rowManager.getTableElement().appendChild(this.hoverElement);
293 this.hoverElement.style.left =
"0";
294 this.hoverElement.style.top =
"0";
296 this._bindMouseMove();
299 document.body.addEventListener(
"mousemove", this.moveHover);
300 document.body.addEventListener(
"mouseup", this.endMove);
306 MoveRows.prototype.setStartPosition =
function(e, row){
307 var pageX = this.touchMove ? e.touches[0].pageX : e.pageX,
308 pageY = this.touchMove ? e.touches[0].pageY : e.pageY,
311 element = row.getElement();
313 position = element.getBoundingClientRect();
315 this.startX = position.left - pageX + window.pageXOffset;
316 this.startY = position.top - pageY + window.pageYOffset;
318 this.startY = (pageY - element.getBoundingClientRect().top);
322 MoveRows.prototype.endMove =
function(e){
323 if(!e || e.which === 1 ||
this.touchMove){
324 this._unbindMouseMove();
326 if(!this.connection){
327 this.placeholderElement.parentNode.insertBefore(this.moving.getElement(), this.placeholderElement.nextSibling);
328 this.placeholderElement.parentNode.removeChild(this.placeholderElement);
331 this.hoverElement.parentNode.removeChild(this.hoverElement);
333 this.table.element.classList.remove(
"tabulator-block-select");
336 this.table.rowManager.moveRow(this.moving, this.toRow, this.toRowAfter);
341 this.toRowAfter =
false;
343 document.body.removeEventListener(
"mousemove", this.moveHover);
344 document.body.removeEventListener(
"mouseup", this.endMove);
347 this.table.element.classList.remove(
"tabulator-movingrow-sending");
348 this.disconnectFromTables();
353 MoveRows.prototype.moveRow =
function(row, after){
355 this.toRowAfter = after;
358 MoveRows.prototype.moveHover =
function(e){
360 this.moveHoverConnections.call(
this, e);
362 this.moveHoverTable.call(
this, e);
366 MoveRows.prototype.moveHoverTable =
function(e){
367 var rowHolder = this.table.rowManager.getElement(),
368 scrollTop = rowHolder.scrollTop,
369 yPos = ((this.touchMove ? e.touches[0].pageY : e.pageY) - rowHolder.getBoundingClientRect().top) + scrollTop,
372 this.hoverElement.style.top = (yPos - this.startY) +
"px";
376 MoveRows.prototype.moveHoverConnections =
function(e){
377 this.hoverElement.style.left = (this.startX + (this.touchMove ? e.touches[0].pageX : e.pageX)) +
"px";
378 this.hoverElement.style.top = (this.startY + (this.touchMove ? e.touches[0].pageY : e.pageY)) +
"px";
383 MoveRows.prototype.connectToTables =
function(row){
385 connections = this.table.modules.comms.getConnections(this.connection);
387 this.table.options.movableRowsSendingStart.call(this.table, connections);
389 this.table.modules.comms.send(this.connection,
"moveRow",
"connect", {
396 MoveRows.prototype.disconnectFromTables =
function(){
398 connections = this.table.modules.comms.getConnections(this.connection);
400 this.table.options.movableRowsSendingStop.call(this.table, connections);
402 this.table.modules.comms.send(this.connection,
"moveRow",
"disconnect");
407 MoveRows.prototype.connect =
function(table, row){
409 if(!this.connectedTable){
410 this.connectedTable = table;
411 this.connectedRow = row;
413 this.table.element.classList.add(
"tabulator-movingrow-receiving");
415 self.table.rowManager.getDisplayRows().forEach(
function(row){
416 if(row.type ===
"row" && row.modules.moveRow && row.modules.moveRow.mouseup){
417 row.getElement().addEventListener(
"mouseup", row.modules.moveRow.mouseup);
421 self.tableRowDropEvent =
self.tableRowDrop.bind(
self);
423 self.table.element.addEventListener(
"mouseup",
self.tableRowDropEvent);
425 this.table.options.movableRowsReceivingStart.call(this.table, row, table);
429 console.warn(
"Move Row Error - Table cannot accept connection, already connected to table:", this.connectedTable);
435 MoveRows.prototype.disconnect =
function(table){
437 if(table === this.connectedTable){
438 this.connectedTable =
false;
439 this.connectedRow =
false;
441 this.table.element.classList.remove(
"tabulator-movingrow-receiving");
443 self.table.rowManager.getDisplayRows().forEach(
function(row){
444 if(row.type ===
"row" && row.modules.moveRow && row.modules.moveRow.mouseup){
445 row.getElement().removeEventListener(
"mouseup", row.modules.moveRow.mouseup);
449 self.table.element.removeEventListener(
"mouseup",
self.tableRowDropEvent);
451 this.table.options.movableRowsReceivingStop.call(this.table, table);
453 console.warn(
"Move Row Error - trying to disconnect from non connected table")
457 MoveRows.prototype.dropComplete =
function(table, row, success){
462 switch(typeof this.table.options.movableRowsSender){
464 sender = this.senders[this.table.options.movableRowsSender];
468 sender = this.table.options.movableRowsSender;
473 sender.call(
this, this.moving.getComponent(), row ? row.getComponent() : undefined, table)
475 if(this.table.options.movableRowsSender){
476 console.warn(
"Mover Row Error - no matching sender found:", this.table.options.movableRowsSender);
480 this.table.options.movableRowsSent.call(this.table, this.moving.getComponent(), row ? row.getComponent() : undefined, table);
483 this.table.options.movableRowsSentFailed.call(this.table, this.moving.getComponent(), row ? row.getComponent() : undefined, table);
491 MoveRows.prototype.tableRowDrop =
function(e, row){
492 var receiver =
false,
495 e.stopImmediatePropagation();
497 switch(typeof this.table.options.movableRowsReceiver){
499 receiver = this.receivers[this.table.options.movableRowsReceiver];
503 receiver = this.table.options.movableRowsReceiver;
508 success = receiver.call(
this, this.connectedRow.getComponent(), row ? row.getComponent() : undefined, this.connectedTable)
510 console.warn(
"Mover Row Error - no matching receiver found:", this.table.options.movableRowsReceiver)
514 this.table.options.movableRowsReceived.call(this.table, this.connectedRow.getComponent(), row ? row.getComponent() : undefined, this.connectedTable);
516 this.table.options.movableRowsReceivedFailed.call(this.table, this.connectedRow.getComponent(), row ? row.getComponent() : undefined, this.connectedTable);
519 this.table.modules.comms.send(this.connectedTable,
"moveRow",
"dropcomplete", {
527 MoveRows.prototype.receivers = {
528 insert:
function(fromRow, toRow, fromTable){
529 this.table.addRow(fromRow.getData(), undefined, toRow);
533 add:
function(fromRow, toRow, fromTable){
534 this.table.addRow(fromRow.getData());
538 update:
function(fromRow, toRow, fromTable){
540 toRow.update(fromRow.getData());
547 replace:
function(fromRow, toRow, fromTable){
549 this.table.addRow(fromRow.getData(), undefined, toRow);
558 MoveRows.prototype.senders = {
559 delete:
function(fromRow, toRow, toTable){
565 MoveRows.prototype.commsReceived =
function(table, action, data){
568 return this.connect(table, data.row);
572 return this.disconnect(table);
576 return this.dropComplete(table, data.row, data.success);
582 Tabulator.prototype.registerModule(
"moveRow", MoveRows);