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)
371 lines (334 loc) • 11.5 kB
JavaScript
/**
* @author: aperez <aperez@datadec.es>
* @version: v2.0.0
*
* @update Dennis Hernández
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
const Utils = $.fn.bootstrapTable.utils
const theme = {
bootstrap3: {
classes: {},
html: {
modal: `
<div id="avdSearchModal_%s" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-xs">
<div class="modal-content">
<div class="modal-header">
<button class="close toolbar-modal-close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title toolbar-modal-title"></h4>
</div>
<div class="modal-body toolbar-modal-body"></div>
<div class="modal-footer toolbar-modal-footer">
<button class="btn btn-%s toolbar-modal-close"></button>
</div>
</div>
</div>
</div>
`
}
},
bootstrap4: {
classes: {},
html: {
modal: `
<div id="avdSearchModal_%s" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-xs">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title toolbar-modal-title"></h4>
<button class="close toolbar-modal-close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body toolbar-modal-body"></div>
<div class="modal-footer toolbar-modal-footer">
<button class="btn btn-%s toolbar-modal-close"></button>
</div>
</div>
</div>
</div>
`
}
},
bootstrap5: {
classes: {
formGroup: 'mb-3'
},
html: {
modal: `
<div id="avdSearchModal_%s" class="modal fade" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xs">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title toolbar-modal-title"></h5>
<button class="btn-close toolbar-modal-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body toolbar-modal-body"></div>
<div class="modal-footer toolbar-modal-footer">
<button class="btn btn-%s toolbar-modal-close"></button>
</div>
</div>
</div>
</div>
`
}
},
bulma: {
classes: {},
html: {
modal: `
<div class="modal" id="avdSearchModal_%s">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title toolbar-modal-title"></p>
<button class="delete toolbar-modal-close"></button>
</header>
<section class="modal-card-body toolbar-modal-body"></section>
<footer class="modal-card-foot toolbar-modal-footer">
<button class="button button-%s toolbar-modal-close"></button>
</footer>
</div>
</div>
`
}
},
foundation: {
classes: {},
html: {
modal: `
<div class="reveal" id="avdSearchModal_%s" data-reveal>
<h1 class="toolbar-modal-title"></h1>
<div class="toolbar-modal-body"></div>
<button class="close-button toolbar-modal-close" data-close aria-label="Close modal">
<span aria-hidden="true">×</span>
</button>
<div class="toolbar-modal-footer">
<button class="button button-%s toolbar-modal-close"></button>
</div>
</div>
`
}
},
materialize: {
classes: {},
html: {
modal: `
<div id="avdSearchModal_%s" class="modal">
<div class="modal-content">
<h4 class="toolbar-modal-title"></h4>
<div class="toolbar-modal-body"></div>
</div>
<div class="modal-footer toolbar-modal-footer">
<a href="javascript:void(0)" class="modal-close waves-effect waves-green btn-flat btn-%s toolbar-modal-close"></a>
</div>
</div>
`
}
},
semantic: {
classes: {},
html: {
modal: `
<div class="ui modal" id="avdSearchModal_%s">
<i class="close icon toolbar-modal-close"></i>
<div class="header toolbar-modal-title""></div>
<div class="image content ui form toolbar-modal-body"></div>
<div class="actions toolbar-modal-footer">
<div class="ui black deny button button-%s toolbar-modal-close"></div>
</div>
</div>
`
}
}
}[$.fn.bootstrapTable.theme]
Object.assign($.fn.bootstrapTable.defaults, {
advancedSearch: false,
idForm: 'advancedSearch',
actionForm: '',
idTable: undefined,
// eslint-disable-next-line no-unused-vars
onColumnAdvancedSearch (field, text) {
return false
}
})
Utils.assignIcons($.fn.bootstrapTable.icons, 'advancedSearchIcon', {
glyphicon: 'glyphicon-chevron-down',
fa: 'fa-chevron-down',
bi: 'bi-chevron-down',
'material-icons': 'expand_more'
})
Object.assign($.fn.bootstrapTable.events, {
'column-advanced-search.bs.table': 'onColumnAdvancedSearch'
})
Object.assign($.fn.bootstrapTable.locales, {
formatAdvancedSearch () {
return 'Advanced search'
},
formatAdvancedCloseButton () {
return 'Close'
}
})
Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.BootstrapTable = class extends $.BootstrapTable {
initToolbar () {
this.showToolbar = this.showToolbar ||
this.options.search &&
this.options.advancedSearch &&
this.options.idTable
if (this.showToolbar) {
this.buttons = Object.assign(this.buttons, {
advancedSearch: {
text: this.options.formatAdvancedSearch(),
icon: this.options.icons.advancedSearchIcon,
event: this.showAdvancedSearch,
attributes: {
'aria-label': this.options.formatAdvancedSearch(),
title: this.options.formatAdvancedSearch()
}
}
})
if (Utils.isEmptyObject(this.filterColumnsPartial)) {
this.filterColumnsPartial = {}
}
}
super.initToolbar()
}
showAdvancedSearch () {
this.$toolbarModal = $(`#avdSearchModal_${this.options.idTable}`)
if (this.$toolbarModal.length <= 0) {
$('body').append(Utils.sprintf(theme.html.modal,
this.options.idTable, this.options.buttonsClass))
this.$toolbarModal = $(`#avdSearchModal_${this.options.idTable}`)
this.$toolbarModal.find('.toolbar-modal-close')
.off('click')
.on('click', () => this.hideToolbarModal())
}
this.initToolbarModalBody()
this.showToolbarModal()
}
initToolbarModalBody () {
this.$toolbarModal.find('.toolbar-modal-title')
.html(this.options.formatAdvancedSearch())
this.$toolbarModal.find('.toolbar-modal-footer .toolbar-modal-close')
.html(this.options.formatAdvancedCloseButton())
this.$toolbarModal.find('.toolbar-modal-body')
.html(this.createToolbarForm())
.off('keyup blur', 'input').on('keyup blur', 'input', e => {
this.onColumnAdvancedSearch(e)
})
}
showToolbarModal () {
const theme = $.fn.bootstrapTable.theme
if (['bootstrap3', 'bootstrap4'].includes(theme)) {
this.$toolbarModal.modal()
} else if (theme === 'bootstrap5') {
if (!this.toolbarModal) {
this.toolbarModal = new window.bootstrap.Modal(this.$toolbarModal[0], {})
}
this.toolbarModal.show()
} else if (theme === 'bulma') {
this.$toolbarModal.toggleClass('is-active')
} else if (theme === 'foundation') {
if (!this.toolbarModal) {
this.toolbarModal = new window.Foundation.Reveal(this.$toolbarModal)
}
this.toolbarModal.open()
} else if (theme === 'materialize') {
this.$toolbarModal.modal().modal('open')
} else if (theme === 'semantic') {
this.$toolbarModal.modal('show')
}
}
hideToolbarModal () {
const theme = $.fn.bootstrapTable.theme
if (['bootstrap3', 'bootstrap4'].includes(theme)) {
this.$toolbarModal.modal('hide')
} else if (theme === 'bootstrap5') {
this.toolbarModal.hide()
} else if (theme === 'bulma') {
$('html').toggleClass('is-clipped')
this.$toolbarModal.toggleClass('is-active')
} else if (theme === 'foundation') {
this.toolbarModal.close()
} else if (theme === 'materialize') {
this.$toolbarModal.modal('open')
} else if (theme === 'semantic') {
this.$toolbarModal.modal('close')
}
if (this.options.sidePagination === 'server') {
this.options.pageNumber = 1
this.updatePagination()
this.trigger('column-advanced-search', this.filterColumnsPartial)
}
}
createToolbarForm () {
const html = [
`<form class="form-horizontal toolbar-model-form" action="${this.options.actionForm}">`
]
for (const column of this.columns) {
if (!column.checkbox && column.visible && column.searchable) {
const title = $('<div/>').html(column.title).text().trim()
const value = this.filterColumnsPartial[column.field] || ''
html.push(`
<div class="form-group row ${theme.classes.formGroup || ''}">
<label class="col-sm-4 control-label">${title}</label>
<div class="col-sm-6">
<input type="text" class="form-control ${this.constants.classes.input}"
name="${column.field}" placeholder="${title}" value="${value}">
</div>
</div>
`)
}
}
html.push('</form>')
return html.join('')
}
initSearch () {
super.initSearch()
if (!this.options.advancedSearch || this.options.sidePagination === 'server') {
return
}
const fp = Utils.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial
this.data = fp ? this.data.filter((item, i) => {
for (const [key, v] of Object.entries(fp)) {
const val = v.toLowerCase()
let value = item[key]
const index = this.header.fields.indexOf(key)
value = Utils.calculateObjectValue(this.header,
this.header.formatters[index], [value, item, i], value)
if (this.header.formatters[index]) {
// search innerText
value = $('<div>').html(value).text()
}
if (
!(index !== -1 &&
(typeof value === 'string' || typeof value === 'number') &&
`${value}`.toLowerCase().includes(val))
) {
return false
}
}
return true
}) : this.data
this.unsortedData = [...this.data]
}
onColumnAdvancedSearch (e) {
const text = $(e.currentTarget).val().trim()
const field = $(e.currentTarget).attr('name')
if (text) {
this.filterColumnsPartial[field] = text
} else {
delete this.filterColumnsPartial[field]
}
if (this.options.sidePagination !== 'server') {
this.options.pageNumber = 1
this.initSearch()
this.updatePagination()
this.trigger('column-advanced-search', field, text)
}
}
}