otsdaq_utilities  v2_05_02_indev
core.js
1 'use strict';
2 
3 /*=include polyfills.js */
4 
5 /*=include column_manager.js */
6 /*=include column.js */
7 /*=include row_manager.js */
8 /*=include row.js */
9 /*=include cell.js */
10 /*=include footer_manager.js */
11 
12 var Tabulator = function(element, options){
13 
14  this.options = {};
15 
16  this.columnManager = null; // hold Column Manager
17  this.rowManager = null; //hold Row Manager
18  this.footerManager = null; //holder Footer Manager
19  this.browser = ""; //hold current browser type
20  this.browserSlow = false; //handle reduced functionality for slower browsers
21  this.browserMobile = false; //check if running on moble, prevent resize cancelling edit on keyboard appearence
22 
23  this.modules = {}; //hold all modules bound to this table
24 
25  this.initializeElement(element);
26  this.initializeOptions(options || {});
27  this._create();
28 
29  Tabulator.prototype.comms.register(this); //register table for inderdevice communication
30 };
31 
32 //default setup options
33 Tabulator.prototype.defaultOptions = {
34 
35  height:false, //height of tabulator
36 
37  layout:"fitData",
38  layoutColumnsOnNewData:false, //update column widths on setData
39 
40  columnMinWidth:40, //minimum global width for a column
41  columnHeaderVertAlign:"top", //vertical alignment of column headers
42  columnVertAlign:false, // DEPRECATED - Left to allow warning
43 
44  resizableColumns:true, //resizable columns
45  resizableRows:false, //resizable rows
46  autoResize:true, //auto resize table
47 
48  columns:[],//store for colum header info
49 
50  data:[], //default starting data
51 
52  autoColumns:false, //build columns from data row structure
53 
54  reactiveData:false, //enable data reactivity
55 
56  nestedFieldSeparator:".", //seperatpr for nested data
57 
58  tooltips: false, //Tool tip value
59  tooltipsHeader: false, //Tool tip for headers
60  tooltipGenerationMode:"load", //when to generate tooltips
61 
62  initialSort:false, //initial sorting criteria
63  initialFilter:false, //initial filtering criteria
64  initialHeaderFilter:false, //initial header filtering criteria
65 
66  columnHeaderSortMulti: true, //multiple or single column sorting
67 
68  sortOrderReverse:false, //reverse internal sort ordering
69 
70  headerSort:true, //set default global header sort
71  headerSortTristate:false, //set default tristate header sorting
72 
73  footerElement:false, //hold footer element
74 
75  index:"id", //filed for row index
76 
77  keybindings:[], //array for keybindings
78 
79  tabEndNewRow:false, //create new row when tab to end of table
80 
81  invalidOptionWarnings:true, //allow toggling of invalid option warnings
82 
83  clipboard:false, //enable clipboard
84  clipboardCopyStyled:true, //formatted table data
85  clipboardCopySelector:"active", //method of chosing which data is coppied to the clipboard
86  clipboardCopyFormatter:"table", //convert data to a clipboard string
87  clipboardPasteParser:"table", //convert pasted clipboard data to rows
88  clipboardPasteAction:"insert", //how to insert pasted data into the table
89  clipboardCopyConfig:false, //clipboard config
90 
91  clipboardCopied:function(){}, //data has been copied to the clipboard
92  clipboardPasted:function(){}, //data has been pasted into the table
93  clipboardPasteError:function(){}, //data has not successfully been pasted into the table
94 
95  downloadDataFormatter:false, //function to manipulate table data before it is downloaded
96  downloadReady:function(data, blob){return blob;}, //function to manipulate download data
97  downloadComplete:false, //function to manipulate download data
98  downloadConfig:false, //download config
99 
100  dataTree:false, //enable data tree
101  dataTreeElementColumn:false,
102  dataTreeBranchElement: true, //show data tree branch element
103  dataTreeChildIndent:9, //data tree child indent in px
104  dataTreeChildField:"_children", //data tre column field to look for child rows
105  dataTreeCollapseElement:false, //data tree row collapse element
106  dataTreeExpandElement:false, //data tree row expand element
107  dataTreeStartExpanded:false,
108  dataTreeRowExpanded:function(){}, //row has been expanded
109  dataTreeRowCollapsed:function(){}, //row has been collapsed
110 
111  printAsHtml:false, //enable print as html
112  printFormatter:false, //printing page formatter
113  printHeader:false, //page header contents
114  printFooter:false, //page footer contents
115  printCopyStyle:true, //enable print as html styling
116  printVisibleRows:true, //restrict print to visible rows only
117  printConfig:{}, //print config options
118 
119  addRowPos:"bottom", //position to insert blank rows, top|bottom
120 
121  selectable:"highlight", //highlight rows on hover
122  selectableRangeMode: "drag", //highlight rows on hover
123  selectableRollingSelection:true, //roll selection once maximum number of selectable rows is reached
124  selectablePersistence:true, // maintain selection when table view is updated
125  selectableCheck:function(data, row){return true;}, //check wheather row is selectable
126 
127  headerFilterLiveFilterDelay: 300, //delay before updating column after user types in header filter
128  headerFilterPlaceholder: false, //placeholder text to display in header filters
129 
130  headerVisible:true, //hide header
131 
132  history:false, //enable edit history
133 
134  locale:false, //current system language
135  langs:{},
136 
137  virtualDom:true, //enable DOM virtualization
138  virtualDomBuffer:0, // set virtual DOM buffer size
139 
140  persistentLayout:false, //DEPRICATED - REMOVE in 5.0
141  persistentSort:false, //DEPRICATED - REMOVE in 5.0
142  persistentFilter:false, //DEPRICATED - REMOVE in 5.0
143  persistenceID:"", //key for persistent storage
144  persistenceMode:true, //mode for storing persistence information
145  persistenceReaderFunc:false, //function for handling persistence data reading
146  persistenceWriterFunc:false, //function for handling persistence data writing
147 
148  persistence:false,
149 
150  responsiveLayout:false, //responsive layout flags
151  responsiveLayoutCollapseStartOpen:true, //start showing collapsed data
152  responsiveLayoutCollapseUseFormatters:true, //responsive layout collapse formatter
153  responsiveLayoutCollapseFormatter:false, //responsive layout collapse formatter
154 
155  pagination:false, //set pagination type
156  paginationSize:false, //set number of rows to a page
157  paginationInitialPage:1, //initail page to show on load
158  paginationButtonCount: 5, // set count of page button
159  paginationSizeSelector:false, //add pagination size selector element
160  paginationElement:false, //element to hold pagination numbers
161  paginationDataSent:{}, //pagination data sent to the server
162  paginationDataReceived:{}, //pagination data received from the server
163  paginationAddRow: "page", //add rows on table or page
164 
165  ajaxURL:false, //url for ajax loading
166  ajaxURLGenerator:false,
167  ajaxParams:{}, //params for ajax loading
168  ajaxConfig:"get", //ajax request type
169  ajaxContentType:"form", //ajax request type
170  ajaxRequestFunc:false, //promise function
171  ajaxLoader:true, //show loader
172  ajaxLoaderLoading:false, //loader element
173  ajaxLoaderError:false, //loader element
174  ajaxFiltering:false,
175  ajaxSorting:false,
176  ajaxProgressiveLoad:false, //progressive loading
177  ajaxProgressiveLoadDelay:0, //delay between requests
178  ajaxProgressiveLoadScrollMargin:0, //margin before scroll begins
179 
180  groupBy:false, //enable table grouping and set field to group by
181  groupStartOpen:true, //starting state of group
182  groupValues:false,
183 
184  groupHeader:false, //header generation function
185 
186  htmlOutputConfig:false, //html outypu config
187 
188  movableColumns:false, //enable movable columns
189 
190  movableRows:false, //enable movable rows
191  movableRowsConnectedTables:false, //tables for movable rows to be connected to
192  movableRowsSender:false,
193  movableRowsReceiver:"insert",
194  movableRowsSendingStart:function(){},
195  movableRowsSent:function(){},
196  movableRowsSentFailed:function(){},
197  movableRowsSendingStop:function(){},
198  movableRowsReceivingStart:function(){},
199  movableRowsReceived:function(){},
200  movableRowsReceivedFailed:function(){},
201  movableRowsReceivingStop:function(){},
202 
203  scrollToRowPosition:"top",
204  scrollToRowIfVisible:true,
205 
206  scrollToColumnPosition:"left",
207  scrollToColumnIfVisible:true,
208 
209  rowFormatter:false,
210 
211  placeholder:false,
212 
213  //table building callbacks
214  tableBuilding:function(){},
215  tableBuilt:function(){},
216 
217  //render callbacks
218  renderStarted:function(){},
219  renderComplete:function(){},
220 
221  //row callbacks
222  rowClick:false,
223  rowDblClick:false,
224  rowContext:false,
225  rowTap:false,
226  rowDblTap:false,
227  rowTapHold:false,
228  rowMouseEnter:false,
229  rowMouseLeave:false,
230  rowMouseOver:false,
231  rowMouseOut:false,
232  rowMouseMove:false,
233  rowAdded:function(){},
234  rowDeleted:function(){},
235  rowMoved:function(){},
236  rowUpdated:function(){},
237  rowSelectionChanged:function(){},
238  rowSelected:function(){},
239  rowDeselected:function(){},
240  rowResized:function(){},
241 
242  //cell callbacks
243  //row callbacks
244  cellClick:false,
245  cellDblClick:false,
246  cellContext:false,
247  cellTap:false,
248  cellDblTap:false,
249  cellTapHold:false,
250  cellMouseEnter:false,
251  cellMouseLeave:false,
252  cellMouseOver:false,
253  cellMouseOut:false,
254  cellMouseMove:false,
255  cellEditing:function(){},
256  cellEdited:function(){},
257  cellEditCancelled:function(){},
258 
259  //column callbacks
260  columnMoved:false,
261  columnResized:function(){},
262  columnTitleChanged:function(){},
263  columnVisibilityChanged:function(){},
264 
265  //HTML iport callbacks
266  htmlImporting:function(){},
267  htmlImported:function(){},
268 
269  //data callbacks
270  dataLoading:function(){},
271  dataLoaded:function(){},
272  dataEdited:function(){},
273 
274  //ajax callbacks
275  ajaxRequesting:function(){},
276  ajaxResponse:false,
277  ajaxError:function(){},
278 
279  //filtering callbacks
280  dataFiltering:false,
281  dataFiltered:false,
282 
283  //sorting callbacks
284  dataSorting:function(){},
285  dataSorted:function(){},
286 
287  //grouping callbacks
288  groupToggleElement:"arrow",
289  groupClosedShowCalcs:false,
290  dataGrouping:function(){},
291  dataGrouped:false,
292  groupVisibilityChanged:function(){},
293  groupClick:false,
294  groupDblClick:false,
295  groupContext:false,
296  groupTap:false,
297  groupDblTap:false,
298  groupTapHold:false,
299 
300  columnCalcs:true,
301 
302  //pagination callbacks
303  pageLoaded:function(){},
304 
305  //localization callbacks
306  localized:function(){},
307 
308  //validation has failed
309  validationFailed:function(){},
310 
311  //history callbacks
312  historyUndo:function(){},
313  historyRedo:function(){},
314 
315  //scroll callbacks
316  scrollHorizontal:function(){},
317  scrollVertical:function(){},
318 
319 };
320 
321 Tabulator.prototype.initializeOptions = function(options){
322 
323  //warn user if option is not available
324  if(options.invalidOptionWarnings !== false){
325  for (var key in options){
326  if(typeof this.defaultOptions[key] === "undefined"){
327  console.warn("Invalid table constructor option:", key)
328  }
329  }
330  }
331 
332  //assign options to table
333  for (var key in this.defaultOptions){
334  if(key in options){
335  this.options[key] = options[key];
336  }else{
337  if(Array.isArray(this.defaultOptions[key])){
338  this.options[key] = [];
339  }else if(typeof this.defaultOptions[key] === "object"){
340  this.options[key] = {};
341  }else{
342  this.options[key] = this.defaultOptions[key];
343  }
344  }
345  }
346 };
347 
348 Tabulator.prototype.initializeElement = function(element){
349 
350  if(typeof HTMLElement !== "undefined" && element instanceof HTMLElement){
351  this.element = element;
352  return true;
353  }else if(typeof element === "string"){
354  this.element = document.querySelector(element);
355 
356  if(this.element){
357  return true;
358  }else{
359  console.error("Tabulator Creation Error - no element found matching selector: ", element);
360  return false;
361  }
362  }else{
363  console.error("Tabulator Creation Error - Invalid element provided:", element);
364  return false;
365  }
366 
367 };
368 
369 
370 //convert depricated functionality to new functions
371 Tabulator.prototype._mapDepricatedFunctionality = function(){
372 
373  //map depricated persistance setup options
374  if(this.options.persistentLayout || this.options.persistentSort || this.options.persistentFilter){
375  if(!this.options.persistence){
376  this.options.persistence = {};
377  }
378  }
379 
380  if(this.options.persistentLayout){
381  console.warn("persistentLayout option is deprecated, you should now use the persistence option");
382 
383  if(this.options.persistence !== true && typeof this.options.persistence.columns === "undefined"){
384  this.options.persistence.columns = true;
385  }
386  }
387 
388  if(this.options.persistentSort){
389  console.warn("persistentSort option is deprecated, you should now use the persistence option");
390 
391  if(this.options.persistence !== true && typeof this.options.persistence.sort === "undefined"){
392  this.options.persistence.sort = true;
393  }
394  }
395 
396  if(this.options.persistentFilter){
397  console.warn("persistentFilter option is deprecated, you should now use the persistence option");
398 
399  if(this.options.persistence !== true && typeof this.options.persistence.filter === "undefined"){
400  this.options.persistence.filter = true;
401  }
402  }
403 
404  if(this.options.columnVertAlign){
405  console.warn("columnVertAlign option is deprecated, you should now use the columnHeaderVertAlign option");
406 
407  this.options.columnHeaderVertAlign = this.options.columnVertAlign;
408  }
409 };
410 
411 Tabulator.prototype._clearSelection = function(){
412 
413  this.element.classList.add("tabulator-block-select");
414 
415  if (window.getSelection) {
416  if (window.getSelection().empty) { // Chrome
417  window.getSelection().empty();
418  } else if (window.getSelection().removeAllRanges) { // Firefox
419  window.getSelection().removeAllRanges();
420  }
421  } else if (document.selection) { // IE?
422  document.selection.empty();
423  }
424 
425  this.element.classList.remove("tabulator-block-select");
426 };
427 
428 
429 //concreate table
430 Tabulator.prototype._create = function(){
431  this._clearObjectPointers();
432 
433  this._mapDepricatedFunctionality();
434 
435  this.bindModules();
436 
437  if(this.element.tagName === "TABLE"){
438  if(this.modExists("htmlTableImport", true)){
439  this.modules.htmlTableImport.parseTable();
440  }
441  }
442 
443  this.columnManager = new ColumnManager(this);
444  this.rowManager = new RowManager(this);
445  this.footerManager = new FooterManager(this);
446 
447  this.columnManager.setRowManager(this.rowManager);
448  this.rowManager.setColumnManager(this.columnManager);
449 
450  this._buildElement();
451 
452  this._loadInitialData();
453 };
454 
455 //clear pointers to objects in default config object
456 Tabulator.prototype._clearObjectPointers = function(){
457  this.options.columns = this.options.columns.slice(0);
458 
459  if(!this.options.reactiveData){
460  this.options.data = this.options.data.slice(0);
461  }
462 };
463 
464 
465 //build tabulator element
466 Tabulator.prototype._buildElement = function(){
467  var element = this.element,
468  mod = this.modules,
469  options = this.options;
470 
471  options.tableBuilding.call(this);
472 
473  element.classList.add("tabulator");
474  element.setAttribute("role", "grid");
475 
476  //empty element
477  while(element.firstChild) element.removeChild(element.firstChild);
478 
479  //set table height
480  if(options.height){
481  options.height = isNaN(options.height) ? options.height : options.height + "px";
482  element.style.height = options.height;
483  }
484 
485  this.columnManager.initialize();
486  this.rowManager.initialize();
487 
488  this._detectBrowser();
489 
490  if(this.modExists("layout", true)){
491  mod.layout.initialize(options.layout);
492  }
493 
494  //set localization
495  if(options.headerFilterPlaceholder !== false){
496  mod.localize.setHeaderFilterPlaceholder(options.headerFilterPlaceholder);
497  }
498 
499  for(let locale in options.langs){
500  mod.localize.installLang(locale, options.langs[locale]);
501  }
502 
503  mod.localize.setLocale(options.locale);
504 
505  //configure placeholder element
506  if(typeof options.placeholder == "string"){
507 
508  var el = document.createElement("div");
509  el.classList.add("tabulator-placeholder");
510 
511  var span = document.createElement("span");
512  span.innerHTML = options.placeholder;
513 
514  el.appendChild(span);
515 
516  options.placeholder = el;
517  }
518 
519  //build table elements
520  element.appendChild(this.columnManager.getElement());
521  element.appendChild(this.rowManager.getElement());
522 
523 
524  if(options.footerElement){
525  this.footerManager.activate();
526  }
527 
528  if(options.persistence && this.modExists("persistence", true)){
529  mod.persistence.initialize();
530  }
531 
532  if(options.persistence && this.modExists("persistence", true) && mod.persistence.config.columns){
533  options.columns = mod.persistence.load("columns", options.columns) ;
534  }
535 
536  if(options.movableRows && this.modExists("moveRow")){
537  mod.moveRow.initialize();
538  }
539 
540  if(options.autoColumns && this.options.data){
541  this.columnManager.generateColumnsFromRowData(this.options.data);
542  }
543 
544  if(this.modExists("columnCalcs")){
545  mod.columnCalcs.initialize();
546  }
547 
548  this.columnManager.setColumns(options.columns);
549 
550  if(options.dataTree && this.modExists("dataTree", true)){
551  mod.dataTree.initialize();
552  }
553 
554  if(this.modExists("frozenRows")){
555  this.modules.frozenRows.initialize();
556  }
557 
558  if(((options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort) || options.initialSort) && this.modExists("sort", true)){
559  var sorters = [];
560 
561  if(options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort){
562  sorters = mod.persistence.load("sort");
563 
564  if(sorters === false && options.initialSort){
565  sorters = options.initialSort;
566  }
567  }else if(options.initialSort){
568  sorters = options.initialSort;
569  }
570 
571  mod.sort.setSort(sorters);
572  }
573 
574  if(((options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter) || options.initialFilter) && this.modExists("filter", true)){
575  var filters = [];
576 
577 
578  if(options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter){
579  filters = mod.persistence.load("filter");
580 
581  if(filters === false && options.initialFilter){
582  filters = options.initialFilter;
583  }
584  }else if(options.initialFilter){
585  filters = options.initialFilter;
586  }
587 
588  mod.filter.setFilter(filters);
589  }
590 
591  if(options.initialHeaderFilter && this.modExists("filter", true)){
592  options.initialHeaderFilter.forEach((item) => {
593 
594  var column = this.columnManager.findColumn(item.field);
595 
596  if(column){
597  mod.filter.setHeaderFilterValue(column, item.value);
598  }else{
599  console.warn("Column Filter Error - No matching column found:", item.field);
600  return false;
601  }
602  });
603  }
604 
605 
606  if(this.modExists("ajax")){
607  mod.ajax.initialize();
608  }
609 
610  if(options.pagination && this.modExists("page", true)){
611  mod.page.initialize();
612  }
613 
614  if(options.groupBy && this.modExists("groupRows", true)){
615  mod.groupRows.initialize();
616  }
617 
618  if(this.modExists("keybindings")){
619  mod.keybindings.initialize();
620  }
621 
622  if(this.modExists("selectRow")){
623  mod.selectRow.clearSelectionData(true);
624  }
625 
626  if(options.autoResize && this.modExists("resizeTable")){
627  mod.resizeTable.initialize();
628  }
629 
630  if(this.modExists("clipboard")){
631  mod.clipboard.initialize();
632  }
633 
634  if(options.printAsHtml && this.modExists("print")){
635  mod.print.initialize();
636  }
637 
638  options.tableBuilt.call(this);
639 };
640 
641 Tabulator.prototype._loadInitialData = function(){
642  var self = this;
643 
644  if(self.options.pagination && self.modExists("page")){
645  self.modules.page.reset(true);
646 
647  if(self.options.pagination == "local"){
648  if(self.options.data.length){
649  self.rowManager.setData(self.options.data);
650  }else{
651  if((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")){
652  self.modules.ajax.loadData().then(()=>{}).catch(()=>{
653  if(self.options.paginationInitialPage){
654  self.modules.page.setPage(self.options.paginationInitialPage);
655  }
656  });
657 
658  return;
659  }else{
660  self.rowManager.setData(self.options.data);
661  }
662  }
663 
664  if(self.options.paginationInitialPage){
665  self.modules.page.setPage(self.options.paginationInitialPage);
666  }
667  }else{
668  if(self.options.ajaxURL){
669  self.modules.page.setPage(self.options.paginationInitialPage).then(()=>{}).catch(()=>{});
670  }else{
671  self.rowManager.setData([]);
672  }
673  }
674  }else{
675  if(self.options.data.length){
676  self.rowManager.setData(self.options.data);
677  }else{
678  if((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")){
679  self.modules.ajax.loadData().then(()=>{}).catch(()=>{});
680  }else{
681  self.rowManager.setData(self.options.data);
682  }
683  }
684  }
685 };
686 
687 //deconstructor
688 Tabulator.prototype.destroy = function(){
689  var element = this.element;
690 
691  Tabulator.prototype.comms.deregister(this); //deregister table from inderdevice communication
692 
693  if(this.options.reactiveData && this.modExists("reactiveData", true)){
694  this.modules.reactiveData.unwatchData();
695  }
696 
697  //clear row data
698  this.rowManager.rows.forEach(function(row){
699  row.wipe();
700  });
701 
702  this.rowManager.rows = [];
703  this.rowManager.activeRows = [];
704  this.rowManager.displayRows = [];
705 
706  //clear event bindings
707  if(this.options.autoResize && this.modExists("resizeTable")){
708  this.modules.resizeTable.clearBindings();
709  }
710 
711  if(this.modExists("keybindings")){
712  this.modules.keybindings.clearBindings();
713  }
714 
715  //clear DOM
716  while(element.firstChild) element.removeChild(element.firstChild);
717  element.classList.remove("tabulator");
718 };
719 
720 Tabulator.prototype._detectBrowser = function(){
721  var ua = navigator.userAgent||navigator.vendor||window.opera;
722 
723  if(ua.indexOf("Trident") > -1){
724  this.browser = "ie";
725  this.browserSlow = true;
726  }else if(ua.indexOf("Edge") > -1){
727  this.browser = "edge";
728  this.browserSlow = true;
729  }else if(ua.indexOf("Firefox") > -1){
730  this.browser = "firefox";
731  this.browserSlow = false;
732  }else{
733  this.browser = "other";
734  this.browserSlow = false;
735  }
736 
737  this.browserMobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(ua)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(ua.substr(0,4));
738 };
739 
741 
742 //block table redrawing
743 Tabulator.prototype.blockRedraw = function(){
744  return this.rowManager.blockRedraw();
745 };
746 
747 //restore table redrawing
748 Tabulator.prototype.restoreRedraw = function(){
749  return this.rowManager.restoreRedraw();
750 };
751 
752 
753 //local data from local file
754 Tabulator.prototype.setDataFromLocalFile = function(extensions){
755 
756  return new Promise((resolve, reject) => {
757  var input = document.createElement("input");
758  input.type = "file";
759  input.accept = extensions || ".json,application/json";
760 
761  input.addEventListener("change", (e) => {
762  var file = input.files[0],
763  reader = new FileReader(),
764  data;
765 
766  reader.readAsText(file);
767 
768  reader.onload = (e) => {
769 
770  try {
771  data = JSON.parse(reader.result);
772  } catch(e) {
773  console.warn("File Load Error - File contents is invalid JSON", e);
774  reject(e);
775  return;
776  }
777 
778  this._setData(data)
779  .then((data) => {
780  resolve(data);
781  })
782  .catch((err) => {
783  resolve(err);
784  });
785  };
786 
787  reader.onerror = (e) => {
788  console.warn("File Load Error - Unable to read file");
789  reject();
790  };
791  });
792 
793  input.click();
794  });
795 };
796 
797 
798 //load data
799 Tabulator.prototype.setData = function(data, params, config){
800  if(this.modExists("ajax")){
801  this.modules.ajax.blockActiveRequest();
802  }
803 
804  return this._setData(data, params, config);
805 };
806 
807 Tabulator.prototype._setData = function(data, params, config, inPosition){
808  var self = this;
809 
810  if(typeof(data) === "string"){
811  if (data.indexOf("{") == 0 || data.indexOf("[") == 0){
812  //data is a json encoded string
813  return self.rowManager.setData(JSON.parse(data), inPosition);
814  }else{
815 
816  if(self.modExists("ajax", true)){
817  if(params){
818  self.modules.ajax.setParams(params);
819  }
820 
821  if(config){
822  self.modules.ajax.setConfig(config);
823  }
824 
825  self.modules.ajax.setUrl(data);
826 
827  if(self.options.pagination == "remote" && self.modExists("page", true)){
828  self.modules.page.reset(true);
829  return self.modules.page.setPage(1);
830  }else{
831  //assume data is url, make ajax call to url to get data
832  return self.modules.ajax.loadData(inPosition);
833  }
834  }
835  }
836  }else{
837  if(data){
838  //asume data is already an object
839  return self.rowManager.setData(data, inPosition);
840  }else{
841 
842  //no data provided, check if ajaxURL is present;
843  if(self.modExists("ajax") && (self.modules.ajax.getUrl || self.options.ajaxURLGenerator)){
844 
845  if(self.options.pagination == "remote" && self.modExists("page", true)){
846  self.modules.page.reset(true);
847  return self.modules.page.setPage(1);
848  }else{
849  return self.modules.ajax.loadData(inPosition);
850  }
851 
852  }else{
853  //empty data
854  return self.rowManager.setData([], inPosition);
855  }
856  }
857  }
858 };
859 
860 //clear data
861 Tabulator.prototype.clearData = function(){
862  if(this.modExists("ajax")){
863  this.modules.ajax.blockActiveRequest();
864  }
865 
866  this.rowManager.clearData();
867 };
868 
869 //get table data array
870 Tabulator.prototype.getData = function(active){
871 
872  if(active === true){
873  console.warn("passing a boolean to the getData function is deprecated, you should now pass the string 'active'");
874  active = "active";
875  }
876 
877  return this.rowManager.getData(active);
878 };
879 
880 //get table data array count
881 Tabulator.prototype.getDataCount = function(active){
882 
883  if(active === true){
884  console.warn("passing a boolean to the getDataCount function is deprecated, you should now pass the string 'active'");
885  active = "active";
886  }
887 
888  return this.rowManager.getDataCount(active);
889 };
890 
891 //search for specific row components
892 Tabulator.prototype.searchRows = function(field, type, value){
893  if(this.modExists("filter", true)){
894  return this.modules.filter.search("rows", field, type, value);
895  }
896 };
897 
898 //search for specific data
899 Tabulator.prototype.searchData = function(field, type, value){
900  if(this.modExists("filter", true)){
901  return this.modules.filter.search("data", field, type, value);
902  }
903 };
904 
905 //get table html
906 Tabulator.prototype.getHtml = function(visible, style, config){
907  if(this.modExists("htmlTableExport", true)){
908  return this.modules.htmlTableExport.getHtml(visible, style, config);
909  }
910 };
911 
912 //get print html
913 Tabulator.prototype.print = function(visible, style, config){
914  if(this.modExists("print", true)){
915  return this.modules.print.printFullscreen(visible, style, config);
916  }
917 };
918 
919 //retrieve Ajax URL
920 Tabulator.prototype.getAjaxUrl = function(){
921  if(this.modExists("ajax", true)){
922  return this.modules.ajax.getUrl();
923  }
924 };
925 
926 //replace data, keeping table in position with same sort
927 Tabulator.prototype.replaceData = function(data, params, config){
928  if(this.modExists("ajax")){
929  this.modules.ajax.blockActiveRequest();
930  }
931 
932  return this._setData(data, params, config, true);
933 };
934 
935 
936 //update table data
937 Tabulator.prototype.updateData = function(data){
938  var self = this;
939  var responses = 0;
940 
941  return new Promise((resolve, reject) => {
942  if(this.modExists("ajax")){
943  this.modules.ajax.blockActiveRequest();
944  }
945 
946  if(typeof data === "string"){
947  data = JSON.parse(data);
948  }
949 
950  if(data){
951  data.forEach(function(item){
952  var row = self.rowManager.findRow(item[self.options.index]);
953 
954  if(row){
955  responses++;
956 
957  row.updateData(item)
958  .then(()=>{
959  responses--;
960 
961  if(!responses){
962  resolve();
963  }
964  });
965  }
966  });
967  }else{
968  console.warn("Update Error - No data provided");
969  reject("Update Error - No data provided");
970  }
971  });
972 
973 };
974 
975 Tabulator.prototype.addData = function(data, pos, index){
976  return new Promise((resolve, reject) => {
977  if(this.modExists("ajax")){
978  this.modules.ajax.blockActiveRequest();
979  }
980 
981  if(typeof data === "string"){
982  data = JSON.parse(data);
983  }
984 
985  if(data){
986  this.rowManager.addRows(data, pos, index)
987  .then((rows) => {
988  var output = [];
989 
990  rows.forEach(function(row){
991  output.push(row.getComponent());
992  });
993 
994  resolve(output);
995  });
996  }else{
997  console.warn("Update Error - No data provided");
998  reject("Update Error - No data provided");
999  }
1000  });
1001 };
1002 
1003 //update table data
1004 Tabulator.prototype.updateOrAddData = function(data){
1005  var self = this,
1006  rows = [],
1007  responses = 0;
1008 
1009  return new Promise((resolve, reject) => {
1010  if(this.modExists("ajax")){
1011  this.modules.ajax.blockActiveRequest();
1012  }
1013 
1014  if(typeof data === "string"){
1015  data = JSON.parse(data);
1016  }
1017 
1018  if(data){
1019  data.forEach(function(item){
1020  var row = self.rowManager.findRow(item[self.options.index]);
1021 
1022  responses++;
1023 
1024  if(row){
1025  row.updateData(item)
1026  .then(()=>{
1027  responses--;
1028  rows.push(row.getComponent());
1029 
1030  if(!responses){
1031  resolve(rows);
1032  }
1033  });
1034  }else{
1035  self.rowManager.addRows(item)
1036  .then((newRows)=>{
1037  responses--;
1038  rows.push(newRows[0].getComponent());
1039 
1040  if(!responses){
1041  resolve(rows);
1042  }
1043  });
1044  }
1045  });
1046  }else{
1047  console.warn("Update Error - No data provided");
1048  reject("Update Error - No data provided");
1049  }
1050  });
1051 };
1052 
1053 //get row object
1054 Tabulator.prototype.getRow = function(index){
1055  var row = this.rowManager.findRow(index);
1056 
1057  if(row){
1058  return row.getComponent();
1059  }else{
1060  console.warn("Find Error - No matching row found:", index);
1061  return false;
1062  }
1063 };
1064 
1065 //get row object
1066 Tabulator.prototype.getRowFromPosition = function(position, active){
1067  var row = this.rowManager.getRowFromPosition(position, active);
1068 
1069  if(row){
1070  return row.getComponent();
1071  }else{
1072  console.warn("Find Error - No matching row found:", position);
1073  return false;
1074  }
1075 };
1076 
1077 //delete row from table
1078 Tabulator.prototype.deleteRow = function(index){
1079  return new Promise((resolve, reject) => {
1080  var count = 0,
1081  successCount = 0,
1082  self = this;
1083 
1084  function doneCheck(){
1085  count++;
1086 
1087  if(count == index.length){
1088  if(successCount){
1089  self.rowManager.reRenderInPosition();
1090  resolve();
1091  }
1092  }
1093  }
1094 
1095  if(!Array.isArray(index)){
1096  index = [index];
1097  }
1098 
1099  index.forEach((item) =>{
1100  var row = this.rowManager.findRow(item, true);
1101 
1102  if(row){
1103  row.delete()
1104  .then(() => {
1105  successCount++;
1106  doneCheck();
1107  })
1108  .catch((err) => {
1109  doneCheck();
1110  reject(err);
1111  });
1112 
1113  }else{
1114  console.warn("Delete Error - No matching row found:", item);
1115  reject("Delete Error - No matching row found")
1116  doneCheck();
1117  }
1118  });
1119  });
1120 };
1121 
1122 //add row to table
1123 Tabulator.prototype.addRow = function(data, pos, index){
1124  return new Promise((resolve, reject) => {
1125  if(typeof data === "string"){
1126  data = JSON.parse(data);
1127  }
1128 
1129  this.rowManager.addRows(data, pos, index)
1130  .then((rows)=>{
1131  //recalc column calculations if present
1132  if(this.modExists("columnCalcs")){
1133  this.modules.columnCalcs.recalc(this.rowManager.activeRows);
1134  }
1135 
1136  resolve(rows[0].getComponent());
1137  });
1138  });
1139 };
1140 
1141 //update a row if it exitsts otherwise create it
1142 Tabulator.prototype.updateOrAddRow = function(index, data){
1143  return new Promise((resolve, reject) => {
1144  var row = this.rowManager.findRow(index);
1145 
1146  if(typeof data === "string"){
1147  data = JSON.parse(data);
1148  }
1149 
1150  if(row){
1151  row.updateData(data)
1152  .then(()=>{
1153  //recalc column calculations if present
1154  if(this.modExists("columnCalcs")){
1155  this.modules.columnCalcs.recalc(this.rowManager.activeRows);
1156  }
1157 
1158  resolve(row.getComponent());
1159  })
1160  .catch((err)=>{
1161  reject(err);
1162  });
1163  }else{
1164  row = this.rowManager.addRows(data)
1165  .then((rows)=>{
1166  //recalc column calculations if present
1167  if(this.modExists("columnCalcs")){
1168  this.modules.columnCalcs.recalc(this.rowManager.activeRows);
1169  }
1170 
1171  resolve(rows[0].getComponent());
1172  })
1173  .catch((err)=>{
1174  reject(err);
1175  });
1176  }
1177  });
1178 };
1179 
1180 //update row data
1181 Tabulator.prototype.updateRow = function(index, data){
1182  return new Promise((resolve, reject) => {
1183  var row = this.rowManager.findRow(index);
1184 
1185  if(typeof data === "string"){
1186  data = JSON.parse(data);
1187  }
1188 
1189  if(row){
1190  row.updateData(data).then(()=>{
1191  resolve(row.getComponent());
1192  })
1193  .catch((err)=>{
1194  reject(err);
1195  });
1196  }else{
1197  console.warn("Update Error - No matching row found:", index);
1198  reject("Update Error - No matching row found");
1199  }
1200  });
1201 };
1202 
1203 //scroll to row in DOM
1204 Tabulator.prototype.scrollToRow = function(index, position, ifVisible){
1205  return new Promise((resolve, reject) => {
1206  var row = this.rowManager.findRow(index);
1207 
1208  if(row){
1209  this.rowManager.scrollToRow(row, position, ifVisible)
1210  .then(()=>{
1211  resolve();
1212  })
1213  .catch((err)=>{
1214  reject(err);
1215  });
1216  }else{
1217  console.warn("Scroll Error - No matching row found:", index);
1218  reject("Scroll Error - No matching row found");
1219  }
1220  });
1221 };
1222 
1223 Tabulator.prototype.moveRow = function(from, to, after){
1224  var fromRow = this.rowManager.findRow(from);
1225 
1226  if(fromRow){
1227  fromRow.moveToRow(to, after);
1228  }else{
1229  console.warn("Move Error - No matching row found:", from);
1230  }
1231 };
1232 
1233 Tabulator.prototype.getRows = function(active){
1234 
1235  if(active === true){
1236  console.warn("passing a boolean to the getRows function is deprecated, you should now pass the string 'active'");
1237  active = "active";
1238  }
1239 
1240  return this.rowManager.getComponents(active);
1241 };
1242 
1243 //get position of row in table
1244 Tabulator.prototype.getRowPosition = function(index, active){
1245  var row = this.rowManager.findRow(index);
1246 
1247  if(row){
1248  return this.rowManager.getRowPosition(row, active);
1249  }else{
1250  console.warn("Position Error - No matching row found:", index);
1251  return false;
1252  }
1253 };
1254 
1255 //copy table data to clipboard
1256 Tabulator.prototype.copyToClipboard = function(selector, selectorParams, formatter, formatterParams){
1257  if(this.modExists("clipboard", true)){
1258  this.modules.clipboard.copy(selector, selectorParams, formatter, formatterParams);
1259  }
1260 };
1261 
1263 
1264 Tabulator.prototype.setColumns = function(definition){
1265  this.columnManager.setColumns(definition);
1266 };
1267 
1268 Tabulator.prototype.getColumns = function(structured){
1269  return this.columnManager.getComponents(structured);
1270 };
1271 
1272 Tabulator.prototype.getColumn = function(field){
1273  var col = this.columnManager.findColumn(field);
1274 
1275  if(col){
1276  return col.getComponent();
1277  }else{
1278  console.warn("Find Error - No matching column found:", field);
1279  return false;
1280  }
1281 };
1282 
1283 Tabulator.prototype.getColumnDefinitions = function(){
1284  return this.columnManager.getDefinitionTree();
1285 };
1286 
1287 Tabulator.prototype.getColumnLayout = function(){
1288  if(this.modExists("persistence", true)){
1289  return this.modules.persistence.parseColumns(this.columnManager.getColumns());
1290  }
1291 };
1292 
1293 Tabulator.prototype.setColumnLayout = function(layout){
1294  if(this.modExists("persistence", true)){
1295  this.columnManager.setColumns(this.modules.persistence.mergeDefinition(this.options.columns, layout))
1296  return true;
1297  }
1298  return false;
1299 };
1300 
1301 Tabulator.prototype.showColumn = function(field){
1302  var column = this.columnManager.findColumn(field);
1303 
1304  if(column){
1305  column.show();
1306 
1307  if(this.options.responsiveLayout && this.modExists("responsiveLayout", true)){
1308  this.modules.responsiveLayout.update();
1309  }
1310  }else{
1311  console.warn("Column Show Error - No matching column found:", field);
1312  return false;
1313  }
1314 };
1315 
1316 Tabulator.prototype.hideColumn = function(field){
1317  var column = this.columnManager.findColumn(field);
1318 
1319  if(column){
1320  column.hide();
1321 
1322  if(this.options.responsiveLayout && this.modExists("responsiveLayout", true)){
1323  this.modules.responsiveLayout.update();
1324  }
1325  }else{
1326  console.warn("Column Hide Error - No matching column found:", field);
1327  return false;
1328  }
1329 };
1330 
1331 
1332 Tabulator.prototype.toggleColumn = function(field){
1333  var column = this.columnManager.findColumn(field);
1334 
1335  if(column){
1336  if(column.visible){
1337  column.hide();
1338  }else{
1339  column.show();
1340  }
1341  }else{
1342  console.warn("Column Visibility Toggle Error - No matching column found:", field);
1343  return false;
1344  }
1345 };
1346 
1347 Tabulator.prototype.addColumn = function(definition, before, field){
1348  return new Promise((resolve, reject) => {
1349  var column = this.columnManager.findColumn(field);
1350 
1351  this.columnManager.addColumn(definition, before, column)
1352  .then((column) => {
1353  resolve(column.getComponent());
1354  }).catch((err) => {
1355  reject(err);
1356  });
1357  });
1358 };
1359 
1360 Tabulator.prototype.deleteColumn = function(field){
1361  return new Promise((resolve, reject) => {
1362  var column = this.columnManager.findColumn(field);
1363 
1364  if(column){
1365  column.delete()
1366  .then(() => {
1367  resolve();
1368  }).catch((err) => {
1369  reject(err);
1370  });
1371  }else{
1372  console.warn("Column Delete Error - No matching column found:", field);
1373  reject();
1374  }
1375  });
1376 };
1377 
1378 Tabulator.prototype.updateColumnDefinition = function(field, definition){
1379  return new Promise((resolve, reject) => {
1380  var column = this.columnManager.findColumn(field);
1381 
1382  if(column){
1383  column.updateDefinition()
1384  .then((col) => {
1385  resolve(col);
1386  }).catch((err) => {
1387  reject(err);
1388  });
1389  }else{
1390  console.warn("Column Update Error - No matching column found:", field);
1391  reject();
1392  }
1393  });
1394 };
1395 
1396 
1397 Tabulator.prototype.moveColumn = function(from, to, after){
1398  var fromColumn = this.columnManager.findColumn(from);
1399  var toColumn = this.columnManager.findColumn(to);
1400 
1401  if(fromColumn){
1402  if(toColumn){
1403  this.columnManager.moveColumn(fromColumn, toColumn, after)
1404  }else{
1405  console.warn("Move Error - No matching column found:", toColumn);
1406  }
1407  }else{
1408  console.warn("Move Error - No matching column found:", from);
1409  }
1410 };
1411 
1412 //scroll to column in DOM
1413 Tabulator.prototype.scrollToColumn = function(field, position, ifVisible){
1414 
1415  return new Promise((resolve, reject) => {
1416  var column = this.columnManager.findColumn(field);
1417 
1418  if(column){
1419  this.columnManager.scrollToColumn(column, position, ifVisible)
1420  .then(()=>{
1421  resolve();
1422  })
1423  .catch((err)=>{
1424  reject(err);
1425  });
1426  }else{
1427  console.warn("Scroll Error - No matching column found:", field);
1428  reject("Scroll Error - No matching column found");
1429  }
1430  });
1431 
1432 };
1433 
1434 
1436 Tabulator.prototype.setLocale = function(locale){
1437  this.modules.localize.setLocale(locale);
1438 };
1439 
1440 Tabulator.prototype.getLocale = function(){
1441  return this.modules.localize.getLocale();
1442 };
1443 
1444 Tabulator.prototype.getLang = function(locale){
1445  return this.modules.localize.getLang(locale);
1446 };
1447 
1449 
1450 //redraw list without updating data
1451 Tabulator.prototype.redraw = function(force){
1452  this.columnManager.redraw(force);
1453  this.rowManager.redraw(force);
1454 };
1455 
1456 Tabulator.prototype.setHeight = function(height){
1457 
1458  if(this.rowManager.renderMode !== "classic"){
1459  this.options.height = isNaN(height) ? height : height + "px";
1460  this.element.style.height = this.options.height;
1461  this.rowManager.redraw();
1462  }else{
1463  console.warn("setHeight function is not available in classic render mode");
1464  }
1465 
1466 };
1467 
1469 
1470 //trigger sort
1471 Tabulator.prototype.setSort = function(sortList, dir){
1472  if(this.modExists("sort", true)){
1473  this.modules.sort.setSort(sortList, dir);
1474  this.rowManager.sorterRefresh();
1475  }
1476 };
1477 
1478 Tabulator.prototype.getSorters = function(){
1479  if(this.modExists("sort", true)){
1480  return this.modules.sort.getSort();
1481  }
1482 };
1483 
1484 Tabulator.prototype.clearSort = function(){
1485  if(this.modExists("sort", true)){
1486  this.modules.sort.clear();
1487  this.rowManager.sorterRefresh();
1488  }
1489 };
1490 
1491 
1493 
1494 //set standard filters
1495 Tabulator.prototype.setFilter = function(field, type, value){
1496  if(this.modExists("filter", true)){
1497  this.modules.filter.setFilter(field, type, value);
1498  this.rowManager.filterRefresh();
1499  }
1500 };
1501 
1502 //add filter to array
1503 Tabulator.prototype.addFilter = function(field, type, value){
1504  if(this.modExists("filter", true)){
1505  this.modules.filter.addFilter(field, type, value);
1506  this.rowManager.filterRefresh();
1507  }
1508 };
1509 
1510 //get all filters
1511 Tabulator.prototype.getFilters = function(all){
1512  if(this.modExists("filter", true)){
1513  return this.modules.filter.getFilters(all);
1514  }
1515 };
1516 
1517 Tabulator.prototype.setHeaderFilterFocus = function(field){
1518  if(this.modExists("filter", true)){
1519  var column = this.columnManager.findColumn(field);
1520 
1521  if(column){
1522  this.modules.filter.setHeaderFilterFocus(column);
1523  }else{
1524  console.warn("Column Filter Focus Error - No matching column found:", field);
1525  return false;
1526  }
1527  }
1528 };
1529 
1530 
1531 Tabulator.prototype.setHeaderFilterValue = function(field, value){
1532  if(this.modExists("filter", true)){
1533  var column = this.columnManager.findColumn(field);
1534 
1535  if(column){
1536  this.modules.filter.setHeaderFilterValue(column, value);
1537  }else{
1538  console.warn("Column Filter Error - No matching column found:", field);
1539  return false;
1540  }
1541  }
1542 };
1543 
1544 Tabulator.prototype.getHeaderFilters = function(){
1545  if(this.modExists("filter", true)){
1546  return this.modules.filter.getHeaderFilters();
1547  }
1548 };
1549 
1550 
1551 //remove filter from array
1552 Tabulator.prototype.removeFilter = function(field, type, value){
1553  if(this.modExists("filter", true)){
1554  this.modules.filter.removeFilter(field, type, value);
1555  this.rowManager.filterRefresh();
1556  }
1557 };
1558 
1559 //clear filters
1560 Tabulator.prototype.clearFilter = function(all){
1561  if(this.modExists("filter", true)){
1562  this.modules.filter.clearFilter(all);
1563  this.rowManager.filterRefresh();
1564  }
1565 };
1566 
1567 //clear header filters
1568 Tabulator.prototype.clearHeaderFilter = function(){
1569  if(this.modExists("filter", true)){
1570  this.modules.filter.clearHeaderFilter();
1571  this.rowManager.filterRefresh();
1572  }
1573 };
1574 
1576 Tabulator.prototype.selectRow = function(rows){
1577  if(this.modExists("selectRow", true)){
1578  if(rows === true){
1579  console.warn("passing a boolean to the selectRowselectRow function is deprecated, you should now pass the string 'active'");
1580  rows = "active";
1581  }
1582  this.modules.selectRow.selectRows(rows);
1583  }
1584 };
1585 
1586 Tabulator.prototype.deselectRow = function(rows){
1587  if(this.modExists("selectRow", true)){
1588  this.modules.selectRow.deselectRows(rows);
1589  }
1590 };
1591 
1592 Tabulator.prototype.toggleSelectRow = function(row){
1593  if(this.modExists("selectRow", true)){
1594  this.modules.selectRow.toggleRow(row);
1595  }
1596 };
1597 
1598 Tabulator.prototype.getSelectedRows = function(){
1599  if(this.modExists("selectRow", true)){
1600  return this.modules.selectRow.getSelectedRows();
1601  }
1602 };
1603 
1604 Tabulator.prototype.getSelectedData = function(){
1605  if(this.modExists("selectRow", true)){
1606  return this.modules.selectRow.getSelectedData();
1607  }
1608 };
1609 
1611 
1612 Tabulator.prototype.setMaxPage = function(max){
1613  if(this.options.pagination && this.modExists("page")){
1614  this.modules.page.setMaxPage(max);
1615  }else{
1616  return false;
1617  }
1618 };
1619 
1620 Tabulator.prototype.setPage = function(page){
1621  if(this.options.pagination && this.modExists("page")){
1622  return this.modules.page.setPage(page);
1623  }else{
1624  return new Promise((resolve, reject) => { reject() });
1625  }
1626 };
1627 
1628 Tabulator.prototype.setPageToRow = function(row){
1629  return new Promise((resolve, reject) => {
1630  if(this.options.pagination && this.modExists("page")){
1631  row = this.rowManager.findRow(row);
1632 
1633  if(row){
1634  this.modules.page.setPageToRow(row)
1635  .then(()=>{
1636  resolve();
1637  })
1638  .catch(()=>{
1639  reject();
1640  });
1641  }else{
1642  reject();
1643  }
1644  }else{
1645  reject();
1646  }
1647  });
1648 };
1649 
1650 
1651 Tabulator.prototype.setPageSize = function(size){
1652  if(this.options.pagination && this.modExists("page")){
1653  this.modules.page.setPageSize(size);
1654  this.modules.page.setPage(1).then(()=>{}).catch(()=>{});
1655  }else{
1656  return false;
1657  }
1658 };
1659 
1660 Tabulator.prototype.getPageSize = function(){
1661  if(this.options.pagination && this.modExists("page", true)){
1662  return this.modules.page.getPageSize();
1663  }
1664 };
1665 
1666 Tabulator.prototype.previousPage = function(){
1667  if(this.options.pagination && this.modExists("page")){
1668  this.modules.page.previousPage();
1669  }else{
1670  return false;
1671  }
1672 };
1673 
1674 Tabulator.prototype.nextPage = function(){
1675  if(this.options.pagination && this.modExists("page")){
1676  this.modules.page.nextPage();
1677  }else{
1678  return false;
1679  }
1680 };
1681 
1682 Tabulator.prototype.getPage = function(){
1683  if(this.options.pagination && this.modExists("page")){
1684  return this.modules.page.getPage();
1685  }else{
1686  return false;
1687  }
1688 };
1689 
1690 Tabulator.prototype.getPageMax = function(){
1691  if(this.options.pagination && this.modExists("page")){
1692  return this.modules.page.getPageMax();
1693  }else{
1694  return false;
1695  }
1696 };
1697 
1699 
1700 Tabulator.prototype.setGroupBy = function(groups){
1701  if(this.modExists("groupRows", true)){
1702  this.options.groupBy = groups;
1703  this.modules.groupRows.initialize();
1704  this.rowManager.refreshActiveData("display");
1705 
1706  if(this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group){
1707  this.modules.persistence.save("group");
1708  }
1709  }else{
1710  return false;
1711  }
1712 };
1713 
1714 Tabulator.prototype.setGroupStartOpen = function(values){
1715  if(this.modExists("groupRows", true)){
1716  this.options.groupStartOpen = values;
1717  this.modules.groupRows.initialize();
1718  if(this.options.groupBy){
1719  this.rowManager.refreshActiveData("group");
1720 
1721  if(this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group){
1722  this.modules.persistence.save("group");
1723  }
1724  }else{
1725  console.warn("Grouping Update - cant refresh view, no groups have been set");
1726  }
1727  }else{
1728  return false;
1729  }
1730 };
1731 
1732 Tabulator.prototype.setGroupHeader = function(values){
1733  if(this.modExists("groupRows", true)){
1734  this.options.groupHeader = values;
1735  this.modules.groupRows.initialize();
1736  if(this.options.groupBy){
1737  this.rowManager.refreshActiveData("group");
1738 
1739  if(this.options.persistence && this.modExists("persistence", true) && this.modules.persistence.config.group){
1740  this.modules.persistence.save("group");
1741  }
1742  }else{
1743  console.warn("Grouping Update - cant refresh view, no groups have been set");
1744  }
1745  }else{
1746  return false;
1747  }
1748 };
1749 
1750 Tabulator.prototype.getGroups = function(values){
1751  if(this.modExists("groupRows", true)){
1752  return this.modules.groupRows.getGroups(true);
1753  }else{
1754  return false;
1755  }
1756 };
1757 
1758 // get grouped table data in the same format as getData()
1759 Tabulator.prototype.getGroupedData = function(){
1760  if (this.modExists("groupRows", true)){
1761  return this.options.groupBy ?
1762  this.modules.groupRows.getGroupedData() : this.getData()
1763  }
1764 }
1765 
1767 Tabulator.prototype.getCalcResults = function(){
1768  if(this.modExists("columnCalcs", true)){
1769  return this.modules.columnCalcs.getResults();
1770  }else{
1771  return false;
1772  }
1773 };
1774 
1776 
1777 Tabulator.prototype.navigatePrev = function(){
1778  var cell = false;
1779 
1780  if(this.modExists("edit", true)){
1781  cell = this.modules.edit.currentCell;
1782 
1783  if(cell){
1784  return cell.nav().prev();
1785  }
1786  }
1787 
1788  return false;
1789 };
1790 
1791 Tabulator.prototype.navigateNext = function(){
1792  var cell = false;
1793 
1794  if(this.modExists("edit", true)){
1795  cell = this.modules.edit.currentCell;
1796 
1797  if(cell){
1798  return cell.nav().next();
1799  }
1800  }
1801 
1802  return false;
1803 };
1804 
1805 Tabulator.prototype.navigateLeft = function(){
1806  var cell = false;
1807 
1808  if(this.modExists("edit", true)){
1809  cell = this.modules.edit.currentCell;
1810 
1811  if(cell){
1812  e.preventDefault();
1813  return cell.nav().left();
1814  }
1815  }
1816 
1817  return false;
1818 };
1819 
1820 Tabulator.prototype.navigateRight = function(){
1821  var cell = false;
1822 
1823  if(this.modExists("edit", true)){
1824  cell = this.modules.edit.currentCell;
1825 
1826  if(cell){
1827  e.preventDefault();
1828  return cell.nav().right();
1829  }
1830  }
1831 
1832  return false;
1833 };
1834 
1835 Tabulator.prototype.navigateUp = function(){
1836  var cell = false;
1837 
1838  if(this.modExists("edit", true)){
1839  cell = this.modules.edit.currentCell;
1840 
1841  if(cell){
1842  e.preventDefault();
1843  return cell.nav().up();
1844  }
1845  }
1846 
1847  return false;
1848 };
1849 
1850 Tabulator.prototype.navigateDown = function(){
1851  var cell = false;
1852 
1853  if(this.modExists("edit", true)){
1854  cell = this.modules.edit.currentCell;
1855 
1856  if(cell){
1857  e.preventDefault();
1858  return cell.nav().down();
1859  }
1860  }
1861 
1862  return false;
1863 };
1864 
1865 
1867 Tabulator.prototype.undo = function(){
1868  if(this.options.history && this.modExists("history", true)){
1869  return this.modules.history.undo();
1870  }else{
1871  return false;
1872  }
1873 };
1874 
1875 Tabulator.prototype.redo = function(){
1876  if(this.options.history && this.modExists("history", true)){
1877  return this.modules.history.redo();
1878  }else{
1879  return false;
1880  }
1881 };
1882 
1883 Tabulator.prototype.getHistoryUndoSize = function(){
1884  if(this.options.history && this.modExists("history", true)){
1885  return this.modules.history.getHistoryUndoSize();
1886  }else{
1887  return false;
1888  }
1889 };
1890 
1891 Tabulator.prototype.getHistoryRedoSize = function(){
1892  if(this.options.history && this.modExists("history", true)){
1893  return this.modules.history.getHistoryRedoSize();
1894  }else{
1895  return false;
1896  }
1897 };
1898 
1900 
1901 Tabulator.prototype.download = function(type, filename, options, active){
1902  if(this.modExists("download", true)){
1903  this.modules.download.download(type, filename, options, active);
1904  }
1905 };
1906 
1907 Tabulator.prototype.downloadToTab = function(type, filename, options, active){
1908  if(this.modExists("download", true)){
1909  this.modules.download.download(type, filename, options, active, true);
1910  }
1911 };
1912 
1913 
1915 
1916 Tabulator.prototype.tableComms = function(table, module, action, data){
1917  this.modules.comms.receive(table, module, action, data);
1918 };
1919 
1921 
1922 //object to hold module
1923 Tabulator.prototype.moduleBindings = {};
1924 
1925 //extend module
1926 Tabulator.prototype.extendModule = function(name, property, values){
1927 
1928  if(Tabulator.prototype.moduleBindings[name]){
1929  var source = Tabulator.prototype.moduleBindings[name].prototype[property];
1930 
1931  if(source){
1932  if(typeof values == "object"){
1933  for(let key in values){
1934  source[key] = values[key];
1935  }
1936  }else{
1937  console.warn("Module Error - Invalid value type, it must be an object");
1938  }
1939  }else{
1940  console.warn("Module Error - property does not exist:", property);
1941  }
1942  }else{
1943  console.warn("Module Error - module does not exist:", name);
1944  }
1945 
1946 };
1947 
1948 //add module to tabulator
1949 Tabulator.prototype.registerModule = function(name, module){
1950  var self = this;
1951  Tabulator.prototype.moduleBindings[name] = module;
1952 };
1953 
1954 //ensure that module are bound to instantiated function
1955 Tabulator.prototype.bindModules = function(){
1956  this.modules = {};
1957 
1958  for(var name in Tabulator.prototype.moduleBindings){
1959  this.modules[name] = new Tabulator.prototype.moduleBindings[name](this);
1960  }
1961 };
1962 
1963 //Check for module
1964 Tabulator.prototype.modExists = function(plugin, required){
1965  if(this.modules[plugin]){
1966  return true;
1967  }else{
1968  if(required){
1969  console.error("Tabulator Module Not Installed: " + plugin);
1970  }
1971  return false;
1972  }
1973 };
1974 
1975 
1976 Tabulator.prototype.helpers = {
1977 
1978  elVisible: function(el){
1979  return !(el.offsetWidth <= 0 && el.offsetHeight <= 0);
1980  },
1981 
1982  elOffset: function(el){
1983  var box = el.getBoundingClientRect();
1984 
1985  return {
1986  top: box.top + window.pageYOffset - document.documentElement.clientTop,
1987  left: box.left + window.pageXOffset - document.documentElement.clientLeft
1988  };
1989  },
1990 
1991  deepClone: function(obj){
1992  var clone = Array.isArray(obj) ? [] : {};
1993 
1994  for(var i in obj) {
1995  if(obj[i] != null && typeof(obj[i]) === "object"){
1996  if (obj[i] instanceof Date) {
1997  clone[i] = new Date(obj[i]);
1998  } else {
1999  clone[i] = this.deepClone(obj[i]);
2000  }
2001  }
2002  else{
2003  clone[i] = obj[i];
2004  }
2005  }
2006  return clone;
2007  }
2008 };
2009 
2010 Tabulator.prototype.comms = {
2011  tables:[],
2012  register:function(table){
2013  Tabulator.prototype.comms.tables.push(table);
2014  },
2015  deregister:function(table){
2016  var index = Tabulator.prototype.comms.tables.indexOf(table);
2017 
2018  if(index > -1){
2019  Tabulator.prototype.comms.tables.splice(index, 1);
2020  }
2021  },
2022  lookupTable:function(query, silent){
2023  var results = [],
2024  matches, match;
2025 
2026  if(typeof query === "string"){
2027  matches = document.querySelectorAll(query);
2028 
2029  if(matches.length){
2030  for(var i = 0; i < matches.length; i++){
2031  match = Tabulator.prototype.comms.matchElement(matches[i]);
2032 
2033  if(match){
2034  results.push(match);
2035  }
2036  }
2037  }
2038 
2039  }else if((typeof HTMLElement !== "undefined" && query instanceof HTMLElement) || query instanceof Tabulator){
2040  match = Tabulator.prototype.comms.matchElement(query);
2041 
2042  if(match){
2043  results.push(match);
2044  }
2045  }else if(Array.isArray(query)){
2046  query.forEach(function(item){
2047  results = results.concat(Tabulator.prototype.comms.lookupTable(item));
2048  });
2049  }else{
2050  if(!silent){
2051  console.warn("Table Connection Error - Invalid Selector", query);
2052  }
2053  }
2054 
2055  return results;
2056  },
2057  matchElement:function(element){
2058  return Tabulator.prototype.comms.tables.find(function(table){
2059  return element instanceof Tabulator ? table === element : table.element === element;
2060  });
2061  }
2062 };
2063 
2064 Tabulator.prototype.findTable = function(query){
2065  var results = Tabulator.prototype.comms.lookupTable(query, true);
2066  return Array.isArray(results) && !results.length ? false : results;
2067 }
2068 
2069 /*=include modules/layout.js */
2070 /*=include modules/localize.js */
2071 /*=include modules/comms.js */