otsdaq_utilities  v2_05_02_indev
row.js
1 
2 //public row object
3 var RowComponent = function (row){
4  this._row = row;
5 };
6 
7 RowComponent.prototype.getData = function(transform){
8  return this._row.getData(transform);
9 };
10 
11 RowComponent.prototype.getElement = function(){
12  return this._row.getElement();
13 };
14 
15 RowComponent.prototype.getCells = function(){
16  var cells = [];
17 
18  this._row.getCells().forEach(function(cell){
19  cells.push(cell.getComponent());
20  });
21 
22  return cells;
23 };
24 
25 RowComponent.prototype.getCell = function(column){
26  var cell = this._row.getCell(column);
27  return cell ? cell.getComponent() : false;
28 };
29 
30 RowComponent.prototype.getIndex = function(){
31  return this._row.getData("data")[this._row.table.options.index];
32 };
33 
34 RowComponent.prototype.getPosition = function(active){
35  return this._row.table.rowManager.getRowPosition(this._row, active);
36 };
37 
38 RowComponent.prototype.delete = function(){
39  return this._row.delete();
40 };
41 
42 RowComponent.prototype.scrollTo = function(){
43  return this._row.table.rowManager.scrollToRow(this._row);
44 };
45 
46 RowComponent.prototype.pageTo = function(){
47  if(this._row.table.modExists("page", true)){
48  return this._row.table.modules.page.setPageToRow(this._row);
49  }
50 };
51 
52 RowComponent.prototype.move = function(to, after){
53  this._row.moveToRow(to, after);
54 };
55 
56 RowComponent.prototype.update = function(data){
57  return this._row.updateData(data);
58 };
59 
60 RowComponent.prototype.normalizeHeight = function(){
61  this._row.normalizeHeight(true);
62 };
63 
64 RowComponent.prototype.select = function(){
65  this._row.table.modules.selectRow.selectRows(this._row);
66 };
67 
68 RowComponent.prototype.deselect = function(){
69  this._row.table.modules.selectRow.deselectRows(this._row);
70 };
71 
72 RowComponent.prototype.toggleSelect = function(){
73  this._row.table.modules.selectRow.toggleRow(this._row);
74 };
75 
76 RowComponent.prototype.isSelected = function(){
77  return this._row.table.modules.selectRow.isRowSelected(this._row);
78 };
79 
80 RowComponent.prototype._getSelf = function(){
81  return this._row;
82 };
83 
84 RowComponent.prototype.freeze = function(){
85  if(this._row.table.modExists("frozenRows", true)){
86  this._row.table.modules.frozenRows.freezeRow(this._row);
87  }
88 };
89 
90 RowComponent.prototype.unfreeze = function(){
91  if(this._row.table.modExists("frozenRows", true)){
92  this._row.table.modules.frozenRows.unfreezeRow(this._row);
93  }
94 };
95 
96 RowComponent.prototype.treeCollapse = function(){
97  if(this._row.table.modExists("dataTree", true)){
98  this._row.table.modules.dataTree.collapseRow(this._row);
99  }
100 };
101 
102 RowComponent.prototype.treeExpand = function(){
103  if(this._row.table.modExists("dataTree", true)){
104  this._row.table.modules.dataTree.expandRow(this._row);
105  }
106 };
107 
108 RowComponent.prototype.treeToggle = function(){
109  if(this._row.table.modExists("dataTree", true)){
110  this._row.table.modules.dataTree.toggleRow(this._row);
111  }
112 };
113 
114 RowComponent.prototype.getTreeParent = function(){
115  if(this._row.table.modExists("dataTree", true)){
116  return this._row.table.modules.dataTree.getTreeParent(this._row);
117  }
118 
119  return false;
120 };
121 
122 RowComponent.prototype.getTreeChildren = function(){
123  if(this._row.table.modExists("dataTree", true)){
124  return this._row.table.modules.dataTree.getTreeChildren(this._row);
125  }
126 
127  return false;
128 };
129 
130 RowComponent.prototype.reformat = function(){
131  return this._row.reinitialize();
132 };
133 
134 RowComponent.prototype.getGroup = function(){
135  return this._row.getGroup().getComponent();
136 };
137 
138 RowComponent.prototype.getTable = function(){
139  return this._row.table;
140 };
141 
142 RowComponent.prototype.getNextRow = function(){
143  var row = this._row.nextRow();
144  return row ? row.getComponent() : row;
145 };
146 
147 RowComponent.prototype.getPrevRow = function(){
148  var row = this._row.prevRow();
149  return row ? row.getComponent() : row;
150 };
151 
152 
153 var Row = function(data, parent, type = "row"){
154  this.table = parent.table;
155  this.parent = parent;
156  this.data = {};
157  this.type = type; //type of element
158  this.element = this.createElement();
159  this.modules = {}; //hold module variables;
160  this.cells = [];
161  this.height = 0; //hold element height
162  this.heightStyled = ""; //hold element height prestyled to improve render efficiency
163  this.manualHeight = false; //user has manually set row height
164  this.outerHeight = 0; //holde lements outer height
165  this.initialized = false; //element has been rendered
166  this.heightInitialized = false; //element has resized cells to fit
167 
168  this.setData(data);
169  this.generateElement();
170 };
171 
172 Row.prototype.createElement = function (){
173  var el = document.createElement("div");
174 
175  el.classList.add("tabulator-row");
176  el.setAttribute("role", "row");
177 
178  return el;
179 };
180 
181 Row.prototype.getElement = function(){
182  return this.element;
183 };
184 
185 Row.prototype.detachElement = function(){
186  if (this.element && this.element.parentNode){
187  this.element.parentNode.removeChild(this.element);
188  }
189 };
190 
191 Row.prototype.generateElement = function(){
192  var self = this,
193  dblTap, tapHold, tap;
194 
195  //set row selection characteristics
196  if(self.table.options.selectable !== false && self.table.modExists("selectRow")){
197  self.table.modules.selectRow.initializeRow(this);
198  }
199 
200  //setup movable rows
201  if(self.table.options.movableRows !== false && self.table.modExists("moveRow")){
202  self.table.modules.moveRow.initializeRow(this);
203  }
204 
205  //setup data tree
206  if(self.table.options.dataTree !== false && self.table.modExists("dataTree")){
207  self.table.modules.dataTree.initializeRow(this);
208  }
209 
210  //setup column colapse container
211  if(self.table.options.responsiveLayout === "collapse" && self.table.modExists("responsiveLayout")){
212  self.table.modules.responsiveLayout.initializeRow(this);
213  }
214 
215  //handle row click events
216  if (self.table.options.rowClick){
217  self.element.addEventListener("click", function(e){
218  self.table.options.rowClick(e, self.getComponent());
219  });
220  }
221 
222  if (self.table.options.rowDblClick){
223  self.element.addEventListener("dblclick", function(e){
224  self.table.options.rowDblClick(e, self.getComponent());
225  });
226  }
227 
228  if (self.table.options.rowContext){
229  self.element.addEventListener("contextmenu", function(e){
230  self.table.options.rowContext(e, self.getComponent());
231  });
232  }
233 
234 
235  //handle mouse events
236  if (self.table.options.rowMouseEnter){
237  self.element.addEventListener("mouseenter", function(e){
238  self.table.options.rowMouseEnter(e, self.getComponent());
239  });
240  }
241 
242  if (self.table.options.rowMouseLeave){
243  self.element.addEventListener("mouseleave", function(e){
244  self.table.options.rowMouseLeave(e, self.getComponent());
245  });
246  }
247 
248  if (self.table.options.rowMouseOver){
249  self.element.addEventListener("mouseover", function(e){
250  self.table.options.rowMouseOver(e, self.getComponent());
251  });
252  }
253 
254  if (self.table.options.rowMouseOut){
255  self.element.addEventListener("mouseout", function(e){
256  self.table.options.rowMouseOut(e, self.getComponent());
257  });
258  }
259 
260  if (self.table.options.rowMouseMove){
261  self.element.addEventListener("mousemove", function(e){
262  self.table.options.rowMouseMove(e, self.getComponent());
263  });
264  }
265 
266 
267  if (self.table.options.rowTap){
268 
269  tap = false;
270 
271  self.element.addEventListener("touchstart", function(e){
272  tap = true;
273  }, {passive: true});
274 
275  self.element.addEventListener("touchend", function(e){
276  if(tap){
277  self.table.options.rowTap(e, self.getComponent());
278  }
279 
280  tap = false;
281  });
282  }
283 
284  if (self.table.options.rowDblTap){
285 
286  dblTap = null;
287 
288  self.element.addEventListener("touchend", function(e){
289 
290  if(dblTap){
291  clearTimeout(dblTap);
292  dblTap = null;
293 
294  self.table.options.rowDblTap(e, self.getComponent());
295  }else{
296 
297  dblTap = setTimeout(function(){
298  clearTimeout(dblTap);
299  dblTap = null;
300  }, 300);
301  }
302 
303  });
304  }
305 
306 
307  if (self.table.options.rowTapHold){
308 
309  tapHold = null;
310 
311  self.element.addEventListener("touchstart", function(e){
312  clearTimeout(tapHold);
313 
314  tapHold = setTimeout(function(){
315  clearTimeout(tapHold);
316  tapHold = null;
317  tap = false;
318  self.table.options.rowTapHold(e, self.getComponent());
319  }, 1000);
320 
321  }, {passive: true});
322 
323  self.element.addEventListener("touchend", function(e){
324  clearTimeout(tapHold);
325  tapHold = null;
326  });
327  }
328 };
329 
330 Row.prototype.generateCells = function(){
331  this.cells = this.table.columnManager.generateCells(this);
332 };
333 
334 //functions to setup on first render
335 Row.prototype.initialize = function(force){
336  var self = this;
337 
338  if(!self.initialized || force){
339 
340  self.deleteCells();
341 
342  while(self.element.firstChild) self.element.removeChild(self.element.firstChild);
343 
344  //handle frozen cells
345  if(this.table.modExists("frozenColumns")){
346  this.table.modules.frozenColumns.layoutRow(this);
347  }
348 
349  this.generateCells();
350 
351  self.cells.forEach(function(cell){
352  self.element.appendChild(cell.getElement());
353  cell.cellRendered();
354  });
355 
356  if(force){
357  self.normalizeHeight();
358  }
359 
360  //setup movable rows
361  if(self.table.options.dataTree && self.table.modExists("dataTree")){
362  self.table.modules.dataTree.layoutRow(this);
363  }
364 
365  //setup column colapse container
366  if(self.table.options.responsiveLayout === "collapse" && self.table.modExists("responsiveLayout")){
367  self.table.modules.responsiveLayout.layoutRow(this);
368  }
369 
370  if(self.table.options.rowFormatter){
371  self.table.options.rowFormatter(self.getComponent());
372  }
373 
374  //set resizable handles
375  if(self.table.options.resizableRows && self.table.modExists("resizeRows")){
376  self.table.modules.resizeRows.initializeRow(self);
377  }
378 
379  self.initialized = true;
380  }
381 };
382 
383 Row.prototype.reinitializeHeight = function(){
384  this.heightInitialized = false;
385 
386  if(this.element.offsetParent !== null){
387  this.normalizeHeight(true);
388  }
389 };
390 
391 
392 Row.prototype.reinitialize = function(){
393  this.initialized = false;
394  this.heightInitialized = false;
395 
396  if(!this.manualHeight){
397  this.height = 0;
398  this.heightStyled = "";
399  }
400 
401  if(this.element.offsetParent !== null){
402  this.initialize(true);
403  }
404 };
405 
406 //get heights when doing bulk row style calcs in virtual DOM
407 Row.prototype.calcHeight = function(force){
408 
409  var maxHeight = 0,
410  minHeight = this.table.options.resizableRows ? this.element.clientHeight : 0;
411 
412  this.cells.forEach(function(cell){
413  var height = cell.getHeight();
414  if(height > maxHeight){
415  maxHeight = height;
416  }
417  });
418 
419  if(force){
420  this.height = Math.max(maxHeight, minHeight);
421  }else{
422  this.height = this.manualHeight ? this.height : Math.max(maxHeight, minHeight);
423  }
424 
425  this.heightStyled = this.height ? this.height + "px" : "";
426  this.outerHeight = this.element.offsetHeight;
427 };
428 
429 //set of cells
430 Row.prototype.setCellHeight = function(){
431  this.cells.forEach(function(cell){
432  cell.setHeight();
433  });
434 
435  this.heightInitialized = true;
436 };
437 
438 Row.prototype.clearCellHeight = function(){
439  this.cells.forEach(function(cell){
440  cell.clearHeight();
441  });
442 };
443 
444 //normalize the height of elements in the row
445 Row.prototype.normalizeHeight = function(force){
446 
447  if(force){
448  this.clearCellHeight();
449  }
450 
451  this.calcHeight(force);
452 
453  this.setCellHeight();
454 };
455 
456 // Row.prototype.setHeight = function(height){
457 // this.height = height;
458 
459 // this.setCellHeight();
460 // };
461 
462 //set height of rows
463 Row.prototype.setHeight = function(height, force){
464  if(this.height != height || force){
465 
466  this.manualHeight = true;
467 
468  this.height = height;
469  this.heightStyled = height ? height + "px" : "";
470 
471  this.setCellHeight();
472 
473  // this.outerHeight = this.element.outerHeight();
474  this.outerHeight = this.element.offsetHeight;
475  }
476 };
477 
478 //return rows outer height
479 Row.prototype.getHeight = function(){
480  return this.outerHeight;
481 };
482 
483 //return rows outer Width
484 Row.prototype.getWidth = function(){
485  return this.element.offsetWidth;
486 };
487 
488 
490 
491 Row.prototype.deleteCell = function(cell){
492  var index = this.cells.indexOf(cell);
493 
494  if(index > -1){
495  this.cells.splice(index, 1);
496  }
497 };
498 
500 
501 Row.prototype.setData = function(data){
502  if(this.table.modExists("mutator")){
503  data = this.table.modules.mutator.transformRow(data, "data", data);
504  }
505 
506  this.data = data;
507 
508  if(this.table.options.reactiveData && this.table.modExists("reactiveData", true)){
509  this.table.modules.reactiveData.watchRow(this);
510  }
511 };
512 
513 //update the rows data
514 Row.prototype.updateData = function(data){
515  var visible = Tabulator.prototype.helpers.elVisible(this.element),
516  tempData = {};
517 
518  return new Promise((resolve, reject) => {
519 
520  if(typeof data === "string"){
521  data = JSON.parse(data);
522  }
523 
524  if(this.table.options.reactiveData && this.table.modExists("reactiveData", true)){
525  this.table.modules.reactiveData.block();
526  }
527 
528  //mutate incomming data if needed
529  if(this.table.modExists("mutator")){
530 
531  tempData = Object.assign(tempData, this.data);
532  tempData = Object.assign(tempData, data);
533 
534  data = this.table.modules.mutator.transformRow(tempData, "data", data);
535  }
536 
537  //set data
538  for (var attrname in data) {
539  this.data[attrname] = data[attrname];
540  }
541 
542  if(this.table.options.reactiveData && this.table.modExists("reactiveData", true)){
543  this.table.modules.reactiveData.unblock();
544  }
545 
546  //update affected cells only
547  for (var attrname in data) {
548 
549  let columns = this.table.columnManager.getColumnsByFieldRoot(attrname);
550 
551  columns.forEach((column) => {
552  let cell = this.getCell(column.getField());
553 
554  if(cell){
555  let value = column.getFieldValue(data);
556  if(cell.getValue() != value){
557  cell.setValueProcessData(value);
558 
559  if(visible){
560  cell.cellRendered();
561  }
562  }
563  }
564  });
565  }
566 
567  //Partial reinitialization if visible
568  if(visible){
569  this.normalizeHeight();
570 
571  if(this.table.options.rowFormatter){
572  this.table.options.rowFormatter(this.getComponent());
573  }
574  }else{
575  this.initialized = false;
576  this.height = 0;
577  this.heightStyled = "";
578  }
579 
580  if(this.table.options.dataTree !== false && this.table.modExists("dataTree") && this.table.modules.dataTree.redrawNeeded(data)){
581  this.table.modules.dataTree.initializeRow(this);
582  this.table.modules.dataTree.layoutRow(this);
583  this.table.rowManager.refreshActiveData("tree", false, true);
584  }
585 
586  //this.reinitialize();
587 
588  this.table.options.rowUpdated.call(this.table, this.getComponent());
589 
590  resolve();
591  });
592 };
593 
594 Row.prototype.getData = function(transform){
595  var self = this;
596 
597  if(transform){
598  if(self.table.modExists("accessor")){
599  return self.table.modules.accessor.transformRow(self.data, transform);
600  }
601  }else{
602  return this.data;
603  }
604 
605 };
606 
607 Row.prototype.getCell = function(column){
608  var match = false;
609 
610  column = this.table.columnManager.findColumn(column);
611 
612  match = this.cells.find(function(cell){
613  return cell.column === column;
614  });
615 
616  return match;
617 };
618 
619 Row.prototype.getCellIndex = function(findCell){
620  return this.cells.findIndex(function(cell){
621  return cell === findCell;
622  });
623 };
624 
625 
626 Row.prototype.findNextEditableCell = function(index){
627  var nextCell = false;
628 
629  if(index < this.cells.length-1){
630  for(var i = index+1; i < this.cells.length; i++){
631  let cell = this.cells[i];
632 
633  if(cell.column.modules.edit && Tabulator.prototype.helpers.elVisible(cell.getElement())){
634  let allowEdit = true;
635 
636  if(typeof cell.column.modules.edit.check == "function"){
637  allowEdit = cell.column.modules.edit.check(cell.getComponent());
638  }
639 
640  if(allowEdit){
641  nextCell = cell;
642  break;
643  }
644  }
645  }
646  }
647 
648  return nextCell;
649 };
650 
651 Row.prototype.findPrevEditableCell = function(index){
652  var prevCell = false;
653 
654  if(index > 0){
655  for(var i = index-1; i >= 0; i--){
656  let cell = this.cells[i],
657  allowEdit = true;
658 
659  if(cell.column.modules.edit && Tabulator.prototype.helpers.elVisible(cell.getElement())){
660  if(typeof cell.column.modules.edit.check == "function"){
661  allowEdit = cell.column.modules.edit.check(cell.getComponent());
662  }
663 
664  if(allowEdit){
665  prevCell = cell;
666  break;
667  }
668  }
669  }
670  }
671 
672  return prevCell;
673 };
674 
675 Row.prototype.getCells = function(){
676  return this.cells;
677 };
678 
679 Row.prototype.nextRow = function(){
680  var row = this.table.rowManager.nextDisplayRow(this, true);
681  return row || false;
682 };
683 
684 Row.prototype.prevRow = function(){
685  var row = this.table.rowManager.prevDisplayRow(this, true);
686  return row || false;
687 };
688 
689 Row.prototype.moveToRow = function(to, before){
690  var toRow = this.table.rowManager.findRow(to);
691 
692  if(toRow){
693  this.table.rowManager.moveRowActual(this, toRow, !before);
694  this.table.rowManager.refreshActiveData("display", false, true);
695  }else{
696  console.warn("Move Error - No matching row found:", to);
697  }
698 };
699 
700 
702 
703 Row.prototype.delete = function(){
704  return new Promise((resolve, reject) => {
705  var index, rows;
706 
707  if(this.table.options.history && this.table.modExists("history")){
708 
709  if(this.table.options.groupBy && this.table.modExists("groupRows")){
710  rows = this.getGroup().rows
711  index = rows.indexOf(this);
712 
713  if(index){
714  index = rows[index-1];
715  }
716  }else{
717  index = this.table.rowManager.getRowIndex(this);
718 
719  if(index){
720  index = this.table.rowManager.rows[index-1];
721  }
722  }
723 
724  this.table.modules.history.action("rowDelete", this, {data:this.getData(), pos:!index, index:index});
725  }
726 
727  this.deleteActual();
728 
729 
730  resolve();
731  });
732 };
733 
734 
735 Row.prototype.deleteActual = function(blockRedraw){
736  var index = this.table.rowManager.getRowIndex(this);
737 
738  //deselect row if it is selected
739  if(this.table.modExists("selectRow")){
740  this.table.modules.selectRow._deselectRow(this, true);
741  }
742 
743  // if(this.table.options.dataTree && this.table.modExists("dataTree")){
744  // this.table.modules.dataTree.collapseRow(this, true);
745  // }
746 
747  //remove any reactive data watchers from row object
748  if(this.table.options.reactiveData && this.table.modExists("reactiveData", true)){
749  // this.table.modules.reactiveData.unwatchRow(this);
750  }
751 
752  //remove from group
753  if(this.modules.group){
754  this.modules.group.removeRow(this);
755  }
756 
757  this.table.rowManager.deleteRow(this, blockRedraw);
758 
759  this.deleteCells();
760 
761  this.initialized = false;
762  this.heightInitialized = false;
763 
764  //recalc column calculations if present
765  if(this.table.modExists("columnCalcs")){
766  if(this.table.options.groupBy && this.table.modExists("groupRows")){
767  this.table.modules.columnCalcs.recalcRowGroup(this);
768  }else{
769  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
770  }
771  }
772 };
773 
774 Row.prototype.deleteCells = function(){
775  var cellCount = this.cells.length;
776 
777  for(let i = 0; i < cellCount; i++){
778  this.cells[0].delete();
779  }
780 };
781 
782 Row.prototype.wipe = function(){
783  this.deleteCells();
784 
785  while(this.element.firstChild) this.element.removeChild(this.element.firstChild);
786 
787  this.element = false;
788  this.modules = {};
789 
790  if(this.element.parentNode){
791  this.element.parentNode.removeChild(this.element);
792  }
793 };
794 
795 
796 Row.prototype.getGroup = function(){
797  return this.modules.group || false;
798 };
799 
800 
802 Row.prototype.getComponent = function(){
803  return new RowComponent(this);
804 };