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