UNPKG

bootstrap-table

Version:

An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)

630 lines (549 loc) 20.7 kB
/** * @author: Dennis Hernández * @update zhixin wen <wenzhixin2010@gmail.com> */ const Utils = $.fn.bootstrapTable.utils const UtilsCookie = { cookieIds: { sortOrder: 'bs.table.sortOrder', sortName: 'bs.table.sortName', sortPriority: 'bs.table.sortPriority', pageNumber: 'bs.table.pageNumber', pageList: 'bs.table.pageList', columns: 'bs.table.columns', hiddenColumns: 'bs.table.hiddenColumns', cardView: 'bs.table.cardView', searchText: 'bs.table.searchText', reorderColumns: 'bs.table.reorderColumns', filterControl: 'bs.table.filterControl', filterBy: 'bs.table.filterBy' }, getCurrentHeader (that) { return that.options.height ? that.$tableHeader : that.$header }, getCurrentSearchControls (that) { return that.options.height ? 'table select, table input' : 'select, input' }, isCookieSupportedByBrowser () { return navigator.cookieEnabled }, isCookieEnabled (that, cookieName) { return that.options.cookiesEnabled.includes(cookieName) }, setCookie (that, cookieName, cookieValue) { if ( !that.options.cookie || !UtilsCookie.isCookieEnabled(that, cookieName) ) { return } return that._storage.setItem(`${that.options.cookieIdTable}.${cookieName}`, cookieValue) }, getCookie (that, cookieName) { if ( !cookieName || !UtilsCookie.isCookieEnabled(that, cookieName) ) { return null } return that._storage.getItem(`${that.options.cookieIdTable}.${cookieName}`) }, deleteCookie (that, cookieName) { return that._storage.removeItem(`${that.options.cookieIdTable}.${cookieName}`) }, calculateExpiration (cookieExpire) { const time = cookieExpire.replace(/[0-9]*/, '') // s,mi,h,d,m,y cookieExpire = cookieExpire.replace(/[A-Za-z]{1,2}/, '') // number switch (time.toLowerCase()) { case 's': cookieExpire = +cookieExpire break case 'mi': cookieExpire *= 60 break case 'h': cookieExpire = cookieExpire * 60 * 60 break case 'd': cookieExpire = cookieExpire * 24 * 60 * 60 break case 'm': cookieExpire = cookieExpire * 30 * 24 * 60 * 60 break case 'y': cookieExpire = cookieExpire * 365 * 24 * 60 * 60 break default: cookieExpire = undefined break } if (!cookieExpire) { return '' } const d = new Date() d.setTime(d.getTime() + cookieExpire * 1000) return d.toGMTString() }, initCookieFilters (bootstrapTable) { setTimeout(() => { const parsedCookieFilters = JSON.parse( UtilsCookie.getCookie(bootstrapTable, UtilsCookie.cookieIds.filterControl)) if (!bootstrapTable._filterControlValuesLoaded && parsedCookieFilters) { const cachedFilters = {} const header = UtilsCookie.getCurrentHeader(bootstrapTable) const searchControls = UtilsCookie.getCurrentSearchControls(bootstrapTable) const applyCookieFilters = (element, filteredCookies) => { filteredCookies.forEach(cookie => { const value = element.value.toString() const text = cookie.text if ( text === '' || element.type === 'radio' && value !== text ) { return } if ( element.tagName === 'INPUT' && element.type === 'radio' && value === text ) { element.checked = true cachedFilters[cookie.field] = text } else if (element.tagName === 'INPUT') { element.value = text cachedFilters[cookie.field] = text } else if ( element.tagName === 'SELECT' && bootstrapTable.options.filterControlContainer ) { element.value = text cachedFilters[cookie.field] = text } else if (text !== '' && element.tagName === 'SELECT') { cachedFilters[cookie.field] = text for (const currentElement of element) { if (currentElement.value === text) { currentElement.selected = true return } } const option = document.createElement('option') option.value = text option.text = text element.add(option, element[1]) element.selectedIndex = 1 } }) } let filterContainer = header if (bootstrapTable.options.filterControlContainer) { filterContainer = $(`${bootstrapTable.options.filterControlContainer}`) } filterContainer.find(searchControls).each(function () { const field = $(this).closest('[data-field]').data('field') const filteredCookies = parsedCookieFilters.filter(cookie => cookie.field === field) applyCookieFilters(this, filteredCookies) }) bootstrapTable.initColumnSearch(cachedFilters) bootstrapTable._filterControlValuesLoaded = true bootstrapTable.initServer() } }, 250) } } $.extend($.fn.bootstrapTable.defaults, { cookie: false, cookieExpire: '2h', cookiePath: null, cookieDomain: null, cookieSecure: null, cookieSameSite: 'Lax', cookieIdTable: '', cookiesEnabled: [ 'bs.table.sortOrder', 'bs.table.sortName', 'bs.table.sortPriority', 'bs.table.pageNumber', 'bs.table.pageList', 'bs.table.hiddenColumns', 'bs.table.columns', 'bs.table.searchText', 'bs.table.filterControl', 'bs.table.filterBy', 'bs.table.reorderColumns', 'bs.table.cardView' ], cookieStorage: 'cookieStorage', // localStorage, sessionStorage, customStorage cookieCustomStorageGet: null, cookieCustomStorageSet: null, cookieCustomStorageDelete: null, // internal variable _filterControls: [], _filterControlValuesLoaded: false, _storage: { setItem: undefined, getItem: undefined, removeItem: undefined } }) $.fn.bootstrapTable.methods.push('getCookies') $.fn.bootstrapTable.methods.push('deleteCookie') $.extend($.fn.bootstrapTable.utils, { setCookie: UtilsCookie.setCookie, getCookie: UtilsCookie.getCookie }) $.BootstrapTable = class extends $.BootstrapTable { init () { if (this.options.cookie) { if (this.options.cookieStorage === 'cookieStorage' && !UtilsCookie.isCookieSupportedByBrowser()) { throw new Error('Cookies are not enabled in this browser.') } this.configureStorage() // FilterBy logic const filterByCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterBy) if (typeof filterByCookieValue === 'boolean' && !filterByCookieValue) { throw new Error('The cookie value of filterBy must be a json!') } let filterByCookie = {} try { filterByCookie = JSON.parse(filterByCookieValue) } catch (e) { throw new Error('Could not parse the json of the filterBy cookie!') } this.filterColumns = filterByCookie ? filterByCookie : {} // FilterControl logic this._filterControls = [] this._filterControlValuesLoaded = false this.options.cookiesEnabled = typeof this.options.cookiesEnabled === 'string' ? this.options.cookiesEnabled.replace('[', '').replace(']', '') .replace(/'/g, '').replace(/ /g, '').toLowerCase().split(',') : this.options.cookiesEnabled if (this.options.filterControl) { const that = this this.$el.on('column-search.bs.table', (e, field, text) => { let isNewField = true for (let i = 0; i < that._filterControls.length; i++) { if (that._filterControls[i].field === field) { that._filterControls[i].text = text isNewField = false break } } if (isNewField) { that._filterControls.push({ field, text }) } UtilsCookie.setCookie(that, UtilsCookie.cookieIds.filterControl, JSON.stringify(that._filterControls)) }).on('created-controls.bs.table', UtilsCookie.initCookieFilters(that)) } } super.init() } initServer (...args) { if ( this.options.cookie && this.options.filterControl && !this._filterControlValuesLoaded ) { const cookie = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterControl)) if (cookie) { return } } super.initServer(...args) } initTable (...args) { super.initTable(...args) this.initCookie() } onSort (...args) { super.onSort(...args) if (!this.options.cookie) { return } if (this.options.sortName === undefined || this.options.sortOrder === undefined) { UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName) UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder) } else { this.options.sortPriority = null UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority) UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortOrder, this.options.sortOrder) UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortName, this.options.sortName) } } onMultipleSort (...args) { super.onMultipleSort(...args) if (!this.options.cookie) { return } if (this.options.sortPriority === undefined) { UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority) } else { this.options.sortName = undefined this.options.sortOrder = undefined UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName) UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder) UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortPriority, JSON.stringify(this.options.sortPriority)) } } onPageNumber (...args) { super.onPageNumber(...args) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber) } onPageListChange (...args) { super.onPageListChange(...args) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageList, this.options.pageSize) UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber) } onPagePre (...args) { super.onPagePre(...args) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber) } onPageNext (...args) { super.onPageNext(...args) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber) } _toggleColumn (...args) { super._toggleColumn(...args) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field))) } _toggleAllColumns (...args) { super._toggleAllColumns(...args) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field))) } toggleView () { super.toggleView() UtilsCookie.setCookie(this, UtilsCookie.cookieIds.cardView, this.options.cardView) } selectPage (page) { super.selectPage(page) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, page) } onSearch (event) { super.onSearch(event, arguments.length > 1 ? arguments[1] : true) if (!this.options.cookie) { return } if (this.options.search) { UtilsCookie.setCookie(this, UtilsCookie.cookieIds.searchText, this.searchText) } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber) } initHeader (...args) { if (this.options.reorderableColumns && this.options.cookie) { this.columnsSortOrder = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.reorderColumns)) } super.initHeader(...args) } persistReorderColumnsState (that) { UtilsCookie.setCookie(that, UtilsCookie.cookieIds.reorderColumns, JSON.stringify(that.columnsSortOrder)) } filterBy (...args) { super.filterBy(...args) if (!this.options.cookie) { return } UtilsCookie.setCookie(this, UtilsCookie.cookieIds.filterBy, JSON.stringify(this.filterColumns)) } initCookie () { if (!this.options.cookie) { return } if ((this.options.cookieIdTable === '') || (this.options.cookieExpire === '')) { console.error('Configuration error. Please review the cookieIdTable and the cookieExpire property. If the properties are correct, then this browser does not support cookies.') this.options.cookie = false // Make sure that the cookie extension is disabled return } const sortOrderCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortOrder) const sortOrderNameCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortName) let sortPriorityCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortPriority) const pageNumberCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageNumber) const pageListCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageList) const searchTextCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.searchText) const cardViewCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.cardView) const columnsCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.columns) const hiddenColumnsCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.hiddenColumns) if (typeof columnsCookieValue === 'boolean' && !columnsCookieValue) { throw new Error('The cookie value of filterBy must be a json!') } let columnsCookie = {} try { columnsCookie = JSON.parse(columnsCookieValue) } catch (e) { throw new Error('Could not parse the json of the columns cookie!', columnsCookieValue) } let hiddenColumnsCookie = {} try { hiddenColumnsCookie = JSON.parse(hiddenColumnsCookieValue) } catch (e) { throw new Error('Could not parse the json of the hidden columns cookie!', hiddenColumnsCookieValue) } try { sortPriorityCookie = JSON.parse(sortPriorityCookie) } catch (e) { throw new Error('Could not parse the json of the sortPriority cookie!', sortPriorityCookie) } if (!sortPriorityCookie) { // sortOrder this.options.sortOrder = sortOrderCookie ? sortOrderCookie : this.options.sortOrder // sortName this.options.sortName = sortOrderNameCookie ? sortOrderNameCookie : this.options.sortName } else { this.options.sortOrder = undefined this.options.sortName = undefined } // sortPriority this.options.sortPriority = sortPriorityCookie ? sortPriorityCookie : this.options.sortPriority if (this.options.sortOrder || this.options.sortName) { // sortPriority this.options.sortPriority = null } // pageNumber this.options.pageNumber = pageNumberCookie ? +pageNumberCookie : this.options.pageNumber // pageSize this.options.pageSize = pageListCookie ? pageListCookie === this.options.formatAllRows() ? pageListCookie : +pageListCookie : this.options.pageSize // searchText if (UtilsCookie.isCookieEnabled(this, 'bs.table.searchText') && this.options.searchText === '') { this.options.searchText = searchTextCookie ? searchTextCookie : '' } // cardView this.options.cardView = cardViewCookie === 'true' ? cardViewCookie : false if (hiddenColumnsCookie) { for (const column of this.columns) { column.visible = !hiddenColumnsCookie.filter(columnField => { if (this.isSelectionColumn(column)) { return true } return columnField === column.field }).length > 0 || !column.switchable } } else if (columnsCookie) { /** * This is needed for the old saved cookies! * It can be removed in 2-3 Versions Later!! * TODO: Remove this part (column cookie) some versions later e.g. 1.22.0 */ for (const column of this.columns) { if (!column.switchable) { continue } column.visible = columnsCookie.filter(columnField => { if (this.isSelectionColumn(column)) { return true } if (columnField instanceof Object) { return columnField.field === column.field } return columnField === column.field }).length > 0 } } } getCookies () { const bootstrapTable = this const cookies = {} $.each(UtilsCookie.cookieIds, (key, value) => { cookies[key] = UtilsCookie.getCookie(bootstrapTable, value) if (key === 'columns' || key === 'hiddenColumns' || key === 'sortPriority') { cookies[key] = JSON.parse(cookies[key]) } }) return cookies } deleteCookie (cookieName) { if (!cookieName) { return } UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds[cookieName]) } configureStorage () { const that = this this._storage = {} switch (this.options.cookieStorage) { case 'cookieStorage': this._storage.setItem = function (cookieName, cookieValue) { document.cookie = [ cookieName, '=', encodeURIComponent(cookieValue), `; expires=${UtilsCookie.calculateExpiration(that.options.cookieExpire)}`, that.options.cookiePath ? `; path=${that.options.cookiePath}` : '', that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '', that.options.cookieSecure ? '; secure' : '', `;SameSite=${ that.options.cookieSameSite}` ].join('') } this._storage.getItem = function (cookieName) { const value = `; ${document.cookie}` const parts = value.split(`; ${cookieName}=`) return parts.length === 2 ? decodeURIComponent(parts.pop().split(';').shift()) : null } this._storage.removeItem = function (cookieName) { document.cookie = [ encodeURIComponent(cookieName), '=', '; expires=Thu, 01 Jan 1970 00:00:00 GMT', that.options.cookiePath ? `; path=${that.options.cookiePath}` : '', that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '', `;SameSite=${ that.options.cookieSameSite}` ].join('') } break case 'localStorage': this._storage.setItem = function (cookieName, cookieValue) { localStorage.setItem(cookieName, cookieValue) } this._storage.getItem = function (cookieName) { return localStorage.getItem(cookieName) } this._storage.removeItem = function (cookieName) { localStorage.removeItem(cookieName) } break case 'sessionStorage': this._storage.setItem = function (cookieName, cookieValue) { sessionStorage.setItem(cookieName, cookieValue) } this._storage.getItem = function (cookieName) { return sessionStorage.getItem(cookieName) } this._storage.removeItem = function (cookieName) { sessionStorage.removeItem(cookieName) } break case 'customStorage': if ( !this.options.cookieCustomStorageSet || !this.options.cookieCustomStorageGet || !this.options.cookieCustomStorageDelete ) { throw new Error('The following options must be set while using the customStorage: cookieCustomStorageSet, cookieCustomStorageGet and cookieCustomStorageDelete') } this._storage.setItem = function (cookieName, cookieValue) { Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageSet, [cookieName, cookieValue], '') } this._storage.getItem = function (cookieName) { return Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageGet, [cookieName], '') } this._storage.removeItem = function (cookieName) { Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageDelete, [cookieName], '') } break default: throw new Error('Storage method not supported.') } } }