otsdaq_utilities  v2_05_02_indev
moveable_columns.js
1 /* Tabulator v4.5.3 (c) Oliver Folkerd */
2 
3 var MoveColumns = function MoveColumns(table) {
4  this.table = table; //hold Tabulator object
5  this.placeholderElement = this.createPlaceholderElement();
6  this.hoverElement = false; //floating column header element
7  this.checkTimeout = false; //click check timeout holder
8  this.checkPeriod = 250; //period to wait on mousedown to consider this a move and not a click
9  this.moving = false; //currently moving column
10  this.toCol = false; //destination column
11  this.toColAfter = false; //position of moving column relative to the desitnation column
12  this.startX = 0; //starting position within header element
13  this.autoScrollMargin = 40; //auto scroll on edge when within margin
14  this.autoScrollStep = 5; //auto scroll distance in pixels
15  this.autoScrollTimeout = false; //auto scroll timeout
16  this.touchMove = false;
17 
18  this.moveHover = this.moveHover.bind(this);
19  this.endMove = this.endMove.bind(this);
20 };
21 
22 MoveColumns.prototype.createPlaceholderElement = function () {
23  var el = document.createElement("div");
24 
25  el.classList.add("tabulator-col");
26  el.classList.add("tabulator-col-placeholder");
27 
28  return el;
29 };
30 
31 MoveColumns.prototype.initializeColumn = function (column) {
32  var self = this,
33  config = {},
34  colEl;
35 
36  if (!column.modules.frozen) {
37 
38  colEl = column.getElement();
39 
40  config.mousemove = function (e) {
41  if (column.parent === self.moving.parent) {
42  if ((self.touchMove ? e.touches[0].pageX : e.pageX) - Tabulator.prototype.helpers.elOffset(colEl).left + self.table.columnManager.element.scrollLeft > column.getWidth() / 2) {
43  if (self.toCol !== column || !self.toColAfter) {
44  colEl.parentNode.insertBefore(self.placeholderElement, colEl.nextSibling);
45  self.moveColumn(column, true);
46  }
47  } else {
48  if (self.toCol !== column || self.toColAfter) {
49  colEl.parentNode.insertBefore(self.placeholderElement, colEl);
50  self.moveColumn(column, false);
51  }
52  }
53  }
54  }.bind(self);
55 
56  colEl.addEventListener("mousedown", function (e) {
57  self.touchMove = false;
58  if (e.which === 1) {
59  self.checkTimeout = setTimeout(function () {
60  self.startMove(e, column);
61  }, self.checkPeriod);
62  }
63  });
64 
65  colEl.addEventListener("mouseup", function (e) {
66  if (e.which === 1) {
67  if (self.checkTimeout) {
68  clearTimeout(self.checkTimeout);
69  }
70  }
71  });
72 
73  self.bindTouchEvents(column);
74  }
75 
76  column.modules.moveColumn = config;
77 };
78 
79 MoveColumns.prototype.bindTouchEvents = function (column) {
80  var self = this,
81  colEl = column.getElement(),
82  startXMove = false,
83  //shifting center position of the cell
84  dir = false,
85  currentCol,
86  nextCol,
87  prevCol,
88  nextColWidth,
89  prevColWidth,
90  nextColWidthLast,
91  prevColWidthLast;
92 
93  colEl.addEventListener("touchstart", function (e) {
94  self.checkTimeout = setTimeout(function () {
95  self.touchMove = true;
96  currentCol = column;
97  nextCol = column.nextColumn();
98  nextColWidth = nextCol ? nextCol.getWidth() / 2 : 0;
99  prevCol = column.prevColumn();
100  prevColWidth = prevCol ? prevCol.getWidth() / 2 : 0;
101  nextColWidthLast = 0;
102  prevColWidthLast = 0;
103  startXMove = false;
104 
105  self.startMove(e, column);
106  }, self.checkPeriod);
107  }, { passive: true });
108 
109  colEl.addEventListener("touchmove", function (e) {
110  var halfCol, diff, moveToCol;
111 
112  if (self.moving) {
113  self.moveHover(e);
114 
115  if (!startXMove) {
116  startXMove = e.touches[0].pageX;
117  }
118 
119  diff = e.touches[0].pageX - startXMove;
120 
121  if (diff > 0) {
122  if (nextCol && diff - nextColWidthLast > nextColWidth) {
123  moveToCol = nextCol;
124 
125  if (moveToCol !== column) {
126  startXMove = e.touches[0].pageX;
127  moveToCol.getElement().parentNode.insertBefore(self.placeholderElement, moveToCol.getElement().nextSibling);
128  self.moveColumn(moveToCol, true);
129  }
130  }
131  } else {
132  if (prevCol && -diff - prevColWidthLast > prevColWidth) {
133  moveToCol = prevCol;
134 
135  if (moveToCol !== column) {
136  startXMove = e.touches[0].pageX;
137  moveToCol.getElement().parentNode.insertBefore(self.placeholderElement, moveToCol.getElement());
138  self.moveColumn(moveToCol, false);
139  }
140  }
141  }
142 
143  if (moveToCol) {
144  currentCol = moveToCol;
145  nextCol = moveToCol.nextColumn();
146  nextColWidthLast = nextColWidth;
147  nextColWidth = nextCol ? nextCol.getWidth() / 2 : 0;
148  prevCol = moveToCol.prevColumn();
149  prevColWidthLast = prevColWidth;
150  prevColWidth = prevCol ? prevCol.getWidth() / 2 : 0;
151  }
152  }
153  }, { passive: true });
154 
155  colEl.addEventListener("touchend", function (e) {
156  if (self.checkTimeout) {
157  clearTimeout(self.checkTimeout);
158  }
159  if (self.moving) {
160  self.endMove(e);
161  }
162  });
163 };
164 
165 MoveColumns.prototype.startMove = function (e, column) {
166  var element = column.getElement();
167 
168  this.moving = column;
169  this.startX = (this.touchMove ? e.touches[0].pageX : e.pageX) - Tabulator.prototype.helpers.elOffset(element).left;
170 
171  this.table.element.classList.add("tabulator-block-select");
172 
173  //create placeholder
174  this.placeholderElement.style.width = column.getWidth() + "px";
175  this.placeholderElement.style.height = column.getHeight() + "px";
176 
177  element.parentNode.insertBefore(this.placeholderElement, element);
178  element.parentNode.removeChild(element);
179 
180  //create hover element
181  this.hoverElement = element.cloneNode(true);
182  this.hoverElement.classList.add("tabulator-moving");
183 
184  this.table.columnManager.getElement().appendChild(this.hoverElement);
185 
186  this.hoverElement.style.left = "0";
187  this.hoverElement.style.bottom = "0";
188 
189  if (!this.touchMove) {
190  this._bindMouseMove();
191 
192  document.body.addEventListener("mousemove", this.moveHover);
193  document.body.addEventListener("mouseup", this.endMove);
194  }
195 
196  this.moveHover(e);
197 };
198 
199 MoveColumns.prototype._bindMouseMove = function () {
200  this.table.columnManager.columnsByIndex.forEach(function (column) {
201  if (column.modules.moveColumn.mousemove) {
202  column.getElement().addEventListener("mousemove", column.modules.moveColumn.mousemove);
203  }
204  });
205 };
206 
207 MoveColumns.prototype._unbindMouseMove = function () {
208  this.table.columnManager.columnsByIndex.forEach(function (column) {
209  if (column.modules.moveColumn.mousemove) {
210  column.getElement().removeEventListener("mousemove", column.modules.moveColumn.mousemove);
211  }
212  });
213 };
214 
215 MoveColumns.prototype.moveColumn = function (column, after) {
216  var movingCells = this.moving.getCells();
217 
218  this.toCol = column;
219  this.toColAfter = after;
220 
221  if (after) {
222  column.getCells().forEach(function (cell, i) {
223  var cellEl = cell.getElement();
224  cellEl.parentNode.insertBefore(movingCells[i].getElement(), cellEl.nextSibling);
225  });
226  } else {
227  column.getCells().forEach(function (cell, i) {
228  var cellEl = cell.getElement();
229  cellEl.parentNode.insertBefore(movingCells[i].getElement(), cellEl);
230  });
231  }
232 };
233 
234 MoveColumns.prototype.endMove = function (e) {
235  if (e.which === 1 || this.touchMove) {
236  this._unbindMouseMove();
237 
238  this.placeholderElement.parentNode.insertBefore(this.moving.getElement(), this.placeholderElement.nextSibling);
239  this.placeholderElement.parentNode.removeChild(this.placeholderElement);
240  this.hoverElement.parentNode.removeChild(this.hoverElement);
241 
242  this.table.element.classList.remove("tabulator-block-select");
243 
244  if (this.toCol) {
245  this.table.columnManager.moveColumnActual(this.moving, this.toCol, this.toColAfter);
246  }
247 
248  this.moving = false;
249  this.toCol = false;
250  this.toColAfter = false;
251 
252  if (!this.touchMove) {
253  document.body.removeEventListener("mousemove", this.moveHover);
254  document.body.removeEventListener("mouseup", this.endMove);
255  }
256  }
257 };
258 
259 MoveColumns.prototype.moveHover = function (e) {
260  var self = this,
261  columnHolder = self.table.columnManager.getElement(),
262  scrollLeft = columnHolder.scrollLeft,
263  xPos = (self.touchMove ? e.touches[0].pageX : e.pageX) - Tabulator.prototype.helpers.elOffset(columnHolder).left + scrollLeft,
264  scrollPos;
265 
266  self.hoverElement.style.left = xPos - self.startX + "px";
267 
268  if (xPos - scrollLeft < self.autoScrollMargin) {
269  if (!self.autoScrollTimeout) {
270  self.autoScrollTimeout = setTimeout(function () {
271  scrollPos = Math.max(0, scrollLeft - 5);
272  self.table.rowManager.getElement().scrollLeft = scrollPos;
273  self.autoScrollTimeout = false;
274  }, 1);
275  }
276  }
277 
278  if (scrollLeft + columnHolder.clientWidth - xPos < self.autoScrollMargin) {
279  if (!self.autoScrollTimeout) {
280  self.autoScrollTimeout = setTimeout(function () {
281  scrollPos = Math.min(columnHolder.clientWidth, scrollLeft + 5);
282  self.table.rowManager.getElement().scrollLeft = scrollPos;
283  self.autoScrollTimeout = false;
284  }, 1);
285  }
286  }
287 };
288 
289 Tabulator.prototype.registerModule("moveColumn", MoveColumns);