otsdaq_utilities  v2_05_02_indev
cell.js
1 
2 //public row object
3 var CellComponent = function (cell){
4  this._cell = cell;
5 };
6 
7 CellComponent.prototype.getValue = function(){
8  return this._cell.getValue();
9 };
10 
11 CellComponent.prototype.getOldValue = function(){
12  return this._cell.getOldValue();
13 };
14 
15 CellComponent.prototype.getElement = function(){
16  return this._cell.getElement();
17 };
18 
19 CellComponent.prototype.getRow = function(){
20  return this._cell.row.getComponent();
21 };
22 
23 CellComponent.prototype.getData = function(){
24  return this._cell.row.getData();
25 };
26 
27 CellComponent.prototype.getField = function(){
28  return this._cell.column.getField();
29 };
30 
31 CellComponent.prototype.getColumn = function(){
32  return this._cell.column.getComponent();
33 };
34 
35 CellComponent.prototype.setValue = function(value, mutate){
36  if(typeof mutate == "undefined"){
37  mutate = true;
38  }
39 
40  this._cell.setValue(value, mutate);
41 };
42 
43 CellComponent.prototype.restoreOldValue = function(){
44  this._cell.setValueActual(this._cell.getOldValue());
45 };
46 
47 CellComponent.prototype.edit = function(force){
48  return this._cell.edit(force);
49 };
50 
51 CellComponent.prototype.cancelEdit = function(){
52  this._cell.cancelEdit();
53 };
54 
55 
56 CellComponent.prototype.nav = function(){
57  return this._cell.nav();
58 };
59 
60 CellComponent.prototype.checkHeight = function(){
61  this._cell.checkHeight();
62 };
63 
64 CellComponent.prototype.getTable = function(){
65  return this._cell.table;
66 };
67 
68 CellComponent.prototype._getSelf = function(){
69  return this._cell;
70 };
71 
72 
73 
74 var Cell = function(column, row){
75 
76  this.table = column.table;
77  this.column = column;
78  this.row = row;
79  this.element = null;
80  this.value = null;
81  this.oldValue = null;
82  this.modules = {};
83 
84  this.height = null;
85  this.width = null;
86  this.minWidth = null;
87 
88  this.build();
89 };
90 
92 
93 //generate element
94 Cell.prototype.build = function(){
95  this.generateElement();
96 
97  this.setWidth();
98 
99  this._configureCell();
100 
101  this.setValueActual(this.column.getFieldValue(this.row.data));
102 };
103 
104 Cell.prototype.generateElement = function(){
105  this.element = document.createElement('div');
106  this.element.className = "tabulator-cell";
107  this.element.setAttribute("role", "gridcell");
108  this.element = this.element;
109 };
110 
111 
112 Cell.prototype._configureCell = function(){
113  var self = this,
114  cellEvents = self.column.cellEvents,
115  element = self.element,
116  field = this.column.getField();
117 
118  //set text alignment
119  element.style.textAlign = self.column.hozAlign;
120 
121  if(field){
122  element.setAttribute("tabulator-field", field);
123  }
124 
125  //add class to cell if needed
126  if(self.column.definition.cssClass){
127  var classNames = self.column.definition.cssClass.split(" ")
128  classNames.forEach(function(className) {
129  element.classList.add(className)
130  });
131  }
132 
133  //update tooltip on mouse enter
134  if (this.table.options.tooltipGenerationMode === "hover"){
135  element.addEventListener("mouseenter", function(e){
136  self._generateTooltip();
137  });
138  }
139 
140  self._bindClickEvents(cellEvents);
141 
142  self._bindTouchEvents(cellEvents);
143 
144  self._bindMouseEvents(cellEvents);
145 
146  if(self.column.modules.edit){
147  self.table.modules.edit.bindEditor(self);
148  }
149 
150  if(self.column.definition.rowHandle && self.table.options.movableRows !== false && self.table.modExists("moveRow")){
151  self.table.modules.moveRow.initializeCell(self);
152  }
153 
154  //hide cell if not visible
155  if(!self.column.visible){
156  self.hide();
157  }
158 };
159 
160 Cell.prototype._bindClickEvents = function(cellEvents){
161  var self = this,
162  element = self.element;
163 
164  //set event bindings
165  if (cellEvents.cellClick || self.table.options.cellClick){
166  element.addEventListener("click", function(e){
167  var component = self.getComponent();
168 
169  if(cellEvents.cellClick){
170  cellEvents.cellClick.call(self.table, e, component);
171  }
172 
173  if(self.table.options.cellClick){
174  self.table.options.cellClick.call(self.table, e, component);
175  }
176  });
177  }
178 
179  if (cellEvents.cellDblClick || this.table.options.cellDblClick){
180  element.addEventListener("dblclick", function(e){
181  var component = self.getComponent();
182 
183  if(cellEvents.cellDblClick){
184  cellEvents.cellDblClick.call(self.table, e, component);
185  }
186 
187  if(self.table.options.cellDblClick){
188  self.table.options.cellDblClick.call(self.table, e, component);
189  }
190  });
191  }else{
192  element.addEventListener("dblclick", function(e){
193  e.preventDefault();
194 
195  try{
196  if (document.selection) { // IE
197  var range = document.body.createTextRange();
198  range.moveToElementText(self.element);
199  range.select();
200  } else if (window.getSelection) {
201  var range = document.createRange();
202  range.selectNode(self.element);
203  window.getSelection().removeAllRanges();
204  window.getSelection().addRange(range);
205  }
206  }catch(e){}
207  });
208  }
209 
210  if (cellEvents.cellContext || this.table.options.cellContext){
211  element.addEventListener("contextmenu", function(e){
212  var component = self.getComponent();
213 
214  if(cellEvents.cellContext){
215  cellEvents.cellContext.call(self.table, e, component);
216  }
217 
218  if(self.table.options.cellContext){
219  self.table.options.cellContext.call(self.table, e, component);
220  }
221  });
222  }
223 };
224 
225 
226 Cell.prototype._bindMouseEvents = function(cellEvents){
227  var self = this,
228  element = self.element;
229 
230  if (cellEvents.cellMouseEnter || self.table.options.cellMouseEnter){
231  element.addEventListener("mouseenter", function(e){
232  var component = self.getComponent();
233 
234  if(cellEvents.cellMouseEnter){
235  cellEvents.cellMouseEnter.call(self.table, e, component);
236  }
237 
238  if(self.table.options.cellMouseEnter){
239  self.table.options.cellMouseEnter.call(self.table, e, component);
240  }
241  });
242  }
243 
244  if (cellEvents.cellMouseLeave || self.table.options.cellMouseLeave){
245  element.addEventListener("mouseleave", function(e){
246  var component = self.getComponent();
247 
248  if(cellEvents.cellMouseLeave){
249  cellEvents.cellMouseLeave.call(self.table, e, component);
250  }
251 
252  if(self.table.options.cellMouseLeave){
253  self.table.options.cellMouseLeave.call(self.table, e, component);
254  }
255  });
256  }
257 
258  if (cellEvents.cellMouseOver || self.table.options.cellMouseOver){
259  element.addEventListener("mouseover", function(e){
260  var component = self.getComponent();
261 
262  if(cellEvents.cellMouseOver){
263  cellEvents.cellMouseOver.call(self.table, e, component);
264  }
265 
266  if(self.table.options.cellMouseOver){
267  self.table.options.cellMouseOver.call(self.table, e, component);
268  }
269  });
270  }
271 
272  if (cellEvents.cellMouseOut || self.table.options.cellMouseOut){
273  element.addEventListener("mouseout", function(e){
274  var component = self.getComponent();
275 
276  if(cellEvents.cellMouseOut){
277  cellEvents.cellMouseOut.call(self.table, e, component);
278  }
279 
280  if(self.table.options.cellMouseOut){
281  self.table.options.cellMouseOut.call(self.table, e, component);
282  }
283  });
284  }
285 
286  if (cellEvents.cellMouseMove || self.table.options.cellMouseMove){
287  element.addEventListener("mousemove", function(e){
288  var component = self.getComponent();
289 
290  if(cellEvents.cellMouseMove){
291  cellEvents.cellMouseMove.call(self.table, e, component);
292  }
293 
294  if(self.table.options.cellMouseMove){
295  self.table.options.cellMouseMove.call(self.table, e, component);
296  }
297  });
298  }
299 
300 
301 };
302 
303 
304 Cell.prototype._bindTouchEvents = function(cellEvents){
305  var self = this,
306  element = self.element,
307  dblTap, tapHold, tap;
308 
309  if (cellEvents.cellTap || this.table.options.cellTap){
310  tap = false;
311 
312  element.addEventListener("touchstart", function(e){
313  tap = true;
314  }, {passive: true});
315 
316  element.addEventListener("touchend", function(e){
317  if(tap){
318  var component = self.getComponent();
319 
320  if(cellEvents.cellTap){
321  cellEvents.cellTap.call(self.table, e, component);
322  }
323 
324  if(self.table.options.cellTap){
325  self.table.options.cellTap.call(self.table, e, component);
326  }
327  }
328 
329  tap = false;
330  });
331  }
332 
333  if (cellEvents.cellDblTap || this.table.options.cellDblTap){
334  dblTap = null;
335 
336  element.addEventListener("touchend", function(e){
337 
338  if(dblTap){
339  clearTimeout(dblTap);
340  dblTap = null;
341 
342  var component = self.getComponent();
343 
344  if(cellEvents.cellDblTap){
345  cellEvents.cellDblTap.call(self.table, e, component);
346  }
347 
348  if(self.table.options.cellDblTap){
349  self.table.options.cellDblTap.call(self.table, e, component);
350  }
351  }else{
352 
353  dblTap = setTimeout(function(){
354  clearTimeout(dblTap);
355  dblTap = null;
356  }, 300);
357  }
358 
359  });
360  }
361 
362  if (cellEvents.cellTapHold || this.table.options.cellTapHold){
363  tapHold = null;
364 
365  element.addEventListener("touchstart", function(e){
366  clearTimeout(tapHold);
367 
368  tapHold = setTimeout(function(){
369  clearTimeout(tapHold);
370  tapHold = null;
371  tap = false;
372  var component = self.getComponent();
373 
374  if(cellEvents.cellTapHold){
375  cellEvents.cellTapHold.call(self.table, e, component);
376  }
377 
378  if(self.table.options.cellTapHold){
379  self.table.options.cellTapHold.call(self.table, e, component);
380  }
381  }, 1000);
382 
383  }, {passive: true});
384 
385  element.addEventListener("touchend", function(e){
386  clearTimeout(tapHold);
387  tapHold = null;
388  });
389  }
390 };
391 
392 
393 //generate cell contents
394 Cell.prototype._generateContents = function(){
395  var val;
396 
397  if(this.table.modExists("format")){
398  val = this.table.modules.format.formatValue(this);
399  }else{
400  val = this.element.innerHTML = this.value;
401  }
402 
403  switch(typeof val){
404  case "object":
405  if(val instanceof Node){
406 
407  //clear previous cell contents
408  while(this.element.firstChild) this.element.removeChild(this.element.firstChild);
409 
410  this.element.appendChild(val);
411  }else{
412  this.element.innerHTML = "";
413 
414  if(val != null){
415  console.warn("Format Error - Formatter has returned a type of object, the only valid formatter object return is an instance of Node, the formatter returned:", val);
416  }
417  }
418  break;
419  case "undefined":
420  case "null":
421  this.element.innerHTML = "";
422  break;
423  default:
424  this.element.innerHTML = val;
425  }
426 };
427 
428 Cell.prototype.cellRendered = function(){
429  if(this.table.modExists("format") && this.table.modules.format.cellRendered){
430  this.table.modules.format.cellRendered(this);
431  }
432 };
433 
434 //generate tooltip text
435 Cell.prototype._generateTooltip = function(){
436  var tooltip = this.column.tooltip;
437 
438  if(tooltip){
439  if(tooltip === true){
440  tooltip = this.value;
441  }else if(typeof(tooltip) == "function"){
442  tooltip = tooltip(this.getComponent());
443 
444  if(tooltip === false){
445  tooltip = "";
446  }
447  }
448 
449  if(typeof tooltip === "undefined"){
450  tooltip = "";
451  }
452 
453  this.element.setAttribute("title", tooltip);
454  }else{
455  this.element.setAttribute("title", "");
456  }
457 };
458 
459 
461 Cell.prototype.getElement = function(){
462  return this.element;
463 };
464 
465 Cell.prototype.getValue = function(){
466  return this.value;
467 };
468 
469 Cell.prototype.getOldValue = function(){
470  return this.oldValue;
471 };
472 
474 
475 Cell.prototype.setValue = function(value, mutate){
476 
477  var changed = this.setValueProcessData(value, mutate),
478  component;
479 
480  if(changed){
481  if(this.table.options.history && this.table.modExists("history")){
482  this.table.modules.history.action("cellEdit", this, {oldValue:this.oldValue, newValue:this.value});
483  }
484 
485  component = this.getComponent();
486 
487  if(this.column.cellEvents.cellEdited){
488  this.column.cellEvents.cellEdited.call(this.table, component);
489  }
490 
491  this.table.options.cellEdited.call(this.table, component);
492 
493  this.table.options.dataEdited.call(this.table, this.table.rowManager.getData());
494  }
495 
496 };
497 
498 Cell.prototype.setValueProcessData = function(value, mutate){
499  var changed = false;
500 
501  if(this.value != value){
502 
503  changed = true;
504 
505  if(mutate){
506  if(this.column.modules.mutate){
507  value = this.table.modules.mutator.transformCell(this, value);
508  }
509  }
510  }
511 
512  this.setValueActual(value);
513 
514  if(changed && this.table.modExists("columnCalcs")){
515  if(this.column.definition.topCalc || this.column.definition.bottomCalc){
516  if(this.table.options.groupBy && this.table.modExists("groupRows")){
517 
518  if(this.table.options.columnCalcs == "table" || this.table.options.columnCalcs == "both"){
519  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
520  }
521 
522  if(this.table.options.columnCalcs != "table"){
523  this.table.modules.columnCalcs.recalcRowGroup(this.row);
524  }
525 
526  }else{
527  this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows);
528  }
529  }
530  }
531 
532  return changed;
533 };
534 
535 Cell.prototype.setValueActual = function(value){
536  this.oldValue = this.value;
537 
538  this.value = value;
539 
540  if(this.table.options.reactiveData && this.table.modExists("reactiveData")){
541  this.table.modules.reactiveData.block();
542  }
543 
544  this.column.setFieldValue(this.row.data, value);
545 
546  if(this.table.options.reactiveData && this.table.modExists("reactiveData")){
547  this.table.modules.reactiveData.unblock();
548  }
549 
550  this._generateContents();
551  this._generateTooltip();
552 
553  //set resizable handles
554  if(this.table.options.resizableColumns && this.table.modExists("resizeColumns")){
555  this.table.modules.resizeColumns.initializeColumn("cell", this.column, this.element);
556  }
557 
558  //handle frozen cells
559  if(this.table.modExists("frozenColumns")){
560  this.table.modules.frozenColumns.layoutElement(this.element, this.column);
561  }
562 };
563 
564 Cell.prototype.setWidth = function(){
565  this.width = this.column.width;
566  this.element.style.width = this.column.widthStyled;
567 };
568 
569 Cell.prototype.clearWidth = function(){
570  this.width = "";
571  this.element.style.width = "";
572 };
573 
574 Cell.prototype.getWidth = function(){
575  return this.width || this.element.offsetWidth;
576 };
577 
578 Cell.prototype.setMinWidth = function(){
579  this.minWidth = this.column.minWidth;
580  this.element.style.minWidth = this.column.minWidthStyled;
581 };
582 
583 Cell.prototype.checkHeight = function(){
584  // var height = this.element.css("height");
585  this.row.reinitializeHeight();
586 };
587 
588 Cell.prototype.clearHeight = function(){
589  this.element.style.height = "";
590  this.height = null;
591 };
592 
593 
594 Cell.prototype.setHeight = function(){
595  this.height = this.row.height;
596  this.element.style.height = this.row.heightStyled;
597 };
598 
599 Cell.prototype.getHeight = function(){
600  return this.height || this.element.offsetHeight;
601 };
602 
603 Cell.prototype.show = function(){
604  this.element.style.display = "";
605 };
606 
607 Cell.prototype.hide = function(){
608  this.element.style.display = "none";
609 };
610 
611 Cell.prototype.edit = function(force){
612  if(this.table.modExists("edit", true)){
613  return this.table.modules.edit.editCell(this, force);
614  }
615 };
616 
617 Cell.prototype.cancelEdit = function(){
618  if(this.table.modExists("edit", true)){
619  var editing = this.table.modules.edit.getCurrentCell();
620 
621  if(editing && editing._getSelf() === this){
622  this.table.modules.edit.cancelEdit();
623  }else{
624  console.warn("Cancel Editor Error - This cell is not currently being edited ");
625  }
626  }
627 };
628 
629 
630 
631 Cell.prototype.delete = function(){
632  if(!this.table.rowManager.redrawBlock){
633  this.element.parentNode.removeChild(this.element);
634  }
635  this.element = false;
636  this.column.deleteCell(this);
637  this.row.deleteCell(this);
638  this.calcs = {};
639 };
640 
642 
643 Cell.prototype.nav = function(){
644 
645  var self = this,
646  nextCell = false,
647  index = this.row.getCellIndex(this);
648 
649  return {
650  next:function(){
651  var nextCell = this.right(),
652  nextRow;
653 
654  if(!nextCell){
655  nextRow = self.table.rowManager.nextDisplayRow(self.row, true);
656 
657  if(nextRow){
658  nextCell = nextRow.findNextEditableCell(-1);
659 
660  if(nextCell){
661  nextCell.edit();
662  return true;
663  }
664  }
665  }else{
666  return true;
667  }
668 
669  return false;
670  },
671  prev:function(){
672  var nextCell = this.left(),
673  prevRow;
674 
675  if(!nextCell){
676  prevRow = self.table.rowManager.prevDisplayRow(self.row, true);
677 
678  if(prevRow){
679  nextCell = prevRow.findPrevEditableCell(prevRow.cells.length);
680 
681  if(nextCell){
682  nextCell.edit();
683  return true;
684  }
685  }
686 
687  }else{
688  return true;
689  }
690 
691  return false;
692  },
693  left:function(){
694 
695  nextCell = self.row.findPrevEditableCell(index);
696 
697  if(nextCell){
698  nextCell.edit();
699  return true;
700  }else{
701  return false;
702  }
703  },
704  right:function(){
705  nextCell = self.row.findNextEditableCell(index);
706 
707  if(nextCell){
708  nextCell.edit();
709  return true;
710  }else{
711  return false;
712  }
713  },
714  up:function(){
715  var nextRow = self.table.rowManager.prevDisplayRow(self.row, true);
716 
717  if(nextRow){
718  nextRow.cells[index].edit();
719  }
720  },
721  down:function(){
722  var nextRow = self.table.rowManager.nextDisplayRow(self.row, true);
723 
724  if(nextRow){
725  nextRow.cells[index].edit();
726  }
727  },
728 
729  };
730 
731 };
732 
733 Cell.prototype.getIndex = function(){
734  this.row.getCellIndex(this);
735 };
736 
738 Cell.prototype.getComponent = function(){
739  return new CellComponent(this);
740 };