UNPKG

20.7 kBJavaScriptView Raw
1/**
2 * @author: Dennis Hernández
3 * @update zhixin wen <wenzhixin2010@gmail.com>
4 */
5const Utils = $.fn.bootstrapTable.utils
6const UtilsCookie = {
7 cookieIds: {
8 sortOrder: 'bs.table.sortOrder',
9 sortName: 'bs.table.sortName',
10 sortPriority: 'bs.table.sortPriority',
11 pageNumber: 'bs.table.pageNumber',
12 pageList: 'bs.table.pageList',
13 columns: 'bs.table.columns',
14 hiddenColumns: 'bs.table.hiddenColumns',
15 cardView: 'bs.table.cardView',
16 searchText: 'bs.table.searchText',
17 reorderColumns: 'bs.table.reorderColumns',
18 filterControl: 'bs.table.filterControl',
19 filterBy: 'bs.table.filterBy'
20 },
21 getCurrentHeader (that) {
22 return that.options.height ? that.$tableHeader : that.$header
23 },
24 getCurrentSearchControls (that) {
25 return that.options.height ? 'table select, table input' : 'select, input'
26 },
27 isCookieSupportedByBrowser () {
28 return navigator.cookieEnabled
29 },
30 isCookieEnabled (that, cookieName) {
31 return that.options.cookiesEnabled.includes(cookieName)
32 },
33 setCookie (that, cookieName, cookieValue) {
34 if (
35 !that.options.cookie ||
36 !UtilsCookie.isCookieEnabled(that, cookieName)
37 ) {
38 return
39 }
40
41 return that._storage.setItem(`${that.options.cookieIdTable}.${cookieName}`, cookieValue)
42 },
43 getCookie (that, cookieName) {
44 if (
45 !cookieName ||
46 !UtilsCookie.isCookieEnabled(that, cookieName)
47 ) {
48 return null
49 }
50
51 return that._storage.getItem(`${that.options.cookieIdTable}.${cookieName}`)
52 },
53 deleteCookie (that, cookieName) {
54 return that._storage.removeItem(`${that.options.cookieIdTable}.${cookieName}`)
55 },
56 calculateExpiration (cookieExpire) {
57 const time = cookieExpire.replace(/[0-9]*/, '') // s,mi,h,d,m,y
58
59 cookieExpire = cookieExpire.replace(/[A-Za-z]{1,2}/, '') // number
60
61 switch (time.toLowerCase()) {
62 case 's':
63 cookieExpire = +cookieExpire
64 break
65 case 'mi':
66 cookieExpire *= 60
67 break
68 case 'h':
69 cookieExpire = cookieExpire * 60 * 60
70 break
71 case 'd':
72 cookieExpire = cookieExpire * 24 * 60 * 60
73 break
74 case 'm':
75 cookieExpire = cookieExpire * 30 * 24 * 60 * 60
76 break
77 case 'y':
78 cookieExpire = cookieExpire * 365 * 24 * 60 * 60
79 break
80 default:
81 cookieExpire = undefined
82 break
83 }
84 if (!cookieExpire) {
85 return ''
86 }
87 const d = new Date()
88
89 d.setTime(d.getTime() + cookieExpire * 1000)
90 return d.toGMTString()
91 },
92 initCookieFilters (bootstrapTable) {
93 setTimeout(() => {
94 const parsedCookieFilters = JSON.parse(
95 UtilsCookie.getCookie(bootstrapTable, UtilsCookie.cookieIds.filterControl))
96
97 if (!bootstrapTable._filterControlValuesLoaded && parsedCookieFilters) {
98 const cachedFilters = {}
99 const header = UtilsCookie.getCurrentHeader(bootstrapTable)
100 const searchControls = UtilsCookie.getCurrentSearchControls(bootstrapTable)
101
102 const applyCookieFilters = (element, filteredCookies) => {
103 filteredCookies.forEach(cookie => {
104 const value = element.value.toString()
105 const text = cookie.text
106
107 if (
108 text === '' ||
109 element.type === 'radio' &&
110 value !== text
111 ) {
112 return
113 }
114
115 if (
116 element.tagName === 'INPUT' &&
117 element.type === 'radio' &&
118 value === text
119 ) {
120 element.checked = true
121 cachedFilters[cookie.field] = text
122 } else if (element.tagName === 'INPUT') {
123 element.value = text
124 cachedFilters[cookie.field] = text
125 } else if (
126 element.tagName === 'SELECT' &&
127 bootstrapTable.options.filterControlContainer
128 ) {
129 element.value = text
130 cachedFilters[cookie.field] = text
131 } else if (text !== '' && element.tagName === 'SELECT') {
132 cachedFilters[cookie.field] = text
133 for (const currentElement of element) {
134 if (currentElement.value === text) {
135 currentElement.selected = true
136 return
137 }
138 }
139 const option = document.createElement('option')
140
141 option.value = text
142 option.text = text
143 element.add(option, element[1])
144 element.selectedIndex = 1
145 }
146 })
147 }
148
149 let filterContainer = header
150
151 if (bootstrapTable.options.filterControlContainer) {
152 filterContainer = $(`${bootstrapTable.options.filterControlContainer}`)
153 }
154
155 filterContainer.find(searchControls).each(function () {
156 const field = $(this).closest('[data-field]').data('field')
157 const filteredCookies = parsedCookieFilters.filter(cookie => cookie.field === field)
158
159 applyCookieFilters(this, filteredCookies)
160 })
161
162 bootstrapTable.initColumnSearch(cachedFilters)
163 bootstrapTable._filterControlValuesLoaded = true
164 bootstrapTable.initServer()
165 }
166 }, 250)
167 }
168}
169
170Object.assign($.fn.bootstrapTable.defaults, {
171 cookie: false,
172 cookieExpire: '2h',
173 cookiePath: null,
174 cookieDomain: null,
175 cookieSecure: null,
176 cookieSameSite: 'Lax',
177 cookieIdTable: '',
178 cookiesEnabled: [
179 'bs.table.sortOrder', 'bs.table.sortName', 'bs.table.sortPriority',
180 'bs.table.pageNumber', 'bs.table.pageList',
181 'bs.table.hiddenColumns', 'bs.table.columns', 'bs.table.searchText',
182 'bs.table.filterControl', 'bs.table.filterBy',
183 'bs.table.reorderColumns', 'bs.table.cardView'
184 ],
185 cookieStorage: 'cookieStorage', // localStorage, sessionStorage, customStorage
186 cookieCustomStorageGet: null,
187 cookieCustomStorageSet: null,
188 cookieCustomStorageDelete: null,
189 // internal variable
190 _filterControls: [],
191 _filterControlValuesLoaded: false,
192 _storage: {
193 setItem: undefined,
194 getItem: undefined,
195 removeItem: undefined
196 }
197})
198
199$.fn.bootstrapTable.methods.push('getCookies')
200$.fn.bootstrapTable.methods.push('deleteCookie')
201
202Object.assign($.fn.bootstrapTable.utils, {
203 setCookie: UtilsCookie.setCookie,
204 getCookie: UtilsCookie.getCookie
205})
206
207$.BootstrapTable = class extends $.BootstrapTable {
208 init () {
209 if (this.options.cookie) {
210 if (this.options.cookieStorage === 'cookieStorage' && !UtilsCookie.isCookieSupportedByBrowser()) {
211 throw new Error('Cookies are not enabled in this browser.')
212 }
213
214 this.configureStorage()
215
216 // FilterBy logic
217 const filterByCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterBy)
218
219 if (typeof filterByCookieValue === 'boolean' && !filterByCookieValue) {
220 throw new Error('The cookie value of filterBy must be a json!')
221 }
222
223 let filterByCookie = {}
224
225 try {
226 filterByCookie = JSON.parse(filterByCookieValue)
227 } catch (e) {
228 throw new Error('Could not parse the json of the filterBy cookie!')
229 }
230 this.filterColumns = filterByCookie ? filterByCookie : {}
231
232 // FilterControl logic
233 this._filterControls = []
234 this._filterControlValuesLoaded = false
235
236 this.options.cookiesEnabled = typeof this.options.cookiesEnabled === 'string' ?
237 this.options.cookiesEnabled.replace('[', '').replace(']', '')
238 .replace(/'/g, '').replace(/ /g, '').split(',') :
239 this.options.cookiesEnabled
240
241 if (this.options.filterControl) {
242 const that = this
243
244 this.$el.on('column-search.bs.table', (e, field, text) => {
245 let isNewField = true
246
247 for (let i = 0; i < that._filterControls.length; i++) {
248 if (that._filterControls[i].field === field) {
249 that._filterControls[i].text = text
250 isNewField = false
251 break
252 }
253 }
254 if (isNewField) {
255 that._filterControls.push({
256 field,
257 text
258 })
259 }
260
261 UtilsCookie.setCookie(that, UtilsCookie.cookieIds.filterControl, JSON.stringify(that._filterControls))
262 }).on('created-controls.bs.table', UtilsCookie.initCookieFilters(that))
263 }
264 }
265 super.init()
266 }
267
268 initServer (...args) {
269 if (
270 this.options.cookie &&
271 this.options.filterControl &&
272 !this._filterControlValuesLoaded
273 ) {
274 const cookie = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterControl))
275
276 if (cookie) {
277 return
278 }
279 }
280 super.initServer(...args)
281 }
282
283 initTable (...args) {
284 super.initTable(...args)
285 this.initCookie()
286 }
287
288 onSort (...args) {
289 super.onSort(...args)
290
291 if (!this.options.cookie) {
292 return
293 }
294
295 if (this.options.sortName === undefined || this.options.sortOrder === undefined) {
296 UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName)
297 UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder)
298 } else {
299 this.options.sortPriority = null
300 UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority)
301
302 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortOrder, this.options.sortOrder)
303 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortName, this.options.sortName)
304 }
305 }
306
307 onMultipleSort (...args) {
308 super.onMultipleSort(...args)
309
310 if (!this.options.cookie) {
311 return
312 }
313
314 if (this.options.sortPriority === undefined) {
315 UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority)
316 } else {
317 this.options.sortName = undefined
318 this.options.sortOrder = undefined
319 UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName)
320 UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder)
321
322 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortPriority, JSON.stringify(this.options.sortPriority))
323 }
324 }
325
326 onPageNumber (...args) {
327 super.onPageNumber(...args)
328 if (!this.options.cookie) {
329 return
330 }
331 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
332 }
333
334 onPageListChange (...args) {
335 super.onPageListChange(...args)
336 if (!this.options.cookie) {
337 return
338 }
339 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageList, this.options.pageSize)
340 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
341 }
342
343 onPagePre (...args) {
344 super.onPagePre(...args)
345 if (!this.options.cookie) {
346 return
347 }
348 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
349 }
350
351 onPageNext (...args) {
352 super.onPageNext(...args)
353 if (!this.options.cookie) {
354 return
355 }
356 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
357 }
358
359 _toggleColumn (...args) {
360 super._toggleColumn(...args)
361 if (!this.options.cookie) {
362 return
363 }
364 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field)))
365 }
366
367 _toggleAllColumns (...args) {
368 super._toggleAllColumns(...args)
369 if (!this.options.cookie) {
370 return
371 }
372 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field)))
373 }
374
375 toggleView () {
376 super.toggleView()
377 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.cardView, this.options.cardView)
378 }
379
380 selectPage (page) {
381 super.selectPage(page)
382 if (!this.options.cookie) {
383 return
384 }
385 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, page)
386 }
387
388 onSearch (event) {
389 super.onSearch(event, arguments.length > 1 ? arguments[1] : true)
390 if (!this.options.cookie) {
391 return
392 }
393 if (this.options.search) {
394 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.searchText, this.searchText)
395 }
396 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
397 }
398
399 initHeader (...args) {
400 if (this.options.reorderableColumns && this.options.cookie) {
401 this.columnsSortOrder = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.reorderColumns))
402 }
403 super.initHeader(...args)
404 }
405
406 persistReorderColumnsState (that) {
407 UtilsCookie.setCookie(that, UtilsCookie.cookieIds.reorderColumns, JSON.stringify(that.columnsSortOrder))
408 }
409
410 filterBy (...args) {
411 super.filterBy(...args)
412 if (!this.options.cookie) {
413 return
414 }
415 UtilsCookie.setCookie(this, UtilsCookie.cookieIds.filterBy, JSON.stringify(this.filterColumns))
416 }
417
418 initCookie () {
419 if (!this.options.cookie) {
420 return
421 }
422
423 if (this.options.cookieIdTable === '' || this.options.cookieExpire === '') {
424 console.error('Configuration error. Please review the cookieIdTable and the cookieExpire property. If the properties are correct, then this browser does not support cookies.')
425 this.options.cookie = false // Make sure that the cookie extension is disabled
426 return
427 }
428
429 const sortOrderCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortOrder)
430 const sortOrderNameCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortName)
431 let sortPriorityCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortPriority)
432 const pageNumberCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageNumber)
433 const pageListCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageList)
434 const searchTextCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.searchText)
435 const cardViewCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.cardView)
436
437 const columnsCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.columns)
438 const hiddenColumnsCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.hiddenColumns)
439
440 if (typeof columnsCookieValue === 'boolean' && !columnsCookieValue) {
441 throw new Error('The cookie value of filterBy must be a json!')
442 }
443
444 let columnsCookie = {}
445
446 try {
447 columnsCookie = JSON.parse(columnsCookieValue)
448 } catch (e) {
449 throw new Error('Could not parse the json of the columns cookie!', columnsCookieValue)
450 }
451
452 let hiddenColumnsCookie = {}
453
454 try {
455 hiddenColumnsCookie = JSON.parse(hiddenColumnsCookieValue)
456 } catch (e) {
457 throw new Error('Could not parse the json of the hidden columns cookie!', hiddenColumnsCookieValue)
458 }
459
460 try {
461 sortPriorityCookie = JSON.parse(sortPriorityCookie)
462 } catch (e) {
463 throw new Error('Could not parse the json of the sortPriority cookie!', sortPriorityCookie)
464 }
465
466 if (!sortPriorityCookie) {
467 // sortOrder
468 this.options.sortOrder = sortOrderCookie ? sortOrderCookie : this.options.sortOrder
469 // sortName
470 this.options.sortName = sortOrderNameCookie ? sortOrderNameCookie : this.options.sortName
471 } else {
472 this.options.sortOrder = undefined
473 this.options.sortName = undefined
474 }
475
476 // sortPriority
477 this.options.sortPriority = sortPriorityCookie ? sortPriorityCookie : this.options.sortPriority
478
479 if (this.options.sortOrder || this.options.sortName) {
480 // sortPriority
481 this.options.sortPriority = null
482 }
483
484 // pageNumber
485 this.options.pageNumber = pageNumberCookie ? +pageNumberCookie : this.options.pageNumber
486 // pageSize
487 this.options.pageSize = pageListCookie ? pageListCookie === this.options.formatAllRows() ? pageListCookie : +pageListCookie : this.options.pageSize
488 // searchText
489 if (UtilsCookie.isCookieEnabled(this, UtilsCookie.cookieIds.searchText) && this.options.searchText === '') {
490 this.options.searchText = searchTextCookie ? searchTextCookie : ''
491 }
492 // cardView
493 this.options.cardView = cardViewCookie === 'true' ? cardViewCookie : false
494
495 if (hiddenColumnsCookie) {
496 for (const column of this.columns) {
497 column.visible = !hiddenColumnsCookie.filter(columnField => {
498 if (this.isSelectionColumn(column)) {
499 return false
500 }
501
502 return columnField === column.field
503 }).length > 0 || !column.switchable
504 }
505 } else if (columnsCookie) {
506 /**
507 * This is needed for the old saved cookies!
508 * It can be removed in 2-3 Versions Later!!
509 * TODO: Remove this part (column cookie) some versions later e.g. 1.22.0
510 */
511 for (const column of this.columns) {
512 if (!column.switchable) {
513 continue
514 }
515
516 column.visible = columnsCookie.filter(columnField => {
517 if (this.isSelectionColumn(column)) {
518 return true
519 }
520 if (columnField instanceof Object) {
521 return columnField.field === column.field
522 }
523
524 return columnField === column.field
525 }).length > 0
526 }
527 }
528 }
529
530 getCookies () {
531 const bootstrapTable = this
532 const cookies = {}
533
534 $.each(UtilsCookie.cookieIds, (key, value) => {
535 cookies[key] = UtilsCookie.getCookie(bootstrapTable, value)
536 if (key === 'columns' || key === 'hiddenColumns' || key === 'sortPriority') {
537 cookies[key] = JSON.parse(cookies[key])
538 }
539 })
540 return cookies
541 }
542
543 deleteCookie (cookieName) {
544 if (!cookieName) {
545 return
546 }
547
548 UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds[cookieName])
549 }
550
551 configureStorage () {
552 const that = this
553
554 this._storage = {}
555 switch (this.options.cookieStorage) {
556 case 'cookieStorage':
557 this._storage.setItem = function (cookieName, cookieValue) {
558 document.cookie = [
559 cookieName, '=', encodeURIComponent(cookieValue),
560 `; expires=${UtilsCookie.calculateExpiration(that.options.cookieExpire)}`,
561 that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
562 that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '',
563 that.options.cookieSecure ? '; secure' : '',
564 `;SameSite=${that.options.cookieSameSite}`
565 ].join('')
566 }
567 this._storage.getItem = function (cookieName) {
568 const value = `; ${document.cookie}`
569 const parts = value.split(`; ${cookieName}=`)
570
571 return parts.length === 2 ? decodeURIComponent(parts.pop().split(';').shift()) : null
572 }
573 this._storage.removeItem = function (cookieName) {
574 document.cookie = [
575 encodeURIComponent(cookieName), '=',
576 '; expires=Thu, 01 Jan 1970 00:00:00 GMT',
577 that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
578 that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '',
579 `;SameSite=${that.options.cookieSameSite}`
580 ].join('')
581 }
582 break
583 case 'localStorage':
584 this._storage.setItem = function (cookieName, cookieValue) {
585 localStorage.setItem(cookieName, cookieValue)
586 }
587 this._storage.getItem = function (cookieName) {
588 return localStorage.getItem(cookieName)
589 }
590 this._storage.removeItem = function (cookieName) {
591 localStorage.removeItem(cookieName)
592 }
593 break
594 case 'sessionStorage':
595 this._storage.setItem = function (cookieName, cookieValue) {
596 sessionStorage.setItem(cookieName, cookieValue)
597 }
598 this._storage.getItem = function (cookieName) {
599 return sessionStorage.getItem(cookieName)
600 }
601 this._storage.removeItem = function (cookieName) {
602 sessionStorage.removeItem(cookieName)
603 }
604 break
605 case 'customStorage':
606 if (
607 !this.options.cookieCustomStorageSet ||
608 !this.options.cookieCustomStorageGet ||
609 !this.options.cookieCustomStorageDelete
610 ) {
611 throw new Error('The following options must be set while using the customStorage: cookieCustomStorageSet, cookieCustomStorageGet and cookieCustomStorageDelete')
612 }
613
614 this._storage.setItem = function (cookieName, cookieValue) {
615 Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageSet, [cookieName, cookieValue], '')
616 }
617 this._storage.getItem = function (cookieName) {
618 return Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageGet, [cookieName], '')
619 }
620 this._storage.removeItem = function (cookieName) {
621 Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageDelete, [cookieName], '')
622 }
623
624 break
625 default:
626 throw new Error('Storage method not supported.')
627 }
628 }
629}