12 var Tabulator =
function(element, options){
16 this.columnManager = null;
17 this.rowManager = null;
18 this.footerManager = null;
20 this.browserSlow =
false;
21 this.browserMobile =
false;
25 this.initializeElement(element);
26 this.initializeOptions(options || {});
29 Tabulator.prototype.comms.register(
this);
33 Tabulator.prototype.defaultOptions = {
38 layoutColumnsOnNewData:
false,
41 columnHeaderVertAlign:
"top",
42 columnVertAlign:
false,
44 resizableColumns:
true,
56 nestedFieldSeparator:
".",
59 tooltipsHeader:
false,
60 tooltipGenerationMode:
"load",
64 initialHeaderFilter:
false,
66 columnHeaderSortMulti:
true,
68 sortOrderReverse:
false,
71 headerSortTristate:
false,
81 invalidOptionWarnings:
true,
84 clipboardCopyStyled:
true,
85 clipboardCopySelector:
"active",
86 clipboardCopyFormatter:
"table",
87 clipboardPasteParser:
"table",
88 clipboardPasteAction:
"insert",
89 clipboardCopyConfig:
false,
91 clipboardCopied:
function(){},
92 clipboardPasted:
function(){},
93 clipboardPasteError:
function(){},
95 downloadDataFormatter:
false,
96 downloadReady:
function(data, blob){
return blob;},
97 downloadComplete:
false,
101 dataTreeElementColumn:
false,
102 dataTreeBranchElement:
true,
103 dataTreeChildIndent:9,
104 dataTreeChildField:
"_children",
105 dataTreeCollapseElement:
false,
106 dataTreeExpandElement:
false,
107 dataTreeStartExpanded:
false,
108 dataTreeRowExpanded:
function(){},
109 dataTreeRowCollapsed:
function(){},
112 printFormatter:
false,
116 printVisibleRows:
true,
121 selectable:
"highlight",
122 selectableRangeMode:
"drag",
123 selectableRollingSelection:
true,
124 selectablePersistence:
true,
125 selectableCheck:
function(data, row){
return true;},
127 headerFilterLiveFilterDelay: 300,
128 headerFilterPlaceholder:
false,
140 persistentLayout:
false,
141 persistentSort:
false,
142 persistentFilter:
false,
144 persistenceMode:
true,
145 persistenceReaderFunc:
false,
146 persistenceWriterFunc:
false,
150 responsiveLayout:
false,
151 responsiveLayoutCollapseStartOpen:
true,
152 responsiveLayoutCollapseUseFormatters:
true,
153 responsiveLayoutCollapseFormatter:
false,
156 paginationSize:
false,
157 paginationInitialPage:1,
158 paginationButtonCount: 5,
159 paginationSizeSelector:
false,
160 paginationElement:
false,
161 paginationDataSent:{},
162 paginationDataReceived:{},
163 paginationAddRow:
"page",
166 ajaxURLGenerator:
false,
169 ajaxContentType:
"form",
170 ajaxRequestFunc:
false,
172 ajaxLoaderLoading:
false,
173 ajaxLoaderError:
false,
176 ajaxProgressiveLoad:
false,
177 ajaxProgressiveLoadDelay:0,
178 ajaxProgressiveLoadScrollMargin:0,
186 htmlOutputConfig:
false,
188 movableColumns:
false,
191 movableRowsConnectedTables:
false,
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(){},
203 scrollToRowPosition:
"top",
204 scrollToRowIfVisible:
true,
206 scrollToColumnPosition:
"left",
207 scrollToColumnIfVisible:
true,
214 tableBuilding:
function(){},
215 tableBuilt:
function(){},
218 renderStarted:
function(){},
219 renderComplete:
function(){},
233 rowAdded:
function(){},
234 rowDeleted:
function(){},
235 rowMoved:
function(){},
236 rowUpdated:
function(){},
237 rowSelectionChanged:
function(){},
238 rowSelected:
function(){},
239 rowDeselected:
function(){},
240 rowResized:
function(){},
250 cellMouseEnter:
false,
251 cellMouseLeave:
false,
255 cellEditing:
function(){},
256 cellEdited:
function(){},
257 cellEditCancelled:
function(){},
261 columnResized:
function(){},
262 columnTitleChanged:
function(){},
263 columnVisibilityChanged:
function(){},
266 htmlImporting:
function(){},
267 htmlImported:
function(){},
270 dataLoading:
function(){},
271 dataLoaded:
function(){},
272 dataEdited:
function(){},
275 ajaxRequesting:
function(){},
277 ajaxError:
function(){},
284 dataSorting:
function(){},
285 dataSorted:
function(){},
288 groupToggleElement:
"arrow",
289 groupClosedShowCalcs:
false,
290 dataGrouping:
function(){},
292 groupVisibilityChanged:
function(){},
303 pageLoaded:
function(){},
306 localized:
function(){},
309 validationFailed:
function(){},
312 historyUndo:
function(){},
313 historyRedo:
function(){},
316 scrollHorizontal:
function(){},
317 scrollVertical:
function(){},
321 Tabulator.prototype.initializeOptions =
function(options){
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)
333 for (var key in this.defaultOptions){
335 this.options[key] = options[key];
337 if(Array.isArray(
this.defaultOptions[key])){
338 this.options[key] = [];
339 }
else if(typeof this.defaultOptions[key] ===
"object"){
340 this.options[key] = {};
342 this.options[key] = this.defaultOptions[key];
348 Tabulator.prototype.initializeElement =
function(element){
350 if(typeof HTMLElement !==
"undefined" && element instanceof HTMLElement){
351 this.element = element;
353 }
else if(typeof element ===
"string"){
354 this.element = document.querySelector(element);
359 console.error(
"Tabulator Creation Error - no element found matching selector: ", element);
363 console.error(
"Tabulator Creation Error - Invalid element provided:", element);
371 Tabulator.prototype._mapDepricatedFunctionality =
function(){
374 if(this.options.persistentLayout ||
this.options.persistentSort ||
this.options.persistentFilter){
375 if(!this.options.persistence){
376 this.options.persistence = {};
380 if(this.options.persistentLayout){
381 console.warn(
"persistentLayout option is deprecated, you should now use the persistence option");
383 if(this.options.persistence !==
true && typeof
this.options.persistence.columns ===
"undefined"){
384 this.options.persistence.columns =
true;
388 if(this.options.persistentSort){
389 console.warn(
"persistentSort option is deprecated, you should now use the persistence option");
391 if(this.options.persistence !==
true && typeof
this.options.persistence.sort ===
"undefined"){
392 this.options.persistence.sort =
true;
396 if(this.options.persistentFilter){
397 console.warn(
"persistentFilter option is deprecated, you should now use the persistence option");
399 if(this.options.persistence !==
true && typeof
this.options.persistence.filter ===
"undefined"){
400 this.options.persistence.filter =
true;
404 if(this.options.columnVertAlign){
405 console.warn(
"columnVertAlign option is deprecated, you should now use the columnHeaderVertAlign option");
407 this.options.columnHeaderVertAlign = this.options.columnVertAlign;
411 Tabulator.prototype._clearSelection =
function(){
413 this.element.classList.add(
"tabulator-block-select");
415 if (window.getSelection) {
416 if (window.getSelection().empty) {
417 window.getSelection().empty();
418 }
else if (window.getSelection().removeAllRanges) {
419 window.getSelection().removeAllRanges();
421 }
else if (document.selection) {
422 document.selection.empty();
425 this.element.classList.remove(
"tabulator-block-select");
430 Tabulator.prototype._create =
function(){
431 this._clearObjectPointers();
433 this._mapDepricatedFunctionality();
437 if(this.element.tagName ===
"TABLE"){
438 if(this.modExists(
"htmlTableImport",
true)){
439 this.modules.htmlTableImport.parseTable();
443 this.columnManager =
new ColumnManager(
this);
444 this.rowManager =
new RowManager(
this);
445 this.footerManager =
new FooterManager(
this);
447 this.columnManager.setRowManager(this.rowManager);
448 this.rowManager.setColumnManager(this.columnManager);
450 this._buildElement();
452 this._loadInitialData();
456 Tabulator.prototype._clearObjectPointers =
function(){
457 this.options.columns = this.options.columns.slice(0);
459 if(!this.options.reactiveData){
460 this.options.data = this.options.data.slice(0);
466 Tabulator.prototype._buildElement =
function(){
467 var element = this.element,
469 options = this.options;
471 options.tableBuilding.call(
this);
473 element.classList.add(
"tabulator");
474 element.setAttribute(
"role",
"grid");
477 while(element.firstChild) element.removeChild(element.firstChild);
481 options.height = isNaN(options.height) ? options.height : options.height +
"px";
482 element.style.height = options.height;
485 this.columnManager.initialize();
486 this.rowManager.initialize();
488 this._detectBrowser();
490 if(this.modExists(
"layout",
true)){
491 mod.layout.initialize(options.layout);
495 if(options.headerFilterPlaceholder !==
false){
496 mod.localize.setHeaderFilterPlaceholder(options.headerFilterPlaceholder);
499 for(let locale in options.langs){
500 mod.localize.installLang(locale, options.langs[locale]);
503 mod.localize.setLocale(options.locale);
506 if(typeof options.placeholder ==
"string"){
508 var el = document.createElement(
"div");
509 el.classList.add(
"tabulator-placeholder");
511 var span = document.createElement(
"span");
512 span.innerHTML = options.placeholder;
514 el.appendChild(span);
516 options.placeholder = el;
520 element.appendChild(this.columnManager.getElement());
521 element.appendChild(this.rowManager.getElement());
524 if(options.footerElement){
525 this.footerManager.activate();
528 if(options.persistence &&
this.modExists(
"persistence",
true)){
529 mod.persistence.initialize();
532 if(options.persistence &&
this.modExists(
"persistence",
true) && mod.persistence.config.columns){
533 options.columns = mod.persistence.load(
"columns", options.columns) ;
536 if(options.movableRows &&
this.modExists(
"moveRow")){
537 mod.moveRow.initialize();
540 if(options.autoColumns &&
this.options.data){
541 this.columnManager.generateColumnsFromRowData(this.options.data);
544 if(this.modExists(
"columnCalcs")){
545 mod.columnCalcs.initialize();
548 this.columnManager.setColumns(options.columns);
550 if(options.dataTree &&
this.modExists(
"dataTree",
true)){
551 mod.dataTree.initialize();
554 if(this.modExists(
"frozenRows")){
555 this.modules.frozenRows.initialize();
558 if(((options.persistence &&
this.modExists(
"persistence",
true) && mod.persistence.config.sort) || options.initialSort) && this.modExists(
"sort",
true)){
561 if(options.persistence &&
this.modExists(
"persistence",
true) && mod.persistence.config.sort){
562 sorters = mod.persistence.load(
"sort");
564 if(sorters ===
false && options.initialSort){
565 sorters = options.initialSort;
567 }
else if(options.initialSort){
568 sorters = options.initialSort;
571 mod.sort.setSort(sorters);
574 if(((options.persistence &&
this.modExists(
"persistence",
true) && mod.persistence.config.filter) || options.initialFilter) && this.modExists(
"filter",
true)){
578 if(options.persistence &&
this.modExists(
"persistence",
true) && mod.persistence.config.filter){
579 filters = mod.persistence.load(
"filter");
581 if(filters ===
false && options.initialFilter){
582 filters = options.initialFilter;
584 }
else if(options.initialFilter){
585 filters = options.initialFilter;
588 mod.filter.setFilter(filters);
591 if(options.initialHeaderFilter &&
this.modExists(
"filter",
true)){
592 options.initialHeaderFilter.forEach((item) => {
594 var column = this.columnManager.findColumn(item.field);
597 mod.filter.setHeaderFilterValue(column, item.value);
599 console.warn(
"Column Filter Error - No matching column found:", item.field);
606 if(this.modExists(
"ajax")){
607 mod.ajax.initialize();
610 if(options.pagination &&
this.modExists(
"page",
true)){
611 mod.page.initialize();
614 if(options.groupBy &&
this.modExists(
"groupRows",
true)){
615 mod.groupRows.initialize();
618 if(this.modExists(
"keybindings")){
619 mod.keybindings.initialize();
622 if(this.modExists(
"selectRow")){
623 mod.selectRow.clearSelectionData(
true);
626 if(options.autoResize &&
this.modExists(
"resizeTable")){
627 mod.resizeTable.initialize();
630 if(this.modExists(
"clipboard")){
631 mod.clipboard.initialize();
634 if(options.printAsHtml &&
this.modExists(
"print")){
635 mod.print.initialize();
638 options.tableBuilt.call(
this);
641 Tabulator.prototype._loadInitialData =
function(){
644 if(
self.options.pagination &&
self.modExists(
"page")){
645 self.modules.page.reset(
true);
647 if(
self.options.pagination ==
"local"){
648 if(
self.options.data.length){
649 self.rowManager.setData(
self.options.data);
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);
660 self.rowManager.setData(
self.options.data);
664 if(
self.options.paginationInitialPage){
665 self.modules.page.setPage(
self.options.paginationInitialPage);
668 if(
self.options.ajaxURL){
669 self.modules.page.setPage(
self.options.paginationInitialPage).then(()=>{}).
catch(()=>{});
671 self.rowManager.setData([]);
675 if(
self.options.data.length){
676 self.rowManager.setData(
self.options.data);
678 if((
self.options.ajaxURL ||
self.options.ajaxURLGenerator) &&
self.modExists(
"ajax")){
679 self.modules.ajax.loadData().then(()=>{}).
catch(()=>{});
681 self.rowManager.setData(
self.options.data);
688 Tabulator.prototype.destroy =
function(){
689 var element = this.element;
691 Tabulator.prototype.comms.deregister(
this);
693 if(this.options.reactiveData &&
this.modExists(
"reactiveData",
true)){
694 this.modules.reactiveData.unwatchData();
698 this.rowManager.rows.forEach(
function(row){
702 this.rowManager.rows = [];
703 this.rowManager.activeRows = [];
704 this.rowManager.displayRows = [];
707 if(this.options.autoResize &&
this.modExists(
"resizeTable")){
708 this.modules.resizeTable.clearBindings();
711 if(this.modExists(
"keybindings")){
712 this.modules.keybindings.clearBindings();
716 while(element.firstChild) element.removeChild(element.firstChild);
717 element.classList.remove(
"tabulator");
720 Tabulator.prototype._detectBrowser =
function(){
721 var ua = navigator.userAgent||navigator.vendor||window.opera;
723 if(ua.indexOf(
"Trident") > -1){
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;
733 this.browser =
"other";
734 this.browserSlow =
false;
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));
743 Tabulator.prototype.blockRedraw = function(){
744 return this.rowManager.blockRedraw();
748 Tabulator.prototype.restoreRedraw =
function(){
749 return this.rowManager.restoreRedraw();
754 Tabulator.prototype.setDataFromLocalFile =
function(extensions){
756 return new Promise((resolve, reject) => {
757 var input = document.createElement(
"input");
759 input.accept = extensions ||
".json,application/json";
761 input.addEventListener(
"change", (e) => {
762 var file = input.files[0],
763 reader =
new FileReader(),
766 reader.readAsText(file);
768 reader.onload = (e) => {
771 data = JSON.parse(reader.result);
773 console.warn(
"File Load Error - File contents is invalid JSON", e);
787 reader.onerror = (e) => {
788 console.warn(
"File Load Error - Unable to read file");
799 Tabulator.prototype.setData =
function(data, params, config){
800 if(this.modExists(
"ajax")){
801 this.modules.ajax.blockActiveRequest();
804 return this._setData(data, params, config);
807 Tabulator.prototype._setData =
function(data, params, config, inPosition){
810 if(typeof(data) ===
"string"){
811 if (data.indexOf(
"{") == 0 || data.indexOf(
"[") == 0){
813 return self.rowManager.setData(JSON.parse(data), inPosition);
816 if(
self.modExists(
"ajax",
true)){
818 self.modules.ajax.setParams(params);
822 self.modules.ajax.setConfig(config);
825 self.modules.ajax.setUrl(data);
827 if(
self.options.pagination ==
"remote" &&
self.modExists(
"page",
true)){
828 self.modules.page.reset(
true);
829 return self.modules.page.setPage(1);
832 return self.modules.ajax.loadData(inPosition);
839 return self.rowManager.setData(data, inPosition);
843 if(
self.modExists(
"ajax") && (
self.modules.ajax.getUrl ||
self.options.ajaxURLGenerator)){
845 if(
self.options.pagination ==
"remote" &&
self.modExists(
"page",
true)){
846 self.modules.page.reset(
true);
847 return self.modules.page.setPage(1);
849 return self.modules.ajax.loadData(inPosition);
854 return self.rowManager.setData([], inPosition);
861 Tabulator.prototype.clearData =
function(){
862 if(this.modExists(
"ajax")){
863 this.modules.ajax.blockActiveRequest();
866 this.rowManager.clearData();
870 Tabulator.prototype.getData =
function(active){
873 console.warn(
"passing a boolean to the getData function is deprecated, you should now pass the string 'active'");
877 return this.rowManager.getData(active);
881 Tabulator.prototype.getDataCount =
function(active){
884 console.warn(
"passing a boolean to the getDataCount function is deprecated, you should now pass the string 'active'");
888 return this.rowManager.getDataCount(active);
892 Tabulator.prototype.searchRows =
function(field, type, value){
893 if(this.modExists(
"filter",
true)){
894 return this.modules.filter.search(
"rows", field, type, value);
899 Tabulator.prototype.searchData =
function(field, type, value){
900 if(this.modExists(
"filter",
true)){
901 return this.modules.filter.search(
"data", field, type, value);
906 Tabulator.prototype.getHtml =
function(visible, style, config){
907 if(this.modExists(
"htmlTableExport",
true)){
908 return this.modules.htmlTableExport.getHtml(visible, style, config);
913 Tabulator.prototype.print =
function(visible, style, config){
914 if(this.modExists(
"print",
true)){
915 return this.modules.print.printFullscreen(visible, style, config);
920 Tabulator.prototype.getAjaxUrl =
function(){
921 if(this.modExists(
"ajax",
true)){
922 return this.modules.ajax.getUrl();
927 Tabulator.prototype.replaceData =
function(data, params, config){
928 if(this.modExists(
"ajax")){
929 this.modules.ajax.blockActiveRequest();
932 return this._setData(data, params, config,
true);
937 Tabulator.prototype.updateData =
function(data){
941 return new Promise((resolve, reject) => {
942 if(this.modExists(
"ajax")){
943 this.modules.ajax.blockActiveRequest();
946 if(typeof data ===
"string"){
947 data = JSON.parse(data);
951 data.forEach(
function(item){
952 var row =
self.rowManager.findRow(item[
self.options.index]);
968 console.warn(
"Update Error - No data provided");
969 reject(
"Update Error - No data provided");
975 Tabulator.prototype.addData =
function(data, pos, index){
976 return new Promise((resolve, reject) => {
977 if(this.modExists(
"ajax")){
978 this.modules.ajax.blockActiveRequest();
981 if(typeof data ===
"string"){
982 data = JSON.parse(data);
986 this.rowManager.addRows(data, pos, index)
990 rows.forEach(
function(row){
991 output.push(row.getComponent());
997 console.warn(
"Update Error - No data provided");
998 reject(
"Update Error - No data provided");
1004 Tabulator.prototype.updateOrAddData =
function(data){
1009 return new Promise((resolve, reject) => {
1010 if(this.modExists(
"ajax")){
1011 this.modules.ajax.blockActiveRequest();
1014 if(typeof data ===
"string"){
1015 data = JSON.parse(data);
1019 data.forEach(
function(item){
1020 var row =
self.rowManager.findRow(item[
self.options.index]);
1025 row.updateData(item)
1028 rows.push(row.getComponent());
1035 self.rowManager.addRows(item)
1038 rows.push(newRows[0].getComponent());
1047 console.warn(
"Update Error - No data provided");
1048 reject(
"Update Error - No data provided");
1054 Tabulator.prototype.getRow =
function(index){
1055 var row = this.rowManager.findRow(index);
1058 return row.getComponent();
1060 console.warn(
"Find Error - No matching row found:", index);
1066 Tabulator.prototype.getRowFromPosition =
function(position, active){
1067 var row = this.rowManager.getRowFromPosition(position, active);
1070 return row.getComponent();
1072 console.warn(
"Find Error - No matching row found:", position);
1078 Tabulator.prototype.deleteRow =
function(index){
1079 return new Promise((resolve, reject) => {
1084 function doneCheck(){
1087 if(count == index.length){
1089 self.rowManager.reRenderInPosition();
1095 if(!Array.isArray(index)){
1099 index.forEach((item) =>{
1100 var row = this.rowManager.findRow(item,
true);
1114 console.warn(
"Delete Error - No matching row found:", item);
1115 reject(
"Delete Error - No matching row found")
1123 Tabulator.prototype.addRow = function(data, pos, index){
1124 return new Promise((resolve, reject) => {
1125 if(typeof data ===
"string"){
1126 data = JSON.parse(data);
1129 this.rowManager.addRows(data, pos, index)
1132 if(this.modExists(
"columnCalcs")){
1133 this.modules.columnCalcs.recalc(this.rowManager.activeRows);
1136 resolve(rows[0].getComponent());
1142 Tabulator.prototype.updateOrAddRow =
function(index, data){
1143 return new Promise((resolve, reject) => {
1144 var row = this.rowManager.findRow(index);
1146 if(typeof data ===
"string"){
1147 data = JSON.parse(data);
1151 row.updateData(data)
1154 if(this.modExists(
"columnCalcs")){
1155 this.modules.columnCalcs.recalc(this.rowManager.activeRows);
1158 resolve(row.getComponent());
1164 row = this.rowManager.addRows(data)
1167 if(this.modExists(
"columnCalcs")){
1168 this.modules.columnCalcs.recalc(this.rowManager.activeRows);
1171 resolve(rows[0].getComponent());
1181 Tabulator.prototype.updateRow =
function(index, data){
1182 return new Promise((resolve, reject) => {
1183 var row = this.rowManager.findRow(index);
1185 if(typeof data ===
"string"){
1186 data = JSON.parse(data);
1190 row.updateData(data).then(()=>{
1191 resolve(row.getComponent());
1197 console.warn(
"Update Error - No matching row found:", index);
1198 reject(
"Update Error - No matching row found");
1204 Tabulator.prototype.scrollToRow =
function(index, position, ifVisible){
1205 return new Promise((resolve, reject) => {
1206 var row = this.rowManager.findRow(index);
1209 this.rowManager.scrollToRow(row, position, ifVisible)
1217 console.warn(
"Scroll Error - No matching row found:", index);
1218 reject(
"Scroll Error - No matching row found");
1223 Tabulator.prototype.moveRow =
function(from, to, after){
1224 var fromRow = this.rowManager.findRow(from);
1227 fromRow.moveToRow(to, after);
1229 console.warn(
"Move Error - No matching row found:", from);
1233 Tabulator.prototype.getRows =
function(active){
1235 if(active ===
true){
1236 console.warn(
"passing a boolean to the getRows function is deprecated, you should now pass the string 'active'");
1240 return this.rowManager.getComponents(active);
1244 Tabulator.prototype.getRowPosition =
function(index, active){
1245 var row = this.rowManager.findRow(index);
1248 return this.rowManager.getRowPosition(row, active);
1250 console.warn(
"Position Error - No matching row found:", index);
1256 Tabulator.prototype.copyToClipboard =
function(selector, selectorParams, formatter, formatterParams){
1257 if(this.modExists(
"clipboard",
true)){
1258 this.modules.clipboard.copy(selector, selectorParams, formatter, formatterParams);
1264 Tabulator.prototype.setColumns =
function(definition){
1265 this.columnManager.setColumns(definition);
1268 Tabulator.prototype.getColumns =
function(structured){
1269 return this.columnManager.getComponents(structured);
1272 Tabulator.prototype.getColumn =
function(field){
1273 var col = this.columnManager.findColumn(field);
1276 return col.getComponent();
1278 console.warn(
"Find Error - No matching column found:", field);
1283 Tabulator.prototype.getColumnDefinitions =
function(){
1284 return this.columnManager.getDefinitionTree();
1287 Tabulator.prototype.getColumnLayout =
function(){
1288 if(this.modExists(
"persistence",
true)){
1289 return this.modules.persistence.parseColumns(this.columnManager.getColumns());
1293 Tabulator.prototype.setColumnLayout =
function(layout){
1294 if(this.modExists(
"persistence",
true)){
1295 this.columnManager.setColumns(this.modules.persistence.mergeDefinition(
this.options.columns, layout))
1301 Tabulator.prototype.showColumn =
function(field){
1302 var column = this.columnManager.findColumn(field);
1307 if(this.options.responsiveLayout &&
this.modExists(
"responsiveLayout",
true)){
1308 this.modules.responsiveLayout.update();
1311 console.warn(
"Column Show Error - No matching column found:", field);
1316 Tabulator.prototype.hideColumn =
function(field){
1317 var column = this.columnManager.findColumn(field);
1322 if(this.options.responsiveLayout &&
this.modExists(
"responsiveLayout",
true)){
1323 this.modules.responsiveLayout.update();
1326 console.warn(
"Column Hide Error - No matching column found:", field);
1332 Tabulator.prototype.toggleColumn =
function(field){
1333 var column = this.columnManager.findColumn(field);
1342 console.warn(
"Column Visibility Toggle Error - No matching column found:", field);
1347 Tabulator.prototype.addColumn =
function(definition, before, field){
1348 return new Promise((resolve, reject) => {
1349 var column = this.columnManager.findColumn(field);
1351 this.columnManager.addColumn(definition, before, column)
1353 resolve(column.getComponent());
1360 Tabulator.prototype.deleteColumn =
function(field){
1361 return new Promise((resolve, reject) => {
1362 var column = this.columnManager.findColumn(field);
1372 console.warn(
"Column Delete Error - No matching column found:", field);
1378 Tabulator.prototype.updateColumnDefinition =
function(field, definition){
1379 return new Promise((resolve, reject) => {
1380 var column = this.columnManager.findColumn(field);
1383 column.updateDefinition()
1390 console.warn(
"Column Update Error - No matching column found:", field);
1397 Tabulator.prototype.moveColumn =
function(from, to, after){
1398 var fromColumn = this.columnManager.findColumn(from);
1399 var toColumn = this.columnManager.findColumn(to);
1403 this.columnManager.moveColumn(fromColumn, toColumn, after)
1405 console.warn(
"Move Error - No matching column found:", toColumn);
1408 console.warn(
"Move Error - No matching column found:", from);
1413 Tabulator.prototype.scrollToColumn =
function(field, position, ifVisible){
1415 return new Promise((resolve, reject) => {
1416 var column = this.columnManager.findColumn(field);
1419 this.columnManager.scrollToColumn(column, position, ifVisible)
1427 console.warn(
"Scroll Error - No matching column found:", field);
1428 reject(
"Scroll Error - No matching column found");
1436 Tabulator.prototype.setLocale =
function(locale){
1437 this.modules.localize.setLocale(locale);
1440 Tabulator.prototype.getLocale =
function(){
1441 return this.modules.localize.getLocale();
1444 Tabulator.prototype.getLang =
function(locale){
1445 return this.modules.localize.getLang(locale);
1451 Tabulator.prototype.redraw =
function(force){
1452 this.columnManager.redraw(force);
1453 this.rowManager.redraw(force);
1456 Tabulator.prototype.setHeight =
function(height){
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();
1463 console.warn(
"setHeight function is not available in classic render mode");
1471 Tabulator.prototype.setSort =
function(sortList, dir){
1472 if(this.modExists(
"sort",
true)){
1473 this.modules.sort.setSort(sortList, dir);
1474 this.rowManager.sorterRefresh();
1478 Tabulator.prototype.getSorters =
function(){
1479 if(this.modExists(
"sort",
true)){
1480 return this.modules.sort.getSort();
1484 Tabulator.prototype.clearSort =
function(){
1485 if(this.modExists(
"sort",
true)){
1486 this.modules.sort.clear();
1487 this.rowManager.sorterRefresh();
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();
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();
1511 Tabulator.prototype.getFilters =
function(all){
1512 if(this.modExists(
"filter",
true)){
1513 return this.modules.filter.getFilters(all);
1517 Tabulator.prototype.setHeaderFilterFocus =
function(field){
1518 if(this.modExists(
"filter",
true)){
1519 var column = this.columnManager.findColumn(field);
1522 this.modules.filter.setHeaderFilterFocus(column);
1524 console.warn(
"Column Filter Focus Error - No matching column found:", field);
1531 Tabulator.prototype.setHeaderFilterValue =
function(field, value){
1532 if(this.modExists(
"filter",
true)){
1533 var column = this.columnManager.findColumn(field);
1536 this.modules.filter.setHeaderFilterValue(column, value);
1538 console.warn(
"Column Filter Error - No matching column found:", field);
1544 Tabulator.prototype.getHeaderFilters =
function(){
1545 if(this.modExists(
"filter",
true)){
1546 return this.modules.filter.getHeaderFilters();
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();
1560 Tabulator.prototype.clearFilter =
function(all){
1561 if(this.modExists(
"filter",
true)){
1562 this.modules.filter.clearFilter(all);
1563 this.rowManager.filterRefresh();
1568 Tabulator.prototype.clearHeaderFilter =
function(){
1569 if(this.modExists(
"filter",
true)){
1570 this.modules.filter.clearHeaderFilter();
1571 this.rowManager.filterRefresh();
1576 Tabulator.prototype.selectRow =
function(rows){
1577 if(this.modExists(
"selectRow",
true)){
1579 console.warn(
"passing a boolean to the selectRowselectRow function is deprecated, you should now pass the string 'active'");
1582 this.modules.selectRow.selectRows(rows);
1586 Tabulator.prototype.deselectRow =
function(rows){
1587 if(this.modExists(
"selectRow",
true)){
1588 this.modules.selectRow.deselectRows(rows);
1592 Tabulator.prototype.toggleSelectRow =
function(row){
1593 if(this.modExists(
"selectRow",
true)){
1594 this.modules.selectRow.toggleRow(row);
1598 Tabulator.prototype.getSelectedRows =
function(){
1599 if(this.modExists(
"selectRow",
true)){
1600 return this.modules.selectRow.getSelectedRows();
1604 Tabulator.prototype.getSelectedData =
function(){
1605 if(this.modExists(
"selectRow",
true)){
1606 return this.modules.selectRow.getSelectedData();
1612 Tabulator.prototype.setMaxPage =
function(max){
1613 if(this.options.pagination &&
this.modExists(
"page")){
1614 this.modules.page.setMaxPage(max);
1620 Tabulator.prototype.setPage =
function(page){
1621 if(this.options.pagination &&
this.modExists(
"page")){
1622 return this.modules.page.setPage(page);
1624 return new Promise((resolve, reject) => { reject() });
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);
1634 this.modules.page.setPageToRow(row)
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(()=>{});
1660 Tabulator.prototype.getPageSize =
function(){
1661 if(this.options.pagination &&
this.modExists(
"page",
true)){
1662 return this.modules.page.getPageSize();
1666 Tabulator.prototype.previousPage =
function(){
1667 if(this.options.pagination &&
this.modExists(
"page")){
1668 this.modules.page.previousPage();
1674 Tabulator.prototype.nextPage =
function(){
1675 if(this.options.pagination &&
this.modExists(
"page")){
1676 this.modules.page.nextPage();
1682 Tabulator.prototype.getPage =
function(){
1683 if(this.options.pagination &&
this.modExists(
"page")){
1684 return this.modules.page.getPage();
1690 Tabulator.prototype.getPageMax =
function(){
1691 if(this.options.pagination &&
this.modExists(
"page")){
1692 return this.modules.page.getPageMax();
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");
1706 if(this.options.persistence &&
this.modExists(
"persistence",
true) && this.modules.persistence.config.group){
1707 this.modules.persistence.save(
"group");
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");
1721 if(this.options.persistence &&
this.modExists(
"persistence",
true) && this.modules.persistence.config.group){
1722 this.modules.persistence.save(
"group");
1725 console.warn(
"Grouping Update - cant refresh view, no groups have been set");
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");
1739 if(this.options.persistence &&
this.modExists(
"persistence",
true) && this.modules.persistence.config.group){
1740 this.modules.persistence.save(
"group");
1743 console.warn(
"Grouping Update - cant refresh view, no groups have been set");
1750 Tabulator.prototype.getGroups =
function(values){
1751 if(this.modExists(
"groupRows",
true)){
1752 return this.modules.groupRows.getGroups(
true);
1759 Tabulator.prototype.getGroupedData =
function(){
1760 if (this.modExists(
"groupRows",
true)){
1761 return this.options.groupBy ?
1762 this.modules.groupRows.getGroupedData() : this.getData()
1767 Tabulator.prototype.getCalcResults =
function(){
1768 if(this.modExists(
"columnCalcs",
true)){
1769 return this.modules.columnCalcs.getResults();
1777 Tabulator.prototype.navigatePrev =
function(){
1780 if(this.modExists(
"edit",
true)){
1781 cell = this.modules.edit.currentCell;
1784 return cell.nav().prev();
1791 Tabulator.prototype.navigateNext =
function(){
1794 if(this.modExists(
"edit",
true)){
1795 cell = this.modules.edit.currentCell;
1798 return cell.nav().next();
1805 Tabulator.prototype.navigateLeft =
function(){
1808 if(this.modExists(
"edit",
true)){
1809 cell = this.modules.edit.currentCell;
1813 return cell.nav().left();
1820 Tabulator.prototype.navigateRight =
function(){
1823 if(this.modExists(
"edit",
true)){
1824 cell = this.modules.edit.currentCell;
1828 return cell.nav().right();
1835 Tabulator.prototype.navigateUp =
function(){
1838 if(this.modExists(
"edit",
true)){
1839 cell = this.modules.edit.currentCell;
1843 return cell.nav().up();
1850 Tabulator.prototype.navigateDown =
function(){
1853 if(this.modExists(
"edit",
true)){
1854 cell = this.modules.edit.currentCell;
1858 return cell.nav().down();
1867 Tabulator.prototype.undo =
function(){
1868 if(this.options.history &&
this.modExists(
"history",
true)){
1869 return this.modules.history.undo();
1875 Tabulator.prototype.redo =
function(){
1876 if(this.options.history &&
this.modExists(
"history",
true)){
1877 return this.modules.history.redo();
1883 Tabulator.prototype.getHistoryUndoSize =
function(){
1884 if(this.options.history &&
this.modExists(
"history",
true)){
1885 return this.modules.history.getHistoryUndoSize();
1891 Tabulator.prototype.getHistoryRedoSize =
function(){
1892 if(this.options.history &&
this.modExists(
"history",
true)){
1893 return this.modules.history.getHistoryRedoSize();
1901 Tabulator.prototype.download =
function(type, filename, options, active){
1902 if(this.modExists(
"download",
true)){
1903 this.modules.download.download(type, filename, options, active);
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);
1916 Tabulator.prototype.tableComms =
function(table, module, action, data){
1917 this.modules.comms.receive(table, module, action, data);
1923 Tabulator.prototype.moduleBindings = {};
1926 Tabulator.prototype.extendModule =
function(name, property, values){
1928 if(Tabulator.prototype.moduleBindings[name]){
1929 var source = Tabulator.prototype.moduleBindings[name].prototype[property];
1932 if(typeof values ==
"object"){
1933 for(let key in values){
1934 source[key] = values[key];
1937 console.warn(
"Module Error - Invalid value type, it must be an object");
1940 console.warn(
"Module Error - property does not exist:", property);
1943 console.warn(
"Module Error - module does not exist:", name);
1949 Tabulator.prototype.registerModule =
function(name, module){
1951 Tabulator.prototype.moduleBindings[name] = module;
1955 Tabulator.prototype.bindModules =
function(){
1958 for(var name in Tabulator.prototype.moduleBindings){
1959 this.modules[name] =
new Tabulator.prototype.moduleBindings[name](
this);
1964 Tabulator.prototype.modExists =
function(plugin, required){
1965 if(this.modules[plugin]){
1969 console.error(
"Tabulator Module Not Installed: " + plugin);
1976 Tabulator.prototype.helpers = {
1978 elVisible:
function(el){
1979 return !(el.offsetWidth <= 0 && el.offsetHeight <= 0);
1982 elOffset:
function(el){
1983 var box = el.getBoundingClientRect();
1986 top: box.top + window.pageYOffset - document.documentElement.clientTop,
1987 left: box.left + window.pageXOffset - document.documentElement.clientLeft
1991 deepClone:
function(obj){
1992 var clone = Array.isArray(obj) ? [] : {};
1995 if(obj[i] != null && typeof(obj[i]) ===
"object"){
1996 if (obj[i] instanceof Date) {
1997 clone[i] =
new Date(obj[i]);
1999 clone[i] = this.deepClone(obj[i]);
2010 Tabulator.prototype.comms = {
2012 register:
function(table){
2013 Tabulator.prototype.comms.tables.push(table);
2015 deregister:
function(table){
2016 var index = Tabulator.prototype.comms.tables.indexOf(table);
2019 Tabulator.prototype.comms.tables.splice(index, 1);
2022 lookupTable:
function(query, silent){
2026 if(typeof query ===
"string"){
2027 matches = document.querySelectorAll(query);
2030 for(var i = 0; i < matches.length; i++){
2031 match = Tabulator.prototype.comms.matchElement(matches[i]);
2034 results.push(match);
2039 }
else if((typeof HTMLElement !==
"undefined" && query instanceof HTMLElement) || query instanceof Tabulator){
2040 match = Tabulator.prototype.comms.matchElement(query);
2043 results.push(match);
2045 }
else if(Array.isArray(query)){
2046 query.forEach(
function(item){
2047 results = results.concat(Tabulator.prototype.comms.lookupTable(item));
2051 console.warn(
"Table Connection Error - Invalid Selector", query);
2057 matchElement:
function(element){
2058 return Tabulator.prototype.comms.tables.find(
function(table){
2059 return element instanceof Tabulator ? table === element : table.element === element;
2064 Tabulator.prototype.findTable =
function(query){
2065 var results = Tabulator.prototype.comms.lookupTable(query,
true);
2066 return Array.isArray(results) && !results.length ?
false : results;