UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

1,785 lines (1,422 loc) 62.2 kB
'use strict'; /*=include polyfills.js */ /*=include column_manager.js */ /*=include column.js */ /*=include row_manager.js */ /*=include vdom_hoz.js */ /*=include row.js */ /*=include cell.js */ /*=include footer_manager.js */ var Tabulator = function(element, options){ this.options = {}; this.columnManager = null; // hold Column Manager this.rowManager = null; //hold Row Manager this.footerManager = null; //holder Footer Manager this.vdomHoz = null; //holder horizontal virtual dom this.browser = ""; //hold current browser type this.browserSlow = false; //handle reduced functionality for slower browsers this.browserMobile = false; //check if running on moble, prevent resize cancelling edit on keyboard appearence this.rtl = false; //check if the table is in RTL mode this.modules = {}; //hold all modules bound to this table if(this.initializeElement(element)){ this.initializeOptions(options || {}); this._create(); } Tabulator.prototype.comms.register(this); //register table for inderdevice communication }; //default setup options Tabulator.prototype.defaultOptions = { height:false, //height of tabulator minHeight:false, //minimum height of tabulator maxHeight:false, //maximum height of tabulator layout:"fitData", ///layout type "fitColumns" | "fitData" layoutColumnsOnNewData:false, //update column widths on setData columnMinWidth:40, //minimum global width for a column columnMaxWidth:false, //minimum global width for a column columnHeaderVertAlign:"top", //vertical alignment of column headers columnVertAlign:false, // DEPRECATED - Left to allow warning resizableColumns:true, //resizable columns resizableRows:false, //resizable rows autoResize:true, //auto resize table columns:[],//store for colum header info cellHozAlign:"", //horizontal align columns cellVertAlign:"", //vertical align columns headerHozAlign:"", //horizontal header alignment data:[], //default starting data autoColumns:false, //build columns from data row structure autoColumnsDefinitions:false, reactiveData:false, //enable data reactivity nestedFieldSeparator:".", //seperatpr for nested data tooltips: false, //Tool tip value tooltipsHeader: false, //Tool tip for headers tooltipGenerationMode:"load", //when to generate tooltips initialSort:false, //initial sorting criteria initialFilter:false, //initial filtering criteria initialHeaderFilter:false, //initial header filtering criteria columnHeaderSortMulti: true, //multiple or single column sorting sortOrderReverse:false, //reverse internal sort ordering headerSort:true, //set default global header sort headerSortTristate:false, //set default tristate header sorting headerSortElement:"<div class='tabulator-arrow'></div>", //header sort element footerElement:false, //hold footer element index:"id", //filed for row index textDirection:"auto", keybindings:[], //array for keybindings tabEndNewRow:false, //create new row when tab to end of table invalidOptionWarnings:true, //allow toggling of invalid option warnings clipboard:false, //enable clipboard clipboardCopyStyled:true, //formatted table data clipboardCopyConfig:false, //clipboard config clipboardCopyFormatter:false, //DEPRICATED - REMOVE in 5.0 clipboardCopyRowRange:"active", //restrict clipboard to visible rows only clipboardPasteParser:"table", //convert pasted clipboard data to rows clipboardPasteAction:"insert", //how to insert pasted data into the table clipboardCopied:function(){}, //data has been copied to the clipboard clipboardPasted:function(){}, //data has been pasted into the table clipboardPasteError:function(){}, //data has not successfully been pasted into the table downloadDataFormatter:false, //function to manipulate table data before it is downloaded downloadReady:function(data, blob){return blob;}, //function to manipulate download data downloadComplete:false, //function to manipulate download data downloadConfig:{}, //download config downloadRowRange:"active", //restrict download to active rows only dataTree:false, //enable data tree dataTreeFilter:true, //filter child rows dataTreeSort:true, //sort child rows dataTreeElementColumn:false, dataTreeBranchElement: true, //show data tree branch element dataTreeChildIndent:9, //data tree child indent in px dataTreeChildField:"_children", //data tre column field to look for child rows dataTreeCollapseElement:false, //data tree row collapse element dataTreeExpandElement:false, //data tree row expand element dataTreeStartExpanded:false, dataTreeRowExpanded:function(){}, //row has been expanded dataTreeRowCollapsed:function(){}, //row has been collapsed dataTreeChildColumnCalcs:false, //include visible data tree rows in column calculations dataTreeSelectPropagate:false, //seleccting a parent row selects its children printAsHtml:false, //enable print as html printFormatter:false, //printing page formatter printHeader:false, //page header contents printFooter:false, //page footer contents printCopyStyle:true, //DEPRICATED - REMOVE in 5.0 printStyled:true, //enable print as html styling printVisibleRows:true, //DEPRICATED - REMOVE in 5.0 printRowRange:"visible", //restrict print to visible rows only printConfig:{}, //print config options addRowPos:"bottom", //position to insert blank rows, top|bottom selectable:"highlight", //highlight rows on hover selectableRangeMode: "drag", //highlight rows on hover selectableRollingSelection:true, //roll selection once maximum number of selectable rows is reached selectablePersistence:true, // maintain selection when table view is updated selectableCheck:function(data, row){return true;}, //check wheather row is selectable headerFilterLiveFilterDelay: 300, //delay before updating column after user types in header filter headerFilterPlaceholder: false, //placeholder text to display in header filters headerVisible:true, //hide header history:false, //enable edit history locale:false, //current system language langs:{}, virtualDom:true, //enable DOM virtualization virtualDomBuffer:0, // set virtual DOM buffer size virtualDomHoz:false, //enable horizontal DOM virtualization persistentLayout:false, //DEPRICATED - REMOVE in 5.0 persistentSort:false, //DEPRICATED - REMOVE in 5.0 persistentFilter:false, //DEPRICATED - REMOVE in 5.0 persistenceID:"", //key for persistent storage persistenceMode:true, //mode for storing persistence information persistenceReaderFunc:false, //function for handling persistence data reading persistenceWriterFunc:false, //function for handling persistence data writing persistence:false, responsiveLayout:false, //responsive layout flags responsiveLayoutCollapseStartOpen:true, //start showing collapsed data responsiveLayoutCollapseUseFormatters:true, //responsive layout collapse formatter responsiveLayoutCollapseFormatter:false, //responsive layout collapse formatter pagination:false, //set pagination type paginationSize:false, //set number of rows to a page paginationInitialPage:1, //initail page to show on load paginationButtonCount: 5, // set count of page button paginationSizeSelector:false, //add pagination size selector element paginationElement:false, //element to hold pagination numbers paginationDataSent:{}, //pagination data sent to the server paginationDataReceived:{}, //pagination data received from the server paginationAddRow: "page", //add rows on table or page ajaxURL:false, //url for ajax loading ajaxURLGenerator:false, ajaxParams:{}, //params for ajax loading ajaxConfig:"get", //ajax request type ajaxContentType:"form", //ajax request type ajaxRequestFunc:false, //promise function ajaxLoader:true, //show loader ajaxLoaderLoading:false, //loader element ajaxLoaderError:false, //loader element ajaxFiltering:false, ajaxSorting:false, ajaxProgressiveLoad:false, //progressive loading ajaxProgressiveLoadDelay:0, //delay between requests ajaxProgressiveLoadScrollMargin:0, //margin before scroll begins groupBy:false, //enable table grouping and set field to group by groupStartOpen:true, //starting state of group groupValues:false, groupUpdateOnCellEdit:false, groupHeader:false, //header generation function groupHeaderPrint:null, groupHeaderClipboard:null, groupHeaderHtmlOutput:null, groupHeaderDownload:null, htmlOutputConfig:false, //html outypu config movableColumns:false, //enable movable columns movableRows:false, //enable movable rows movableRowsConnectedTables:false, //tables for movable rows to be connected to movableRowsConnectedElements:false, //other elements for movable rows to be connected to movableRowsSender:false, movableRowsReceiver:"insert", movableRowsSendingStart:function(){}, movableRowsSent:function(){}, movableRowsSentFailed:function(){}, movableRowsSendingStop:function(){}, movableRowsReceivingStart:function(){}, movableRowsReceived:function(){}, movableRowsReceivedFailed:function(){}, movableRowsReceivingStop:function(){}, movableRowsElementDrop:function(){}, scrollToRowPosition:"top", scrollToRowIfVisible:true, scrollToColumnPosition:"left", scrollToColumnIfVisible:true, rowFormatter:false, rowFormatterPrint:null, rowFormatterClipboard:null, rowFormatterHtmlOutput:null, placeholder:false, //table building callbacks tableBuilding:function(){}, tableBuilt:function(){}, //render callbacks renderStarted:function(){}, renderComplete:function(){}, //row callbacks rowClick:false, rowDblClick:false, rowContext:false, rowTap:false, rowDblTap:false, rowTapHold:false, rowMouseEnter:false, rowMouseLeave:false, rowMouseOver:false, rowMouseOut:false, rowMouseMove:false, rowContextMenu:false, rowClickMenu:false, rowAdded:function(){}, rowDeleted:function(){}, rowMoved:function(){}, rowUpdated:function(){}, rowSelectionChanged:function(){}, rowSelected:function(){}, rowDeselected:function(){}, rowResized:function(){}, //cell callbacks //row callbacks cellClick:false, cellDblClick:false, cellContext:false, cellTap:false, cellDblTap:false, cellTapHold:false, cellMouseEnter:false, cellMouseLeave:false, cellMouseOver:false, cellMouseOut:false, cellMouseMove:false, cellEditing:function(){}, cellEdited:function(){}, cellEditCancelled:function(){}, //column callbacks columnMoved:false, columnResized:function(){}, columnTitleChanged:function(){}, columnVisibilityChanged:function(){}, //HTML iport callbacks htmlImporting:function(){}, htmlImported:function(){}, //data callbacks dataLoading:function(){}, dataLoaded:function(){}, dataEdited:false, //DEPRECATED dataChanged:false, //ajax callbacks ajaxRequesting:function(){}, ajaxResponse:false, ajaxError:function(){}, //filtering callbacks dataFiltering:false, dataFiltered:false, //sorting callbacks dataSorting:function(){}, dataSorted:function(){}, //grouping callbacks groupToggleElement:"arrow", groupClosedShowCalcs:false, dataGrouping:function(){}, dataGrouped:false, groupVisibilityChanged:function(){}, groupClick:false, groupDblClick:false, groupContext:false, groupContextMenu:false, groupClickMenu:false, groupTap:false, groupDblTap:false, groupTapHold:false, columnCalcs:true, //pagination callbacks pageLoaded:function(){}, //localization callbacks localized:function(){}, //validation callbacks validationMode:"blocking", validationFailed:function(){}, //history callbacks historyUndo:function(){}, historyRedo:function(){}, //scroll callbacks scrollHorizontal:function(){}, scrollVertical:function(){}, }; Tabulator.prototype.initializeOptions = function(options){ //warn user if option is not available if(options.invalidOptionWarnings !== false){ for (var key in options){ if(typeof this.defaultOptions[key] === "undefined"){ console.warn("Invalid table constructor option:", key) } } } //assign options to table for (var key in this.defaultOptions){ if(key in options){ this.options[key] = options[key]; }else{ if(Array.isArray(this.defaultOptions[key])){ this.options[key] = Object.assign([], this.defaultOptions[key]); }else if(typeof this.defaultOptions[key] === "object" && this.defaultOptions[key] !== null){ this.options[key] = Object.assign({}, this.defaultOptions[key]); }else{ this.options[key] = this.defaultOptions[key]; } } } }; Tabulator.prototype.initializeElement = function(element){ if(typeof HTMLElement !== "undefined" && element instanceof HTMLElement){ this.element = element; return true; }else if(typeof element === "string"){ this.element = document.querySelector(element); if(this.element){ return true; }else{ console.error("Tabulator Creation Error - no element found matching selector: ", element); return false; } }else{ console.error("Tabulator Creation Error - Invalid element provided:", element); return false; } }; Tabulator.prototype.rtlCheck = function(){ var style = window.getComputedStyle(this.element); switch(this.options.textDirection){ case"auto": if(style.direction !== "rtl"){ break; }; case "rtl": this.element.classList.add("tabulator-rtl"); this.rtl = true; break; case "ltr": this.element.classList.add("tabulator-ltr"); default: this.rtl = false; } }; //convert depricated functionality to new functions Tabulator.prototype._mapDepricatedFunctionality = function(){ //map depricated persistance setup options if(this.options.persistentLayout || this.options.persistentSort || this.options.persistentFilter){ if(!this.options.persistence){ this.options.persistence = {}; } } if(this.options.dataEdited){ console.warn("DEPRECATION WARNING - dataEdited option has been deprecated, please use the dataChanged option instead"); this.options.dataChanged = this.options.dataEdited; } if(this.options.downloadDataFormatter){ console.warn("DEPRECATION WARNING - downloadDataFormatter option has been deprecated"); } if(typeof this.options.clipboardCopyHeader !== "undefined"){ this.options.columnHeaders = this.options.clipboardCopyHeader; console.warn("DEPRECATION WARNING - clipboardCopyHeader option has been deprecated, please use the columnHeaders property on the clipboardCopyConfig option"); } if(this.options.printVisibleRows !== true){ console.warn("printVisibleRows option is deprecated, you should now use the printRowRange option"); this.options.persistence.printRowRange = "active"; } if(this.options.printCopyStyle !== true){ console.warn("printCopyStyle option is deprecated, you should now use the printStyled option"); this.options.persistence.printStyled = this.options.printCopyStyle; } if(this.options.persistentLayout){ console.warn("persistentLayout option is deprecated, you should now use the persistence option"); if(this.options.persistence !== true && typeof this.options.persistence.columns === "undefined"){ this.options.persistence.columns = true; } } if(this.options.persistentSort){ console.warn("persistentSort option is deprecated, you should now use the persistence option"); if(this.options.persistence !== true && typeof this.options.persistence.sort === "undefined"){ this.options.persistence.sort = true; } } if(this.options.persistentFilter){ console.warn("persistentFilter option is deprecated, you should now use the persistence option"); if(this.options.persistence !== true && typeof this.options.persistence.filter === "undefined"){ this.options.persistence.filter = true; } } if(this.options.columnVertAlign){ console.warn("columnVertAlign option is deprecated, you should now use the columnHeaderVertAlign option"); this.options.columnHeaderVertAlign = this.options.columnVertAlign; } }; Tabulator.prototype._clearSelection = function(){ this.element.classList.add("tabulator-block-select"); if (window.getSelection) { if (window.getSelection().empty) { // Chrome window.getSelection().empty(); } else if (window.getSelection().removeAllRanges) { // Firefox window.getSelection().removeAllRanges(); } } else if (document.selection) { // IE? document.selection.empty(); } this.element.classList.remove("tabulator-block-select"); }; //concreate table Tabulator.prototype._create = function(){ this._clearObjectPointers(); this._mapDepricatedFunctionality(); this.bindModules(); this.rtlCheck(); if(this.element.tagName === "TABLE"){ if(this.modExists("htmlTableImport", true)){ this.modules.htmlTableImport.parseTable(); } } this.columnManager = new ColumnManager(this); this.rowManager = new RowManager(this); this.footerManager = new FooterManager(this); this.columnManager.setRowManager(this.rowManager); this.rowManager.setColumnManager(this.columnManager); if(this.options.virtualDomHoz){ this.vdomHoz = new VDomHoz(this); } this._buildElement(); this._loadInitialData(); }; //clear pointers to objects in default config object Tabulator.prototype._clearObjectPointers = function(){ this.options.columns = this.options.columns.slice(0); if(!this.options.reactiveData){ this.options.data = this.options.data.slice(0); } }; //build tabulator element Tabulator.prototype._buildElement = function(){ var element = this.element, mod = this.modules, options = this.options; options.tableBuilding.call(this); element.classList.add("tabulator"); element.setAttribute("role", "grid"); //empty element while(element.firstChild) element.removeChild(element.firstChild); //set table height if(options.height){ options.height = isNaN(options.height) ? options.height : options.height + "px"; element.style.height = options.height; } //set table min height if(options.minHeight !== false){ options.minHeight = isNaN(options.minHeight) ? options.minHeight : options.minHeight + "px"; element.style.minHeight = options.minHeight; } //set table maxHeight if(options.maxHeight !== false){ options.maxHeight = isNaN(options.maxHeight) ? options.maxHeight : options.maxHeight + "px"; element.style.maxHeight = options.maxHeight; } this.columnManager.initialize(); this.rowManager.initialize(); this._detectBrowser(); if(this.modExists("layout", true)){ mod.layout.initialize(options.layout); } //set localization mod.localize.initialize(); if(options.headerFilterPlaceholder !== false){ mod.localize.setHeaderFilterPlaceholder(options.headerFilterPlaceholder); } for(let locale in options.langs){ mod.localize.installLang(locale, options.langs[locale]); } mod.localize.setLocale(options.locale); //configure placeholder element if(typeof options.placeholder == "string"){ var el = document.createElement("div"); el.classList.add("tabulator-placeholder"); var span = document.createElement("span"); span.innerHTML = options.placeholder; el.appendChild(span); options.placeholder = el; } //build table elements element.appendChild(this.columnManager.getElement()); element.appendChild(this.rowManager.getElement()); if(options.footerElement){ this.footerManager.activate(); } if(options.persistence && this.modExists("persistence", true)){ mod.persistence.initialize(); } if(options.movableRows && this.modExists("moveRow")){ mod.moveRow.initialize(); } if(options.autoColumns && this.options.data){ this.columnManager.generateColumnsFromRowData(this.options.data); } if(this.modExists("columnCalcs")){ mod.columnCalcs.initialize(); } this.columnManager.setColumns(options.columns); if(options.dataTree && this.modExists("dataTree", true)){ mod.dataTree.initialize(); } if(this.modExists("frozenRows")){ this.modules.frozenRows.initialize(); } if(((options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort) || options.initialSort) && this.modExists("sort", true)){ var sorters = []; if(options.persistence && this.modExists("persistence", true) && mod.persistence.config.sort){ sorters = mod.persistence.load("sort"); if(sorters === false && options.initialSort){ sorters = options.initialSort; } }else if(options.initialSort){ sorters = options.initialSort; } mod.sort.setSort(sorters); } if(((options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter) || options.initialFilter) && this.modExists("filter", true)){ var filters = []; if(options.persistence && this.modExists("persistence", true) && mod.persistence.config.filter){ filters = mod.persistence.load("filter"); if(filters === false && options.initialFilter){ filters = options.initialFilter; } }else if(options.initialFilter){ filters = options.initialFilter; } mod.filter.setFilter(filters); } if(options.initialHeaderFilter && this.modExists("filter", true)){ options.initialHeaderFilter.forEach((item) => { var column = this.columnManager.findColumn(item.field); if(column){ mod.filter.setHeaderFilterValue(column, item.value); }else{ console.warn("Column Filter Error - No matching column found:", item.field); return false; } }); } if(this.modExists("ajax")){ mod.ajax.initialize(); } if(options.pagination && this.modExists("page", true)){ mod.page.initialize(); } if(options.groupBy && this.modExists("groupRows", true)){ mod.groupRows.initialize(); } if(this.modExists("keybindings")){ mod.keybindings.initialize(); } if(this.modExists("selectRow")){ mod.selectRow.clearSelectionData(true); } if(options.autoResize && this.modExists("resizeTable")){ mod.resizeTable.initialize(); } if(this.modExists("clipboard")){ mod.clipboard.initialize(); } if(options.printAsHtml && this.modExists("print")){ mod.print.initialize(); } options.tableBuilt.call(this); }; Tabulator.prototype._loadInitialData = function(){ var self = this; if(self.options.pagination && self.modExists("page")){ self.modules.page.reset(true, true); if(self.options.pagination == "local"){ if(self.options.data.length){ self.rowManager.setData(self.options.data, false, true); }else{ if((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")){ self.modules.ajax.loadData(false, true).then(()=>{}).catch(()=>{ if(self.options.paginationInitialPage){ self.modules.page.setPage(self.options.paginationInitialPage); } }); return; }else{ self.rowManager.setData(self.options.data, false, true); } } if(self.options.paginationInitialPage){ self.modules.page.setPage(self.options.paginationInitialPage); } }else{ if(self.options.ajaxURL){ self.modules.page.setPage(self.options.paginationInitialPage).then(()=>{}).catch(()=>{}); }else{ self.rowManager.setData([], false, true); } } }else{ if(self.options.data.length){ self.rowManager.setData(self.options.data); }else{ if((self.options.ajaxURL || self.options.ajaxURLGenerator) && self.modExists("ajax")){ self.modules.ajax.loadData(false, true).then(()=>{}).catch(()=>{}); }else{ self.rowManager.setData(self.options.data, false, true); } } } }; //deconstructor Tabulator.prototype.destroy = function(){ var element = this.element; Tabulator.prototype.comms.deregister(this); //deregister table from inderdevice communication if(this.options.reactiveData && this.modExists("reactiveData", true)){ this.modules.reactiveData.unwatchData(); } //clear row data this.rowManager.rows.forEach(function(row){ row.wipe(); }); this.rowManager.rows = []; this.rowManager.activeRows = []; this.rowManager.displayRows = []; //clear event bindings if(this.options.autoResize && this.modExists("resizeTable")){ this.modules.resizeTable.clearBindings(); } if(this.modExists("keybindings")){ this.modules.keybindings.clearBindings(); } //clear DOM while(element.firstChild) element.removeChild(element.firstChild); element.classList.remove("tabulator"); }; Tabulator.prototype._detectBrowser = function(){ var ua = navigator.userAgent||navigator.vendor||window.opera; if(ua.indexOf("Trident") > -1){ this.browser = "ie"; this.browserSlow = true; }else if(ua.indexOf("Edge") > -1){ this.browser = "edge"; this.browserSlow = true; }else if(ua.indexOf("Firefox") > -1){ this.browser = "firefox"; this.browserSlow = false; }else{ this.browser = "other"; this.browserSlow = false; } 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)); }; ////////////////// Data Handling ////////////////// //block table redrawing Tabulator.prototype.blockRedraw = function(){ return this.rowManager.blockRedraw(); }; //restore table redrawing Tabulator.prototype.restoreRedraw = function(){ return this.rowManager.restoreRedraw(); }; //local data from local file Tabulator.prototype.setDataFromLocalFile = function(extensions){ return new Promise((resolve, reject) => { var input = document.createElement("input"); input.type = "file"; input.accept = extensions || ".json,application/json"; input.addEventListener("change", (e) => { var file = input.files[0], reader = new FileReader(), data; reader.readAsText(file); reader.onload = (e) => { try { data = JSON.parse(reader.result); } catch(e) { console.warn("File Load Error - File contents is invalid JSON", e); reject(e); return; } this.setData(data) .then((data) => { resolve(data); }) .catch((err) => { resolve(err); }); }; reader.onerror = (e) => { console.warn("File Load Error - Unable to read file"); reject(); }; }); input.click(); }); }; //load data Tabulator.prototype.setData = function(data, params, config){ if(this.modExists("ajax")){ this.modules.ajax.blockActiveRequest(); } return this._setData(data, params, config, false, true); }; Tabulator.prototype._setData = function(data, params, config, inPosition, columnsChanged){ var self = this; if(typeof(data) === "string"){ if (data.indexOf("{") == 0 || data.indexOf("[") == 0){ //data is a json encoded string return self.rowManager.setData(JSON.parse(data), inPosition, columnsChanged); }else{ if(self.modExists("ajax", true)){ if(params){ self.modules.ajax.setParams(params); } if(config){ self.modules.ajax.setConfig(config); } self.modules.ajax.setUrl(data); if(self.options.pagination == "remote" && self.modExists("page", true)){ self.modules.page.reset(true, true); return self.modules.page.setPage(1); }else{ //assume data is url, make ajax call to url to get data return self.modules.ajax.loadData(inPosition, columnsChanged); } } } }else{ if(data){ //asume data is already an object return self.rowManager.setData(data, inPosition, columnsChanged); }else{ //no data provided, check if ajaxURL is present; if(self.modExists("ajax") && (self.modules.ajax.getUrl || self.options.ajaxURLGenerator)){ if(self.options.pagination == "remote" && self.modExists("page", true)){ self.modules.page.reset(true, true); return self.modules.page.setPage(1); }else{ return self.modules.ajax.loadData(inPosition, columnsChanged); } }else{ //empty data return self.rowManager.setData([], inPosition, columnsChanged); } } } }; //clear data Tabulator.prototype.clearData = function(){ if(this.modExists("ajax")){ this.modules.ajax.blockActiveRequest(); } this.rowManager.clearData(); }; //get table data array Tabulator.prototype.getData = function(active){ if(active === true){ console.warn("passing a boolean to the getData function is deprecated, you should now pass the string 'active'"); active = "active"; } return this.rowManager.getData(active); }; //get table data array count Tabulator.prototype.getDataCount = function(active){ if(active === true){ console.warn("passing a boolean to the getDataCount function is deprecated, you should now pass the string 'active'"); active = "active"; } return this.rowManager.getDataCount(active); }; //search for specific row components Tabulator.prototype.searchRows = function(field, type, value){ if(this.modExists("filter", true)){ return this.modules.filter.search("rows", field, type, value); } }; //search for specific data Tabulator.prototype.searchData = function(field, type, value){ if(this.modExists("filter", true)){ return this.modules.filter.search("data", field, type, value); } }; //get table html Tabulator.prototype.getHtml = function(visible, style, config){ if(this.modExists("export", true)){ return this.modules.export.getHtml(visible, style, config); } }; //get print html Tabulator.prototype.print = function(visible, style, config){ if(this.modExists("print", true)){ return this.modules.print.printFullscreen(visible, style, config); } }; //retrieve Ajax URL Tabulator.prototype.getAjaxUrl = function(){ if(this.modExists("ajax", true)){ return this.modules.ajax.getUrl(); } }; //replace data, keeping table in position with same sort Tabulator.prototype.replaceData = function(data, params, config){ if(this.modExists("ajax")){ this.modules.ajax.blockActiveRequest(); } return this._setData(data, params, config, true); }; //update table data Tabulator.prototype.updateData = function(data){ var self = this; var responses = 0; return new Promise((resolve, reject) => { if(this.modExists("ajax")){ this.modules.ajax.blockActiveRequest(); } if(typeof data === "string"){ data = JSON.parse(data); } if(data){ data.forEach(function(item){ var row = self.rowManager.findRow(item[self.options.index]); if(row){ responses++; row.updateData(item) .then(()=>{ responses--; if(!responses){ resolve(); } }); } }); }else{ console.warn("Update Error - No data provided"); reject("Update Error - No data provided"); } }); }; Tabulator.prototype.addData = function(data, pos, index){ return new Promise((resolve, reject) => { if(this.modExists("ajax")){ this.modules.ajax.blockActiveRequest(); } if(typeof data === "string"){ data = JSON.parse(data); } if(data){ this.rowManager.addRows(data, pos, index) .then((rows) => { var output = []; rows.forEach(function(row){ output.push(row.getComponent()); }); resolve(output); }); }else{ console.warn("Update Error - No data provided"); reject("Update Error - No data provided"); } }); }; //update table data Tabulator.prototype.updateOrAddData = function(data){ var self = this, rows = [], responses = 0; return new Promise((resolve, reject) => { if(this.modExists("ajax")){ this.modules.ajax.blockActiveRequest(); } if(typeof data === "string"){ data = JSON.parse(data); } if(data){ data.forEach(function(item){ var row = self.rowManager.findRow(item[self.options.index]); responses++; if(row){ row.updateData(item) .then(()=>{ responses--; rows.push(row.getComponent()); if(!responses){ resolve(rows); } }); }else{ self.rowManager.addRows(item) .then((newRows)=>{ responses--; rows.push(newRows[0].getComponent()); if(!responses){ resolve(rows); } }); } }); }else{ console.warn("Update Error - No data provided"); reject("Update Error - No data provided"); } }); }; //get row object Tabulator.prototype.getRow = function(index){ var row = this.rowManager.findRow(index); if(row){ return row.getComponent(); }else{ console.warn("Find Error - No matching row found:", index); return false; } }; //get row object Tabulator.prototype.getRowFromPosition = function(position, active){ var row = this.rowManager.getRowFromPosition(position, active); if(row){ return row.getComponent(); }else{ console.warn("Find Error - No matching row found:", position); return false; } }; //delete row from table Tabulator.prototype.deleteRow = function(index){ return new Promise((resolve, reject) => { var self = this, count = 0, successCount = 0, foundRows = []; function doneCheck(){ count++; if(count == index.length){ if(successCount){ self.rowManager.reRenderInPosition(); resolve(); } } } if(!Array.isArray(index)){ index = [index]; } //find matching rows index.forEach((item) =>{ var row = this.rowManager.findRow(item, true); if(row){ foundRows.push(row); }else{ console.warn("Delete Error - No matching row found:", item); reject("Delete Error - No matching row found") doneCheck(); } }); //sort rows into correct order to ensure smooth delete from table foundRows.sort((a, b) => { return this.rowManager.rows.indexOf(a) > this.rowManager.rows.indexOf(b) ? 1 : -1; }); foundRows.forEach((row) =>{ row.delete() .then(() => { successCount++; doneCheck(); }) .catch((err) => { doneCheck(); reject(err); }); }); }); }; //add row to table Tabulator.prototype.addRow = function(data, pos, index){ return new Promise((resolve, reject) => { if(typeof data === "string"){ data = JSON.parse(data); } this.rowManager.addRows(data, pos, index) .then((rows)=>{ //recalc column calculations if present if(this.modExists("columnCalcs")){ this.modules.columnCalcs.recalc(this.rowManager.activeRows); } resolve(rows[0].getComponent()); }); }); }; //update a row if it exitsts otherwise create it Tabulator.prototype.updateOrAddRow = function(index, data){ return new Promise((resolve, reject) => { var row = this.rowManager.findRow(index); if(typeof data === "string"){ data = JSON.parse(data); } if(row){ row.updateData(data) .then(()=>{ //recalc column calculations if present if(this.modExists("columnCalcs")){ this.modules.columnCalcs.recalc(this.rowManager.activeRows); } resolve(row.getComponent()); }) .catch((err)=>{ reject(err); }); }else{ row = this.rowManager.addRows(data) .then((rows)=>{ //recalc column calculations if present if(this.modExists("columnCalcs")){ this.modules.columnCalcs.recalc(this.rowManager.activeRows); } resolve(rows[0].getComponent()); }) .catch((err)=>{ reject(err); }); } }); }; //update row data Tabulator.prototype.updateRow = function(index, data){ return new Promise((resolve, reject) => { var row = this.rowManager.findRow(index); if(typeof data === "string"){ data = JSON.parse(data); } if(row){ row.updateData(data).then(()=>{ resolve(row.getComponent()); }) .catch((err)=>{ reject(err); }); }else{ console.warn("Update Error - No matching row found:", index); reject("Update Error - No matching row found"); } }); }; //scroll to row in DOM Tabulator.prototype.scrollToRow = function(index, position, ifVisible){ return new Promise((resolve, reject) => { var row = this.rowManager.findRow(index); if(row){ this.rowManager.scrollToRow(row, position, ifVisible) .then(()=>{ resolve(); }) .catch((err)=>{ reject(err); }); }else{ console.warn("Scroll Error - No matching row found:", index); reject("Scroll Error - No matching row found"); } }); }; Tabulator.prototype.moveRow = function(from, to, after){ var fromRow = this.rowManager.findRow(from); if(fromRow){ fromRow.moveToRow(to, after); }else{ console.warn("Move Error - No matching row found:", from); } }; Tabulator.prototype.getRows = function(active){ if(active === true){ console.warn("passing a boolean to the getRows function is deprecated, you should now pass the string 'active'"); active = "active"; } return this.rowManager.getComponents(active); }; //get position of row in table Tabulator.prototype.getRowPosition = function(index, active){ var row = this.rowManager.findRow(index); if(row){ return this.rowManager.getRowPosition(row, active); }else{ console.warn("Position Error - No matching row found:", index); return false; } }; //copy table data to clipboard Tabulator.prototype.copyToClipboard = function(selector){ if(this.modExists("clipboard", true)){ this.modules.clipboard.copy(selector); } }; /////////////// Column Functions /////////////// Tabulator.prototype.setColumns = function(definition){ this.columnManager.setColumns(definition); }; Tabulator.prototype.getColumns = function(structured){ return this.columnManager.getComponents(structured); }; Tabulator.prototype.getColumn = function(field){ var col = this.columnManager.findColumn(field); if(col){ return col.getComponent(); }else{ console.warn("Find Error - No matching column found:", field); return false; } }; Tabulator.prototype.getColumnDefinitions = function(){ return this.columnManager.getDefinitionTree(); }; Tabulator.prototype.getColumnLayout = function(){ if(this.modExists("persistence", true)){ return this.modules.persistence.parseColumns(this.columnManager.getColumns()); } }; Tabulator.prototype.setColumnLayout = function(layout){ if(this.modExists("persistence", true)){ this.columnManager.setColumns(this.modules.persistence.mergeDefinition(this.options.columns, layout)) return true; } return false; }; Tabulator.prototype.showColumn = function(field){ var column = this.columnManager.findColumn(field); if(column){ column.show(); if(this.options.responsiveLayout && this.modExists("responsiveLayout", true)){ this.modules.responsiveLayout.update(); } }else{ console.warn("Column Show Error - No matching column found:", field); return false; } }; Tabulator.prototype.hideColumn = function(field){ var column = this.columnManager.findColumn(field); if(column){ column.hide(); if(this.options.responsiveLayout && this.modExists("responsiveLayout", true)){ this.modules.responsiveLayout.update(); } }else{ console.warn("Column Hide Error - No matching column found:", field); return false; } }; Tabulator.prototype.toggleColumn = function(field){ var column = this.columnManager.findColumn(field); if(column){ if(column.visible){ column.hide(); }else{ column.show(); } }else{ console.warn("Column Visibility Toggle Error - No matching column found:", field); return false; } }; Tabulator.prototype.addColumn = function(definition, before, field){ return new Promise((resolve, reject) => { var column = this.columnManager.findColumn(field); this.columnManager.addColumn(definition, before, column) .then((column) => { resolve(column.getComponent()); }).catch((err) => { reject(err); }); }); }; Tabulator.prototype.deleteColumn = function(field){ return new Promise((resolve, reject) => { var column = this.columnManager.findColumn(field); if(column){ column.delete() .then(() => { resolve(); }).catch((err) => { reject(err); }); }else{ console.warn("Column Delete Error - No matching column found:", field); reject(); } }); }; Tabulator.prototype.updateColumnDefinition = function(field, definition){ return new Promise((resolve, reject) => { var column = this.columnManager.findColumn(field); if(column){ column.updateDefinition(definition) .then((col) => { resolve(col); }).catch((err) => { reject(err); }); }else{ console.warn("Column Update Error - No matching column found:", field); reject(); } }); }; Tabulator.prototype.moveColumn = function(from, to, after){ var fromColumn = this.columnManager.findColumn(from); var toColumn = this.columnManager.findColumn(to); if(fromColumn){ if(toColumn){ this.columnManager.moveColumn(fromColumn, toColumn, after) }else{ console.warn("Move Error - No matching column found:", toColumn); } }else{ console.warn("Move Error - No matching column found:", from); } }; //scroll to column in DOM Tabulator.prototype.scrollToColumn = function(field, position, ifVisible){ return new Promise((resolve, reject) => { var column = this.columnManager.findColumn(field); if(column){ this.columnManager.scrollToColumn(column, position, ifVisible) .then(()=>{ resolve(); }) .catch((err)=>{ reject(err); }); }else{ console.warn("Scroll Error - No matching column found:", field); reject("Scroll Error - No matching column found"); } }); }; //////////// Localization Functions //////////// Tabulator.prototype.setLocale = function(locale){ this.modules.localize.setLocale(locale); }; Tabulator.prototype.getLocale = function(){ return this.modules.localize.getLocale(); }; Tabulator.prototype.getLang = function(locale){ return this.modules.localize.getLang(locale); }; //////////// General Public Functions //////////// //redraw list without updating data Tabulator.prototype.redraw = function(force){ this.columnManager.redraw(force); this.rowManager.redraw(force); }; Tabulator.prototype.setHeight = function(height){ if(this.rowManager.renderMode !== "classic"){ this.options.height = isNaN(height) ? height : height + "px"; this.element.style.height = this.options.height; this.rowManager.setRenderMode(); this.rowManager.redraw(); }else{ console.warn("setHeight function is not available in classic render mode"); } }; ///////////////////// Sorting //////////////////// //trigger sort Tabulator.prototype.setSort = function(sortList, dir){ if(this.modExists("sort", true)){ this.modules.sort.setSort(sortList, dir); this.rowManager.sorterRefresh(); } }; Tabulator.prototype.getSorters = function(){ if(this.modExists("sort", true)){ return this.modules.sort.getSort(); } }; Tabulator.prototype.clearSort = function(){ if(this.modExists("sort", true)){ this.modules.sort.clear(); this.rowManager.sorterRefresh(); } }; ///////////////////// Filtering //////////////////// //set standard filters Tabulator.prototype.setFilter = function(field, type, value, params){ if(this.modExists("filter", true)){ this.modules.filter.setFilter(field, type, value, params); this.rowManager.filterRefresh(); } }; //set standard filters Tabulator.prototype.refreshFilter = function(){ if(this.modExists("filter", true)){ this.rowManager.filterRefresh(); } }; //add filter to array Tabulator.prototype.addFilter = function(field, type, value, params){ if(this.modExists("filter", true)){ this.modules.filter.addFilter(field, type, value, params); this.rowManager.filterRefresh(); } }; //get all filters Tabulator.prototype.getFilters = function(all){ if(this.modExists("filter", true)){ return this.modules.filter.getFilters(all); } }; Tabulator.prototype.setHeaderFilterFocus = function(field){ if(this.modExists("filter", true)){ var column = this.columnManager.findColumn(field); if(column){ this.modules.filter.setHeaderFilterFocus(column); }else{ console.warn("Column Filter Focus Error - No matching column found:", field); return false; } } }; Tabulator.prototype.getHeaderFilterValue = function(field) { if(this.modExists("filter", true)){ var column = this.columnManager.findColumn(field); if(column){ return this.modules.filter.getHeaderFilterValue(column); }else{ console.warn("Column Filter Error - No matching column found:", field); } } }; Tabulator.prototype.setHeaderFilterValue = function(field, value){ if(this.modExists("filter", true)){ var column = this.columnManager.findColumn(field); if(column){ this.modules.filter.setHeaderFilterValue(column, value); }else{ console.warn("Column Filter Error - No matching column found:", field); return false; } } }; Tabulator.prototype.getHeaderFilters = function(){ if(this.modExists("filter", true)){ return this.modules.filter.getHeaderFilters(); } }; //remove filter from array Tabulator.prototype.removeFilter = function(field, type, value){ if(this.modExists("filter", true)){ this.modules.filter.removeFilter(field, type, value); this.rowManager.filterRefresh(); } }; //clear filters Tabulator.prototype.clearFilter = function(all){ if(this.modExists("filter", true)){ this.modules.filter.clearFilter(all); this.rowManager.filterRefresh(); } }; //clear header filters Tabulator.prototype.clearHeaderFilter = function(){ if(this.modExists("filter", true)){ this.modules.filter.clearHeaderFilter(); this.rowManager.filterRefresh(); } }; ///////////////////// select //////////////////// Tabulator.prototype.selectRow = function(rows){ if(this.modExists("selectRow", true)){ if(rows === true){ console.warn("passing a boolean to the selectRowselectRow function is deprecated, you should now pass the string 'active'"); rows = "active"; } this.modules.selectRow.selectRows(rows); } }; Tabulator.prototype.deselectRow = function(rows){ if(this.modExists("selectRow", true)){ this.modules.selectRow.deselectRows(rows); } }; Tabulator.prototype.toggleSelectRow = function(row){ if(this.modExists("selectRow", true)){ this.modules.selectRow.toggleRow(row); } }; Tabulator.prototype.getSelectedRows = function(){ if(this.modExists("selectRow", true)){ return this.modules.selectRow.getSelectedRows(); } }; Tabulator.prototype.getSelectedData = function(){ if(this.modExists("selectRow", true)){ return this.modules.selectRow.getSelectedData(); } }; ///////////////////// validation //////////////////// Tabulator.prototype.getInvalidCells = function(){ if(this.modExists("validate", true)){ return this.modules.validate.getInvalidCells(); } }; Tabulator.prototype.clearCellValidation = function(cells){ if(this.modExists("validate", true)){ if(!cells){ cells = this.modules.validate.getInvalidCells(); } if(!Array.isArray(cells)){ cells = [cells]; } cells.forEach((cell) => { this.modules.validate.clearValidation(cell._getSelf()); }); } }; Tabulator.prototype.validate = function(cells){ var output = []; //clear row data this.rowManager.rows.forEach(function(row){ var valid = row.validate(); if(valid !== true){ output = output.concat(valid); } }); return output.length ? output : true; } //////////// Pagination Functions //