mirror of https://gitee.com/y_project/RuoYi.git
升级bootstrap-table到最新版本v1.18.3
parent
39bd0225b6
commit
3283955284
|
@ -135,7 +135,7 @@
|
||||||
<exclude>**/*.min.js</exclude>
|
<exclude>**/*.min.js</exclude>
|
||||||
<exclude>**/*.min.css</exclude>
|
<exclude>**/*.min.css</exclude>
|
||||||
<exclude>**/fileinput.js</exclude>
|
<exclude>**/fileinput.js</exclude>
|
||||||
<exclude>**/bootstrap-treetable.js</exclude>
|
<exclude>**/bootstrap-table/**</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin> -->
|
</plugin> -->
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* @author: Alec Fenichel
|
||||||
|
* @webSite: https://fenichelar.com
|
||||||
|
* @update: zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Utils = $.fn.bootstrapTable.utils
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
autoRefresh: false,
|
||||||
|
autoRefreshInterval: 60,
|
||||||
|
autoRefreshSilent: true,
|
||||||
|
autoRefreshStatus: true,
|
||||||
|
autoRefreshFunction: null
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||||
|
autoRefresh: {
|
||||||
|
bootstrap3: 'glyphicon-time icon-time',
|
||||||
|
materialize: 'access_time',
|
||||||
|
'bootstrap-table': 'icon-clock'
|
||||||
|
}[$.fn.bootstrapTable.theme] || 'fa-clock'
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.locales, {
|
||||||
|
formatAutoRefresh () {
|
||||||
|
return 'Auto Refresh'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
init (...args) {
|
||||||
|
super.init(...args)
|
||||||
|
|
||||||
|
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
|
||||||
|
this.setupRefreshInterval()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initToolbar (...args) {
|
||||||
|
if (this.options.autoRefresh) {
|
||||||
|
this.buttons = Object.assign(this.buttons, {
|
||||||
|
autoRefresh: {
|
||||||
|
html: `
|
||||||
|
<button class="auto-refresh ${this.constants.buttonsClass}
|
||||||
|
${this.options.autoRefreshStatus ? ` ${this.constants.classes.buttonActive}` : ''}"
|
||||||
|
type="button" name="autoRefresh" title="${this.options.formatAutoRefresh()}">
|
||||||
|
${ this.options.showButtonIcons ? Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, this.options.icons.autoRefresh) : ''}
|
||||||
|
${ this.options.showButtonText ? this.options.formatAutoRefresh() : ''}
|
||||||
|
</button>
|
||||||
|
`,
|
||||||
|
event: this.toggleAutoRefresh
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
super.initToolbar(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAutoRefresh () {
|
||||||
|
if (this.options.autoRefresh) {
|
||||||
|
if (this.options.autoRefreshStatus) {
|
||||||
|
clearInterval(this.options.autoRefreshFunction)
|
||||||
|
this.$toolbar.find('>.columns .auto-refresh')
|
||||||
|
.removeClass(this.constants.classes.buttonActive)
|
||||||
|
} else {
|
||||||
|
this.setupRefreshInterval()
|
||||||
|
this.$toolbar.find('>.columns .auto-refresh')
|
||||||
|
.addClass(this.constants.classes.buttonActive)
|
||||||
|
}
|
||||||
|
this.options.autoRefreshStatus = !this.options.autoRefreshStatus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy () {
|
||||||
|
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
|
||||||
|
clearInterval(this.options.autoRefreshFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
setupRefreshInterval () {
|
||||||
|
this.options.autoRefreshFunction = setInterval(() => {
|
||||||
|
if (!this.options.autoRefresh || !this.options.autoRefreshStatus) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.refresh({ silent: this.options.autoRefreshSilent })
|
||||||
|
}, this.options.autoRefreshInterval * 1000)
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,404 @@
|
||||||
|
/**
|
||||||
|
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Utils = $.fn.bootstrapTable.utils
|
||||||
|
|
||||||
|
// Reasonable defaults
|
||||||
|
const PIXEL_STEP = 10
|
||||||
|
const LINE_HEIGHT = 40
|
||||||
|
const PAGE_HEIGHT = 800
|
||||||
|
|
||||||
|
function normalizeWheel (event) {
|
||||||
|
let sX = 0 // spinX
|
||||||
|
let sY = 0 // spinY
|
||||||
|
let pX = 0 // pixelX
|
||||||
|
let pY = 0 // pixelY
|
||||||
|
|
||||||
|
// Legacy
|
||||||
|
if ('detail' in event) { sY = event.detail }
|
||||||
|
if ('wheelDelta' in event) { sY = -event.wheelDelta / 120 }
|
||||||
|
if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120 }
|
||||||
|
if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120 }
|
||||||
|
|
||||||
|
// side scrolling on FF with DOMMouseScroll
|
||||||
|
if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) {
|
||||||
|
sX = sY
|
||||||
|
sY = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pX = sX * PIXEL_STEP
|
||||||
|
pY = sY * PIXEL_STEP
|
||||||
|
|
||||||
|
if ('deltaY' in event) { pY = event.deltaY }
|
||||||
|
if ('deltaX' in event) { pX = event.deltaX }
|
||||||
|
|
||||||
|
if ((pX || pY) && event.deltaMode) {
|
||||||
|
if (event.deltaMode === 1) { // delta in LINE units
|
||||||
|
pX *= LINE_HEIGHT
|
||||||
|
pY *= LINE_HEIGHT
|
||||||
|
} else { // delta in PAGE units
|
||||||
|
pX *= PAGE_HEIGHT
|
||||||
|
pY *= PAGE_HEIGHT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall-back if spin cannot be determined
|
||||||
|
if (pX && !sX) { sX = (pX < 1) ? -1 : 1 }
|
||||||
|
if (pY && !sY) { sY = (pY < 1) ? -1 : 1 }
|
||||||
|
|
||||||
|
return {
|
||||||
|
spinX: sX,
|
||||||
|
spinY: sY,
|
||||||
|
pixelX: pX,
|
||||||
|
pixelY: pY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
fixedColumns: false,
|
||||||
|
fixedNumber: 0,
|
||||||
|
fixedRightNumber: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
|
||||||
|
fixedColumnsSupported () {
|
||||||
|
return this.options.fixedColumns &&
|
||||||
|
!this.options.detailView &&
|
||||||
|
!this.options.cardView
|
||||||
|
}
|
||||||
|
|
||||||
|
initContainer () {
|
||||||
|
super.initContainer()
|
||||||
|
|
||||||
|
if (!this.fixedColumnsSupported()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.fixedNumber) {
|
||||||
|
this.$tableContainer.append('<div class="fixed-columns"></div>')
|
||||||
|
this.$fixedColumns = this.$tableContainer.find('.fixed-columns')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.fixedRightNumber) {
|
||||||
|
this.$tableContainer.append('<div class="fixed-columns-right"></div>')
|
||||||
|
this.$fixedColumnsRight = this.$tableContainer.find('.fixed-columns-right')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initBody (...args) {
|
||||||
|
super.initBody(...args)
|
||||||
|
|
||||||
|
if (this.$fixedColumns && this.$fixedColumns.length) {
|
||||||
|
this.$fixedColumns.toggle(this.fixedColumnsSupported())
|
||||||
|
}
|
||||||
|
if (this.$fixedColumnsRight && this.$fixedColumnsRight.length) {
|
||||||
|
this.$fixedColumnsRight.toggle(this.fixedColumnsSupported())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.fixedColumnsSupported()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.showHeader && this.options.height) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initFixedColumnsBody()
|
||||||
|
this.initFixedColumnsEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger (...args) {
|
||||||
|
super.trigger(...args)
|
||||||
|
|
||||||
|
if (!this.fixedColumnsSupported()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args[0] === 'post-header') {
|
||||||
|
this.initFixedColumnsHeader()
|
||||||
|
} else if (args[0] === 'scroll-body') {
|
||||||
|
if (this.needFixedColumns && this.options.fixedNumber) {
|
||||||
|
this.$fixedBody.scrollTop(this.$tableBody.scrollTop())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedRightNumber) {
|
||||||
|
this.$fixedBodyRight.scrollTop(this.$tableBody.scrollTop())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSelected () {
|
||||||
|
super.updateSelected()
|
||||||
|
|
||||||
|
if (!this.fixedColumnsSupported()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$tableBody.find('tr').each((i, el) => {
|
||||||
|
const $el = $(el)
|
||||||
|
const index = $el.data('index')
|
||||||
|
const classes = $el.attr('class')
|
||||||
|
|
||||||
|
const inputSelector = `[name="${this.options.selectItemName}"]`
|
||||||
|
const $input = $el.find(inputSelector)
|
||||||
|
|
||||||
|
if (typeof index === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateFixedBody = ($fixedHeader, $fixedBody) => {
|
||||||
|
const $tr = $fixedBody.find(`tr[data-index="${index}"]`)
|
||||||
|
|
||||||
|
$tr.attr('class', classes)
|
||||||
|
|
||||||
|
if ($input.length) {
|
||||||
|
$tr.find(inputSelector).prop('checked', $input.prop('checked'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.$selectAll.length) {
|
||||||
|
$fixedHeader.add($fixedBody)
|
||||||
|
.find('[name="btSelectAll"]')
|
||||||
|
.prop('checked', this.$selectAll.prop('checked'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.$fixedBody && this.options.fixedNumber) {
|
||||||
|
updateFixedBody(this.$fixedHeader, this.$fixedBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.$fixedBodyRight && this.options.fixedRightNumber) {
|
||||||
|
updateFixedBody(this.$fixedHeaderRight, this.$fixedBodyRight)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
hideLoading () {
|
||||||
|
super.hideLoading()
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedNumber) {
|
||||||
|
this.$fixedColumns.find('.fixed-table-loading').hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedRightNumber) {
|
||||||
|
this.$fixedColumnsRight.find('.fixed-table-loading').hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initFixedColumnsHeader () {
|
||||||
|
if (this.options.height) {
|
||||||
|
this.needFixedColumns = this.$tableHeader.outerWidth(true) < this.$tableHeader.find('table').outerWidth(true)
|
||||||
|
} else {
|
||||||
|
this.needFixedColumns = this.$tableBody.outerWidth(true) < this.$tableBody.find('table').outerWidth(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const initFixedHeader = ($fixedColumns, isRight) => {
|
||||||
|
$fixedColumns.find('.fixed-table-header').remove()
|
||||||
|
$fixedColumns.append(this.$tableHeader.clone(true))
|
||||||
|
|
||||||
|
$fixedColumns.css({
|
||||||
|
width: this.getFixedColumnsWidth(isRight)
|
||||||
|
})
|
||||||
|
return $fixedColumns.find('.fixed-table-header')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedNumber) {
|
||||||
|
this.$fixedHeader = initFixedHeader(this.$fixedColumns)
|
||||||
|
this.$fixedHeader.css('margin-right', '')
|
||||||
|
} else if (this.$fixedColumns) {
|
||||||
|
this.$fixedColumns.html('').css('width', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedRightNumber) {
|
||||||
|
this.$fixedHeaderRight = initFixedHeader(this.$fixedColumnsRight, true)
|
||||||
|
this.$fixedHeaderRight.scrollLeft(this.$fixedHeaderRight.find('table').width())
|
||||||
|
} else if (this.$fixedColumnsRight) {
|
||||||
|
this.$fixedColumnsRight.html('').css('width', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initFixedColumnsBody()
|
||||||
|
this.initFixedColumnsEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
initFixedColumnsBody () {
|
||||||
|
const initFixedBody = ($fixedColumns, $fixedHeader) => {
|
||||||
|
$fixedColumns.find('.fixed-table-body').remove()
|
||||||
|
$fixedColumns.append(this.$tableBody.clone(true))
|
||||||
|
|
||||||
|
const $fixedBody = $fixedColumns.find('.fixed-table-body')
|
||||||
|
|
||||||
|
const tableBody = this.$tableBody.get(0)
|
||||||
|
const scrollHeight = tableBody.scrollWidth > tableBody.clientWidth ?
|
||||||
|
Utils.getScrollBarWidth() : 0
|
||||||
|
const height = this.$tableContainer.outerHeight(true) - scrollHeight - 1
|
||||||
|
|
||||||
|
$fixedColumns.css({
|
||||||
|
height
|
||||||
|
})
|
||||||
|
|
||||||
|
$fixedBody.css({
|
||||||
|
height: height - $fixedHeader.height()
|
||||||
|
})
|
||||||
|
|
||||||
|
return $fixedBody
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedNumber) {
|
||||||
|
this.$fixedBody = initFixedBody(this.$fixedColumns, this.$fixedHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedRightNumber) {
|
||||||
|
this.$fixedBodyRight = initFixedBody(this.$fixedColumnsRight, this.$fixedHeaderRight)
|
||||||
|
this.$fixedBodyRight.scrollLeft(this.$fixedBodyRight.find('table').width())
|
||||||
|
this.$fixedBodyRight.css('overflow-y', this.options.height ? 'auto' : 'hidden')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFixedColumnsWidth (isRight) {
|
||||||
|
let visibleFields = this.getVisibleFields()
|
||||||
|
let width = 0
|
||||||
|
let fixedNumber = this.options.fixedNumber
|
||||||
|
let marginRight = 0
|
||||||
|
|
||||||
|
if (isRight) {
|
||||||
|
visibleFields = visibleFields.reverse()
|
||||||
|
fixedNumber = this.options.fixedRightNumber
|
||||||
|
marginRight = parseInt(this.$tableHeader.css('margin-right'), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < fixedNumber; i++) {
|
||||||
|
width += this.$header.find(`th[data-field="${visibleFields[i]}"]`).outerWidth(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return width + marginRight + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
initFixedColumnsEvents () {
|
||||||
|
const toggleHover = (e, toggle) => {
|
||||||
|
const tr = `tr[data-index="${$(e.currentTarget).data('index')}"]`
|
||||||
|
let $trs = this.$tableBody.find(tr)
|
||||||
|
|
||||||
|
if (this.$fixedBody) {
|
||||||
|
$trs = $trs.add(this.$fixedBody.find(tr))
|
||||||
|
}
|
||||||
|
if (this.$fixedBodyRight) {
|
||||||
|
$trs = $trs.add(this.$fixedBodyRight.find(tr))
|
||||||
|
}
|
||||||
|
|
||||||
|
$trs.css('background-color', toggle ? $(e.currentTarget).css('background-color') : '')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$tableBody.find('tr').hover(e => {
|
||||||
|
toggleHover(e, true)
|
||||||
|
}, e => {
|
||||||
|
toggleHover(e, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
const isFirefox = typeof navigator !== 'undefined' &&
|
||||||
|
navigator.userAgent.toLowerCase().indexOf('firefox') > -1
|
||||||
|
const mousewheel = isFirefox ? 'DOMMouseScroll' : 'mousewheel'
|
||||||
|
const updateScroll = (e, fixedBody) => {
|
||||||
|
const normalized = normalizeWheel(e)
|
||||||
|
const deltaY = Math.ceil(normalized.pixelY)
|
||||||
|
const top = this.$tableBody.scrollTop() + deltaY
|
||||||
|
|
||||||
|
if (
|
||||||
|
deltaY < 0 && top > 0 ||
|
||||||
|
deltaY > 0 && top < fixedBody.scrollHeight - fixedBody.clientHeight
|
||||||
|
) {
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$tableBody.scrollTop(top)
|
||||||
|
if (this.$fixedBody) {
|
||||||
|
this.$fixedBody.scrollTop(top)
|
||||||
|
}
|
||||||
|
if (this.$fixedBodyRight) {
|
||||||
|
this.$fixedBodyRight.scrollTop(top)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedNumber) {
|
||||||
|
this.$fixedBody.find('tr').hover(e => {
|
||||||
|
toggleHover(e, true)
|
||||||
|
}, e => {
|
||||||
|
toggleHover(e, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$fixedBody[0].addEventListener(mousewheel, e => {
|
||||||
|
updateScroll(e, this.$fixedBody[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedRightNumber) {
|
||||||
|
this.$fixedBodyRight.find('tr').hover(e => {
|
||||||
|
toggleHover(e, true)
|
||||||
|
}, e => {
|
||||||
|
toggleHover(e, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$fixedBodyRight.off('scroll').on('scroll', () => {
|
||||||
|
const top = this.$fixedBodyRight.scrollTop()
|
||||||
|
|
||||||
|
this.$tableBody.scrollTop(top)
|
||||||
|
if (this.$fixedBody) {
|
||||||
|
this.$fixedBody.scrollTop(top)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.filterControl) {
|
||||||
|
$(this.$fixedColumns).off('keyup change').on('keyup change', e => {
|
||||||
|
const $target = $(e.target)
|
||||||
|
const value = $target.val()
|
||||||
|
const field = $target.parents('th').data('field')
|
||||||
|
const $coreTh = this.$header.find(`th[data-field="${field}"]`)
|
||||||
|
|
||||||
|
if ($target.is('input')) {
|
||||||
|
$coreTh.find('input').val(value)
|
||||||
|
} else if ($target.is('select')) {
|
||||||
|
const $select = $coreTh.find('select')
|
||||||
|
|
||||||
|
$select.find('option[selected]').removeAttr('selected')
|
||||||
|
$select.find(`option[value="${value}"]`).attr('selected', true)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.triggerSearch()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStickyHeader () {
|
||||||
|
if (!this.options.stickyHeader) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$stickyContainer = this.$container.find('.sticky-header-container')
|
||||||
|
super.renderStickyHeader()
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedNumber) {
|
||||||
|
this.$fixedColumns.css('z-index', 101)
|
||||||
|
.find('.sticky-header-container')
|
||||||
|
.css('right', '')
|
||||||
|
.width(this.$fixedColumns.outerWidth())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needFixedColumns && this.options.fixedRightNumber) {
|
||||||
|
const $stickyHeaderContainerRight = this.$fixedColumnsRight.find('.sticky-header-container')
|
||||||
|
|
||||||
|
this.$fixedColumnsRight.css('z-index', 101)
|
||||||
|
$stickyHeaderContainerRight.css('left', '')
|
||||||
|
.scrollLeft($stickyHeaderContainerRight.find('.table').outerWidth())
|
||||||
|
.width(this.$fixedColumnsRight.outerWidth())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matchPositionX () {
|
||||||
|
if (!this.options.stickyHeader) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$stickyContainer.eq(0).scrollLeft(this.$tableBody.scrollLeft())
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,187 @@
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
/**
|
||||||
|
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
* extensions: https://github.com/vitalets/x-editable
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Utils = $.fn.bootstrapTable.utils
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
editable: true,
|
||||||
|
onEditableInit () {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
onEditableSave (field, row, rowIndex, oldValue, $el) {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
onEditableShown (field, row, $el, editable) {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
onEditableHidden (field, row, $el, reason) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.columnDefaults, {
|
||||||
|
alwaysUseFormatter: false
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
|
'editable-init.bs.table': 'onEditableInit',
|
||||||
|
'editable-save.bs.table': 'onEditableSave',
|
||||||
|
'editable-shown.bs.table': 'onEditableShown',
|
||||||
|
'editable-hidden.bs.table': 'onEditableHidden'
|
||||||
|
})
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
initTable () {
|
||||||
|
super.initTable()
|
||||||
|
|
||||||
|
if (!this.options.editable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editedCells = []
|
||||||
|
$.each(this.columns, (i, column) => {
|
||||||
|
if (!column.editable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const editableOptions = {}
|
||||||
|
const editableDataMarkup = []
|
||||||
|
const editableDataPrefix = 'editable-'
|
||||||
|
const processDataOptions = (key, value) => {
|
||||||
|
// Replace camel case with dashes.
|
||||||
|
const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
|
||||||
|
|
||||||
|
if (dashKey.indexOf(editableDataPrefix) === 0) {
|
||||||
|
editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(this.options, processDataOptions)
|
||||||
|
|
||||||
|
column.formatter = column.formatter || (value => value)
|
||||||
|
column._formatter = column._formatter ? column._formatter : column.formatter
|
||||||
|
column.formatter = (value, row, index) => {
|
||||||
|
let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
|
||||||
|
|
||||||
|
result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
|
||||||
|
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
|
||||||
|
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
|
||||||
|
|
||||||
|
if ($.inArray(column.field + uniqueId, this.editedCells) !== -1) {
|
||||||
|
result = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(column, processDataOptions)
|
||||||
|
|
||||||
|
$.each(editableOptions, (key, value) => {
|
||||||
|
editableDataMarkup.push(` ${key}="${value}"`)
|
||||||
|
})
|
||||||
|
|
||||||
|
let noEditFormatter = false
|
||||||
|
const editableOpts = Utils.calculateObjectValue(column,
|
||||||
|
column.editable, [index, row], {})
|
||||||
|
|
||||||
|
if (editableOpts.hasOwnProperty('noEditFormatter')) {
|
||||||
|
noEditFormatter = editableOpts.noEditFormatter(value, row, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noEditFormatter === false) {
|
||||||
|
return `<a href="javascript:void(0)"
|
||||||
|
data-name="${column.field}"
|
||||||
|
data-pk="${row[this.options.idField]}"
|
||||||
|
data-value="${result}"
|
||||||
|
${editableDataMarkup.join('')}></a>`
|
||||||
|
}
|
||||||
|
return noEditFormatter
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
initBody (fixedScroll) {
|
||||||
|
super.initBody(fixedScroll)
|
||||||
|
|
||||||
|
if (!this.options.editable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(this.columns, (i, column) => {
|
||||||
|
if (!column.editable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = this.getData({ escape: true })
|
||||||
|
const $field = this.$body.find(`a[data-name="${column.field}"]`)
|
||||||
|
|
||||||
|
$field.each((i, element) => {
|
||||||
|
const $element = $(element)
|
||||||
|
const $tr = $element.closest('tr')
|
||||||
|
const index = $tr.data('index')
|
||||||
|
const row = data[index]
|
||||||
|
|
||||||
|
const editableOpts = Utils.calculateObjectValue(column,
|
||||||
|
column.editable, [index, row, $element], {})
|
||||||
|
|
||||||
|
$element.editable(editableOpts)
|
||||||
|
})
|
||||||
|
|
||||||
|
$field.off('save').on('save', ({ currentTarget }, { submitValue }) => {
|
||||||
|
const $this = $(currentTarget)
|
||||||
|
const data = this.getData()
|
||||||
|
const rowIndex = $this.parents('tr[data-index]').data('index')
|
||||||
|
const row = data[rowIndex]
|
||||||
|
const oldValue = row[column.field]
|
||||||
|
|
||||||
|
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
|
||||||
|
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
|
||||||
|
|
||||||
|
if ($.inArray(column.field + uniqueId, this.editedCells) === -1) {
|
||||||
|
this.editedCells.push(column.field + uniqueId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submitValue = Utils.escapeHTML(submitValue)
|
||||||
|
$this.data('value', submitValue)
|
||||||
|
row[column.field] = submitValue
|
||||||
|
this.trigger('editable-save', column.field, row, rowIndex, oldValue, $this)
|
||||||
|
this.initBody()
|
||||||
|
})
|
||||||
|
|
||||||
|
$field.off('shown').on('shown', ({ currentTarget }, editable) => {
|
||||||
|
const $this = $(currentTarget)
|
||||||
|
const data = this.getData()
|
||||||
|
const rowIndex = $this.parents('tr[data-index]').data('index')
|
||||||
|
const row = data[rowIndex]
|
||||||
|
|
||||||
|
this.trigger('editable-shown', column.field, row, $this, editable)
|
||||||
|
})
|
||||||
|
|
||||||
|
$field.off('hidden').on('hidden', ({ currentTarget }, reason) => {
|
||||||
|
const $this = $(currentTarget)
|
||||||
|
const data = this.getData()
|
||||||
|
const rowIndex = $this.parents('tr[data-index]').data('index')
|
||||||
|
const row = data[rowIndex]
|
||||||
|
|
||||||
|
this.trigger('editable-hidden', column.field, row, $this, reason)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.trigger('editable-init')
|
||||||
|
}
|
||||||
|
|
||||||
|
getData (params) {
|
||||||
|
const data = super.getData(params)
|
||||||
|
|
||||||
|
if (params && params.escape) {
|
||||||
|
for (const row of data) {
|
||||||
|
for (const [key, value] of Object.entries(row)) {
|
||||||
|
row[key] = Utils.unescapeHTML(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,333 @@
|
||||||
|
/**
|
||||||
|
* @author zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
* extensions: https://github.com/hhurz/tableExport.jquery.plugin
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Utils = $.fn.bootstrapTable.utils
|
||||||
|
|
||||||
|
const TYPE_NAME = {
|
||||||
|
json: 'JSON',
|
||||||
|
xml: 'XML',
|
||||||
|
png: 'PNG',
|
||||||
|
csv: 'CSV',
|
||||||
|
txt: 'TXT',
|
||||||
|
sql: 'SQL',
|
||||||
|
doc: 'MS-Word',
|
||||||
|
excel: 'MS-Excel',
|
||||||
|
xlsx: 'MS-Excel (OpenXML)',
|
||||||
|
powerpoint: 'MS-Powerpoint',
|
||||||
|
pdf: 'PDF'
|
||||||
|
}
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
showExport: false,
|
||||||
|
exportDataType: 'basic', // basic, all, selected
|
||||||
|
exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
|
||||||
|
exportOptions: {
|
||||||
|
onCellHtmlData (cell, rowIndex, colIndex, htmlData) {
|
||||||
|
if (cell.is('th')) {
|
||||||
|
return cell.find('.th-inner').text()
|
||||||
|
}
|
||||||
|
|
||||||
|
return htmlData
|
||||||
|
}
|
||||||
|
},
|
||||||
|
exportFooter: false
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.columnDefaults, {
|
||||||
|
forceExport: false,
|
||||||
|
forceHide: false
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||||
|
export: {
|
||||||
|
bootstrap3: 'glyphicon-export icon-share',
|
||||||
|
materialize: 'file_download',
|
||||||
|
'bootstrap-table': 'icon-download'
|
||||||
|
}[$.fn.bootstrapTable.theme] || 'fa-download'
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.locales, {
|
||||||
|
formatExport () {
|
||||||
|
return 'Export data'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
||||||
|
|
||||||
|
$.fn.bootstrapTable.methods.push('exportTable')
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
onExportSaved (exportedRows) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
|
'export-saved.bs.table': 'onExportSaved'
|
||||||
|
})
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
initToolbar (...args) {
|
||||||
|
const o = this.options
|
||||||
|
let exportTypes = o.exportTypes
|
||||||
|
|
||||||
|
this.showToolbar = this.showToolbar || o.showExport
|
||||||
|
|
||||||
|
if (this.options.showExport) {
|
||||||
|
|
||||||
|
if (typeof exportTypes === 'string') {
|
||||||
|
const types = exportTypes.slice(1, -1).replace(/ /g, '').split(',')
|
||||||
|
|
||||||
|
exportTypes = types.map(t => t.slice(1, -1))
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$export = this.$toolbar.find('>.columns div.export')
|
||||||
|
if (this.$export.length) {
|
||||||
|
this.updateExportButton()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.buttons = Object.assign(this.buttons, {
|
||||||
|
export: {
|
||||||
|
html: exportTypes.length === 1 ? `
|
||||||
|
<div class="export ${this.constants.classes.buttonsDropdown}"
|
||||||
|
data-type="${exportTypes[0]}">
|
||||||
|
<button class="${this.constants.buttonsClass}"
|
||||||
|
aria-label="Export"
|
||||||
|
type="button"
|
||||||
|
title="${o.formatExport()}">
|
||||||
|
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||||
|
${o.showButtonText ? o.formatExport() : ''}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
` : `
|
||||||
|
<div class="export ${this.constants.classes.buttonsDropdown}">
|
||||||
|
<button class="${this.constants.buttonsClass} dropdown-toggle"
|
||||||
|
aria-label="Export"
|
||||||
|
${this.constants.dataToggle}="dropdown"
|
||||||
|
type="button"
|
||||||
|
title="${o.formatExport()}">
|
||||||
|
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
|
||||||
|
${o.showButtonText ? o.formatExport() : ''}
|
||||||
|
${this.constants.html.dropdownCaret}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
super.initToolbar(...args)
|
||||||
|
this.$export = this.$toolbar.find('>.columns div.export')
|
||||||
|
|
||||||
|
if (!this.options.showExport) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let $menu = $(this.constants.html.toolbarDropdown.join(''))
|
||||||
|
let $items = this.$export
|
||||||
|
|
||||||
|
if (exportTypes.length > 1) {
|
||||||
|
this.$export.append($menu)
|
||||||
|
|
||||||
|
// themes support
|
||||||
|
if ($menu.children().length) {
|
||||||
|
$menu = $menu.children().eq(0)
|
||||||
|
}
|
||||||
|
for (const type of exportTypes) {
|
||||||
|
if (TYPE_NAME.hasOwnProperty(type)) {
|
||||||
|
const $item = $(Utils.sprintf(this.constants.html.pageDropdownItem,
|
||||||
|
'', TYPE_NAME[type]))
|
||||||
|
|
||||||
|
$item.attr('data-type', type)
|
||||||
|
$menu.append($item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = $menu.children()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateExportButton()
|
||||||
|
|
||||||
|
$items.click(e => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
const type = $(e.currentTarget).data('type')
|
||||||
|
const exportOptions = {
|
||||||
|
type,
|
||||||
|
escape: false
|
||||||
|
}
|
||||||
|
|
||||||
|
this.exportTable(exportOptions)
|
||||||
|
})
|
||||||
|
this.handleToolbar()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleToolbar () {
|
||||||
|
if (!this.$export) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (super.handleToolbar) {
|
||||||
|
super.handleToolbar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exportTable (options) {
|
||||||
|
const o = this.options
|
||||||
|
const stateField = this.header.stateField
|
||||||
|
const isCardView = o.cardView
|
||||||
|
|
||||||
|
const doExport = callback => {
|
||||||
|
if (stateField) {
|
||||||
|
this.hideColumn(stateField)
|
||||||
|
}
|
||||||
|
if (isCardView) {
|
||||||
|
this.toggleView()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.columns.forEach(row => {
|
||||||
|
if (row.forceHide) {
|
||||||
|
this.hideColumn(row.field)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = this.getData()
|
||||||
|
|
||||||
|
if (o.detailView && o.detailViewIcon) {
|
||||||
|
const detailViewIndex = o.detailViewAlign === 'left' ? 0 : this.getVisibleFields().length + Utils.getDetailViewIndexOffset(this.options)
|
||||||
|
|
||||||
|
o.exportOptions.ignoreColumn = [detailViewIndex].concat(o.exportOptions.ignoreColumn || [])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.exportFooter) {
|
||||||
|
const $footerRow = this.$tableFooter.find('tr').first()
|
||||||
|
const footerData = {}
|
||||||
|
const footerHtml = []
|
||||||
|
|
||||||
|
$.each($footerRow.children(), (index, footerCell) => {
|
||||||
|
const footerCellHtml = $(footerCell).children('.th-inner').first().html()
|
||||||
|
|
||||||
|
footerData[this.columns[index].field] = footerCellHtml === ' ' ? null : footerCellHtml
|
||||||
|
|
||||||
|
// grab footer cell text into cell index-based array
|
||||||
|
footerHtml.push(footerCellHtml)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$body.append(this.$body.children().last()[0].outerHTML)
|
||||||
|
const $lastTableRow = this.$body.children().last()
|
||||||
|
|
||||||
|
$.each($lastTableRow.children(), (index, lastTableRowCell) => {
|
||||||
|
$(lastTableRowCell).html(footerHtml[index])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const hiddenColumns = this.getHiddenColumns()
|
||||||
|
|
||||||
|
hiddenColumns.forEach(row => {
|
||||||
|
if (row.forceExport) {
|
||||||
|
this.showColumn(row.field)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (typeof o.exportOptions.fileName === 'function') {
|
||||||
|
options.fileName = o.exportOptions.fileName()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$el.tableExport($.extend({
|
||||||
|
onAfterSaveToFile: () => {
|
||||||
|
if (o.exportFooter) {
|
||||||
|
this.load(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateField) {
|
||||||
|
this.showColumn(stateField)
|
||||||
|
}
|
||||||
|
if (isCardView) {
|
||||||
|
this.toggleView()
|
||||||
|
}
|
||||||
|
|
||||||
|
hiddenColumns.forEach(row => {
|
||||||
|
if (row.forceExport) {
|
||||||
|
this.hideColumn(row.field)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.columns.forEach(row => {
|
||||||
|
if (row.forceHide) {
|
||||||
|
this.showColumn(row.field)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (callback) callback()
|
||||||
|
}
|
||||||
|
}, o.exportOptions, options))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.exportDataType === 'all' && o.pagination) {
|
||||||
|
const eventName = o.sidePagination === 'server' ?
|
||||||
|
'post-body.bs.table' : 'page-change.bs.table'
|
||||||
|
const virtualScroll = this.options.virtualScroll
|
||||||
|
|
||||||
|
this.$el.one(eventName, () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
doExport(() => {
|
||||||
|
this.options.virtualScroll = virtualScroll
|
||||||
|
this.togglePagination()
|
||||||
|
})
|
||||||
|
}, 0)
|
||||||
|
})
|
||||||
|
this.options.virtualScroll = false
|
||||||
|
this.togglePagination()
|
||||||
|
this.trigger('export-saved', this.getData())
|
||||||
|
} else if (o.exportDataType === 'selected') {
|
||||||
|
let data = this.getData()
|
||||||
|
let selectedData = this.getSelections()
|
||||||
|
const pagination = o.pagination
|
||||||
|
|
||||||
|
if (!selectedData.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.sidePagination === 'server') {
|
||||||
|
data = {
|
||||||
|
total: o.totalRows,
|
||||||
|
[this.options.dataField]: data
|
||||||
|
}
|
||||||
|
selectedData = {
|
||||||
|
total: selectedData.length,
|
||||||
|
[this.options.dataField]: selectedData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.load(selectedData)
|
||||||
|
if (pagination) {
|
||||||
|
this.togglePagination()
|
||||||
|
}
|
||||||
|
doExport(() => {
|
||||||
|
if (pagination) {
|
||||||
|
this.togglePagination()
|
||||||
|
}
|
||||||
|
this.load(data)
|
||||||
|
})
|
||||||
|
this.trigger('export-saved', selectedData)
|
||||||
|
} else {
|
||||||
|
doExport()
|
||||||
|
this.trigger('export-saved', this.getData(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSelected () {
|
||||||
|
super.updateSelected()
|
||||||
|
this.updateExportButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateExportButton () {
|
||||||
|
if (this.options.exportDataType === 'selected') {
|
||||||
|
this.$export.find('> button')
|
||||||
|
.prop('disabled', !this.getSelections().length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,124 @@
|
||||||
|
/**
|
||||||
|
* @author: Dennis Hernández
|
||||||
|
* @webSite: http://djhvscf.github.io/Blog
|
||||||
|
* @update zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
const debounce = (func, wait) => {
|
||||||
|
let timeout = 0
|
||||||
|
|
||||||
|
return (...args) => {
|
||||||
|
const later = () => {
|
||||||
|
timeout = 0
|
||||||
|
func(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTimeout(timeout)
|
||||||
|
timeout = setTimeout(later, wait)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
mobileResponsive: false,
|
||||||
|
minWidth: 562,
|
||||||
|
minHeight: undefined,
|
||||||
|
heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar
|
||||||
|
checkOnInit: true,
|
||||||
|
columnsHidden: []
|
||||||
|
})
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
init (...args) {
|
||||||
|
super.init(...args)
|
||||||
|
|
||||||
|
if (!this.options.mobileResponsive || !this.options.minWidth) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.minWidth < 100 && this.options.resizable) {
|
||||||
|
console.warn('The minWidth when the resizable extension is active should be greater or equal than 100')
|
||||||
|
this.options.minWidth = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
let old = {
|
||||||
|
width: $(window).width(),
|
||||||
|
height: $(window).height()
|
||||||
|
}
|
||||||
|
|
||||||
|
$(window).on('resize orientationchange', debounce(() => {
|
||||||
|
// reset view if height has only changed by at least the threshold.
|
||||||
|
const width = $(window).width()
|
||||||
|
const height = $(window).height()
|
||||||
|
const $activeElement = $(document.activeElement)
|
||||||
|
|
||||||
|
if ($activeElement.length && ['INPUT', 'SELECT', 'TEXTAREA'].includes($activeElement.prop('nodeName'))) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
Math.abs(old.height - height) > this.options.heightThreshold ||
|
||||||
|
old.width !== width
|
||||||
|
) {
|
||||||
|
this.changeView(width, height)
|
||||||
|
old = {
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 200))
|
||||||
|
|
||||||
|
if (this.options.checkOnInit) {
|
||||||
|
const width = $(window).width()
|
||||||
|
const height = $(window).height()
|
||||||
|
|
||||||
|
this.changeView(width, height)
|
||||||
|
old = {
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionCardView () {
|
||||||
|
this.changeTableView(false)
|
||||||
|
this.showHideColumns(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionFullView () {
|
||||||
|
this.changeTableView(true)
|
||||||
|
this.showHideColumns(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
changeTableView (cardViewState) {
|
||||||
|
this.options.cardView = cardViewState
|
||||||
|
this.toggleView()
|
||||||
|
}
|
||||||
|
|
||||||
|
showHideColumns (checked) {
|
||||||
|
if (this.options.columnsHidden.length > 0) {
|
||||||
|
this.columns.forEach(column => {
|
||||||
|
if (this.options.columnsHidden.includes(column.field)) {
|
||||||
|
if (column.visible !== checked) {
|
||||||
|
this._toggleColumn(this.fieldsColumnsIndex[column.field], checked, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeView (width, height) {
|
||||||
|
if (this.options.minHeight) {
|
||||||
|
if ((width <= this.options.minWidth) && (height <= this.options.minHeight)) {
|
||||||
|
this.conditionCardView()
|
||||||
|
} else if ((width > this.options.minWidth) && (height > this.options.minHeight)) {
|
||||||
|
this.conditionFullView()
|
||||||
|
}
|
||||||
|
} else if (width <= this.options.minWidth) {
|
||||||
|
this.conditionCardView()
|
||||||
|
} else if (width > this.options.minWidth) {
|
||||||
|
this.conditionFullView()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resetView()
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,284 @@
|
||||||
|
/**
|
||||||
|
* @update zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Utils = $.fn.bootstrapTable.utils
|
||||||
|
|
||||||
|
function printPageBuilderDefault (table) {
|
||||||
|
return `
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style type="text/css" media="print">
|
||||||
|
@page {
|
||||||
|
size: auto;
|
||||||
|
margin: 25px 0 25px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style type="text/css" media="all">
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid grey;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left:20px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width:94%;
|
||||||
|
margin-left:3%;
|
||||||
|
margin-right:3%;
|
||||||
|
}
|
||||||
|
div.bs-table-print {
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<title>Print Table</title>
|
||||||
|
<body>
|
||||||
|
<p>Printed on: ${new Date} </p>
|
||||||
|
<div class="bs-table-print">${table}</div>
|
||||||
|
</body>
|
||||||
|
</html>`
|
||||||
|
}
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.locales, {
|
||||||
|
formatPrint () {
|
||||||
|
return 'Print'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
showPrint: false,
|
||||||
|
printAsFilteredAndSortedOnUI: true,
|
||||||
|
printSortColumn: undefined,
|
||||||
|
printSortOrder: 'asc',
|
||||||
|
printPageBuilder (table) {
|
||||||
|
return printPageBuilderDefault(table)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
|
||||||
|
printFilter: undefined,
|
||||||
|
printIgnore: false,
|
||||||
|
printFormatter: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults.icons, {
|
||||||
|
print: {
|
||||||
|
bootstrap3: 'glyphicon-print icon-share',
|
||||||
|
'bootstrap-table': 'icon-printer'
|
||||||
|
}[$.fn.bootstrapTable.theme] || 'fa-print'
|
||||||
|
})
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
init (...args) {
|
||||||
|
super.init(...args)
|
||||||
|
|
||||||
|
if (!this.options.showPrint) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mergedCells = []
|
||||||
|
}
|
||||||
|
|
||||||
|
initToolbar (...args) {
|
||||||
|
this.showToolbar = this.showToolbar || this.options.showPrint
|
||||||
|
|
||||||
|
if (this.options.showPrint) {
|
||||||
|
this.buttons = Object.assign(this.buttons, {
|
||||||
|
print: {
|
||||||
|
text: this.options.formatPrint(),
|
||||||
|
icon: this.options.icons.print,
|
||||||
|
event: () => {
|
||||||
|
this.doPrint(this.options.printAsFilteredAndSortedOnUI ? this.getData() : this.options.data.slice(0))
|
||||||
|
},
|
||||||
|
attributes: {
|
||||||
|
'aria-label': this.options.formatPrint(),
|
||||||
|
title: this.options.formatPrint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
super.initToolbar(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeCells (options) {
|
||||||
|
super.mergeCells(options)
|
||||||
|
|
||||||
|
if (!this.options.showPrint) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let col = this.getVisibleFields().indexOf(options.field)
|
||||||
|
|
||||||
|
if (Utils.hasDetailViewIcon(this.options)) {
|
||||||
|
col += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mergedCells.push({
|
||||||
|
row: options.index,
|
||||||
|
col,
|
||||||
|
rowspan: options.rowspan || 1,
|
||||||
|
colspan: options.colspan || 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
doPrint (data) {
|
||||||
|
const formatValue = (row, i, column) => {
|
||||||
|
const value = Utils.calculateObjectValue(column, column.printFormatter,
|
||||||
|
[row[column.field], row, i], row[column.field])
|
||||||
|
|
||||||
|
return typeof value === 'undefined' || value === null ?
|
||||||
|
this.options.undefinedText : value
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildTable = (data, columnsArray) => {
|
||||||
|
const dir = this.$el.attr('dir') || 'ltr'
|
||||||
|
const html = [`<table dir="${dir}"><thead>`]
|
||||||
|
|
||||||
|
for (const columns of columnsArray) {
|
||||||
|
html.push('<tr>')
|
||||||
|
for (let h = 0; h < columns.length; h++) {
|
||||||
|
if (!columns[h].printIgnore) {
|
||||||
|
html.push(
|
||||||
|
`<th
|
||||||
|
${Utils.sprintf(' rowspan="%s"', columns[h].rowspan)}
|
||||||
|
${Utils.sprintf(' colspan="%s"', columns[h].colspan)}
|
||||||
|
>${columns[h].title}</th>`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html.push('</tr>')
|
||||||
|
}
|
||||||
|
|
||||||
|
html.push('</thead><tbody>')
|
||||||
|
|
||||||
|
const dontRender = []
|
||||||
|
|
||||||
|
if (this.mergedCells) {
|
||||||
|
for (let mc = 0; mc < this.mergedCells.length; mc++) {
|
||||||
|
const currentMergedCell = this.mergedCells[mc]
|
||||||
|
|
||||||
|
for (let rs = 0; rs < currentMergedCell.rowspan; rs++) {
|
||||||
|
const row = currentMergedCell.row + rs
|
||||||
|
|
||||||
|
for (let cs = 0; cs < currentMergedCell.colspan; cs++) {
|
||||||
|
const col = currentMergedCell.col + cs
|
||||||
|
|
||||||
|
dontRender.push(`${row },${ col}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
html.push('<tr>')
|
||||||
|
|
||||||
|
const columns = columnsArray.flat(1)
|
||||||
|
|
||||||
|
columns.sort((c1, c2) => {
|
||||||
|
return c1.colspanIndex - c2.colspanIndex
|
||||||
|
})
|
||||||
|
|
||||||
|
for (let j = 0; j < columns.length; j++) {
|
||||||
|
if (columns[j].colspanGroup > 0) continue
|
||||||
|
|
||||||
|
let rowspan = 0
|
||||||
|
let colspan = 0
|
||||||
|
|
||||||
|
if (this.mergedCells) {
|
||||||
|
for (let mc = 0; mc < this.mergedCells.length; mc++) {
|
||||||
|
const currentMergedCell = this.mergedCells[mc]
|
||||||
|
|
||||||
|
if (currentMergedCell.col === j && currentMergedCell.row === i) {
|
||||||
|
rowspan = currentMergedCell.rowspan
|
||||||
|
colspan = currentMergedCell.colspan
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!columns[j].printIgnore && columns[j].field &&
|
||||||
|
(
|
||||||
|
!dontRender.includes(`${i },${ j}`) ||
|
||||||
|
(rowspan > 0 && colspan > 0)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (rowspan > 0 && colspan > 0) {
|
||||||
|
html.push(`<td ${Utils.sprintf(' rowspan="%s"', rowspan)} ${Utils.sprintf(' colspan="%s"', colspan)}>`, formatValue(data[i], i, columns[j]), '</td>')
|
||||||
|
} else {
|
||||||
|
html.push('<td>', formatValue(data[i], i, columns[j]), '</td>')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
html.push('</tr>')
|
||||||
|
}
|
||||||
|
|
||||||
|
html.push('</tbody>')
|
||||||
|
if (this.options.showFooter) {
|
||||||
|
html.push('<footer><tr>')
|
||||||
|
|
||||||
|
for (const columns of columnsArray) {
|
||||||
|
for (let h = 0; h < columns.length; h++) {
|
||||||
|
if (!columns[h].printIgnore) {
|
||||||
|
const footerData = Utils.trToData(columns, this.$el.find('>tfoot>tr'))
|
||||||
|
const footerValue = Utils.calculateObjectValue(columns[h], columns[h].footerFormatter, [data], footerData[0] && footerData[0][columns[h].field] || '')
|
||||||
|
|
||||||
|
html.push(`<th>${footerValue}</th>`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html.push('</tr></footer>')
|
||||||
|
}
|
||||||
|
html.push('</table>')
|
||||||
|
return html.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortRows = (data, colName, sortOrder) => {
|
||||||
|
if (!colName) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
let reverse = sortOrder !== 'asc'
|
||||||
|
|
||||||
|
reverse = -((+reverse) || -1)
|
||||||
|
return data.sort((a, b) => reverse * (a[colName].localeCompare(b[colName])))
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterRow = (row, filters) => {
|
||||||
|
for (let index = 0; index < filters.length; ++index) {
|
||||||
|
if (row[filters[index].colName] !== filters[index].value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterRows = (data, filters) => data.filter(row => filterRow(row, filters))
|
||||||
|
const getColumnFilters = columns => !columns || !columns[0] ? [] : columns[0].filter(col => col.printFilter).map(col => ({
|
||||||
|
colName: col.field,
|
||||||
|
value: col.printFilter
|
||||||
|
}))
|
||||||
|
|
||||||
|
data = filterRows(data, getColumnFilters(this.options.columns))
|
||||||
|
data = sortRows(data, this.options.printSortColumn, this.options.printSortOrder)
|
||||||
|
const table = buildTable(data, this.options.columns)
|
||||||
|
const newWin = window.open('')
|
||||||
|
|
||||||
|
newWin.document.write(this.options.printPageBuilder.call(this, table))
|
||||||
|
newWin.document.close()
|
||||||
|
newWin.focus()
|
||||||
|
newWin.print()
|
||||||
|
newWin.close()
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,213 @@
|
||||||
|
/**
|
||||||
|
* @author: Dennis Hernández
|
||||||
|
* @webSite: http://djhvscf.github.io/Blog
|
||||||
|
* @update: https://github.com/wenzhixin
|
||||||
|
* @version: v1.2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
$.akottr.dragtable.prototype._restoreState = function (persistObj) {
|
||||||
|
let i = 0
|
||||||
|
|
||||||
|
for (const [field, value] of Object.entries(persistObj)) {
|
||||||
|
const $th = this.originalTable.el.find(`th[data-field="${field}"]`)
|
||||||
|
|
||||||
|
if (!$th.length) {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
this.originalTable.startIndex = $th.prevAll().length + 1
|
||||||
|
this.originalTable.endIndex = parseInt(value, 10) + 1 - i
|
||||||
|
this._bubbleCols()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// From MDN site, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
|
||||||
|
const filterFn = () => {
|
||||||
|
if (!Array.prototype.filter) {
|
||||||
|
Array.prototype.filter = function (fun/* , thisArg*/) {
|
||||||
|
if (this === undefined || this === null) {
|
||||||
|
throw new TypeError()
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = Object(this)
|
||||||
|
const len = t.length >>> 0
|
||||||
|
|
||||||
|
if (typeof fun !== 'function') {
|
||||||
|
throw new TypeError()
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = []
|
||||||
|
const thisArg = arguments.length >= 2 ? arguments[1] : undefined
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
if (i in t) {
|
||||||
|
const val = t[i]
|
||||||
|
|
||||||
|
// NOTE: Technically this should Object.defineProperty at
|
||||||
|
// the next index, as push can be affected by
|
||||||
|
// properties on Object.prototype and Array.prototype.
|
||||||
|
// But this method's new, and collisions should be
|
||||||
|
// rare, so use the more-compatible alternative.
|
||||||
|
if (fun.call(thisArg, val, i, t)) {
|
||||||
|
res.push(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
reorderableColumns: false,
|
||||||
|
maxMovingRows: 10,
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
onReorderColumn (headerFields) {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
dragaccept: null
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
|
'reorder-column.bs.table': 'onReorderColumn'
|
||||||
|
})
|
||||||
|
|
||||||
|
$.fn.bootstrapTable.methods.push('orderColumns')
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
initHeader (...args) {
|
||||||
|
super.initHeader(...args)
|
||||||
|
|
||||||
|
if (!this.options.reorderableColumns) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.makeRowsReorderable()
|
||||||
|
}
|
||||||
|
|
||||||
|
_toggleColumn (...args) {
|
||||||
|
super._toggleColumn(...args)
|
||||||
|
|
||||||
|
if (!this.options.reorderableColumns) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.makeRowsReorderable()
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleView (...args) {
|
||||||
|
super.toggleView(...args)
|
||||||
|
|
||||||
|
if (!this.options.reorderableColumns) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.cardView) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.makeRowsReorderable()
|
||||||
|
}
|
||||||
|
|
||||||
|
resetView (...args) {
|
||||||
|
super.resetView(...args)
|
||||||
|
|
||||||
|
if (!this.options.reorderableColumns) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.makeRowsReorderable()
|
||||||
|
}
|
||||||
|
|
||||||
|
makeRowsReorderable (order = null) {
|
||||||
|
try {
|
||||||
|
$(this.$el).dragtable('destroy')
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
$(this.$el).dragtable({
|
||||||
|
maxMovingRows: this.options.maxMovingRows,
|
||||||
|
dragaccept: this.options.dragaccept,
|
||||||
|
clickDelay: 200,
|
||||||
|
dragHandle: '.th-inner',
|
||||||
|
restoreState: order ? order : this.columnsSortOrder,
|
||||||
|
beforeStop: table => {
|
||||||
|
const sortOrder = {}
|
||||||
|
|
||||||
|
table.el.find('th').each((i, el) => {
|
||||||
|
sortOrder[$(el).data('field')] = i
|
||||||
|
})
|
||||||
|
|
||||||
|
this.columnsSortOrder = sortOrder
|
||||||
|
if (this.options.cookie) {
|
||||||
|
this.persistReorderColumnsState(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ths = []
|
||||||
|
const formatters = []
|
||||||
|
const columns = []
|
||||||
|
let columnsHidden = []
|
||||||
|
let columnIndex = -1
|
||||||
|
const optionsColumns = []
|
||||||
|
|
||||||
|
this.$header.find('th:not(.detail)').each((i, el) => {
|
||||||
|
ths.push($(el).data('field'))
|
||||||
|
formatters.push($(el).data('formatter'))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Exist columns not shown
|
||||||
|
if (ths.length < this.columns.length) {
|
||||||
|
columnsHidden = this.columns.filter(column => !column.visible)
|
||||||
|
for (let i = 0; i < columnsHidden.length; i++) {
|
||||||
|
ths.push(columnsHidden[i].field)
|
||||||
|
formatters.push(columnsHidden[i].formatter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < ths.length; i++) {
|
||||||
|
columnIndex = this.fieldsColumnsIndex[ths[i]]
|
||||||
|
if (columnIndex !== -1) {
|
||||||
|
this.fieldsColumnsIndex[ths[i]] = i
|
||||||
|
this.columns[columnIndex].fieldIndex = i
|
||||||
|
columns.push(this.columns[columnIndex])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.columns = columns
|
||||||
|
|
||||||
|
filterFn() // Support <IE9
|
||||||
|
$.each(this.columns, (i, column) => {
|
||||||
|
let found = false
|
||||||
|
const field = column.field
|
||||||
|
|
||||||
|
this.options.columns[0].filter(item => {
|
||||||
|
if (!found && item['field'] === field) {
|
||||||
|
optionsColumns.push(item)
|
||||||
|
found = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.options.columns[0] = optionsColumns
|
||||||
|
|
||||||
|
this.header.fields = ths
|
||||||
|
this.header.formatters = formatters
|
||||||
|
this.initHeader()
|
||||||
|
this.initToolbar()
|
||||||
|
this.initSearchText()
|
||||||
|
this.initBody()
|
||||||
|
this.resetView()
|
||||||
|
this.trigger('reorder-column', ths)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
orderColumns (order) {
|
||||||
|
this.columnsSortOrder = order
|
||||||
|
this.makeRowsReorderable()
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -1,117 +0,0 @@
|
||||||
/**
|
|
||||||
* @author: Dennis Hernández
|
|
||||||
* 实现表格拖拽功能
|
|
||||||
* @version: v1.0.1
|
|
||||||
*/
|
|
||||||
(function ($) {
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var isSearch = false;
|
|
||||||
|
|
||||||
var rowAttr = function (row, index) {
|
|
||||||
return {
|
|
||||||
id: 'customId_' + index
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$.extend($.fn.bootstrapTable.defaults, {
|
|
||||||
reorderableRows: false,
|
|
||||||
onDragStyle: null,
|
|
||||||
onDropStyle: null,
|
|
||||||
onDragClass: "reorder_rows_onDragClass",
|
|
||||||
dragHandle: null,
|
|
||||||
useRowAttrFunc: false,
|
|
||||||
onReorderRowsDrag: function (table, row) {
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
onReorderRowsDrop: function (table, row) {
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
onReorderRow: function (newData) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
|
||||||
'reorder-row.bs.table': 'onReorderRow'
|
|
||||||
});
|
|
||||||
|
|
||||||
var BootstrapTable = $.fn.bootstrapTable.Constructor,
|
|
||||||
_init = BootstrapTable.prototype.init,
|
|
||||||
_initSearch = BootstrapTable.prototype.initSearch;
|
|
||||||
|
|
||||||
BootstrapTable.prototype.init = function () {
|
|
||||||
|
|
||||||
if (!this.options.reorderableRows) {
|
|
||||||
_init.apply(this, Array.prototype.slice.apply(arguments));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var that = this;
|
|
||||||
if (this.options.useRowAttrFunc) {
|
|
||||||
this.options.rowAttributes = rowAttr;
|
|
||||||
}
|
|
||||||
|
|
||||||
var onPostBody = this.options.onPostBody;
|
|
||||||
this.options.onPostBody = function () {
|
|
||||||
setTimeout(function () {
|
|
||||||
that.makeRowsReorderable();
|
|
||||||
onPostBody.apply();
|
|
||||||
}, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
_init.apply(this, Array.prototype.slice.apply(arguments));
|
|
||||||
};
|
|
||||||
|
|
||||||
BootstrapTable.prototype.initSearch = function () {
|
|
||||||
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
|
|
||||||
|
|
||||||
if (!this.options.reorderableRows) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Known issue after search if you reorder the rows the data is not display properly
|
|
||||||
//isSearch = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
BootstrapTable.prototype.makeRowsReorderable = function () {
|
|
||||||
if (this.options.cardView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var that = this;
|
|
||||||
this.$el.tableDnD({
|
|
||||||
onDragStyle: that.options.onDragStyle,
|
|
||||||
onDropStyle: that.options.onDropStyle,
|
|
||||||
onDragClass: that.options.onDragClass,
|
|
||||||
onDrop: that.onDrop,
|
|
||||||
onDragStart: that.options.onReorderRowsDrag,
|
|
||||||
dragHandle: that.options.dragHandle
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
BootstrapTable.prototype.onDrop = function (table, droppedRow) {
|
|
||||||
var tableBs = $(table),
|
|
||||||
tableBsData = tableBs.data('bootstrap.table'),
|
|
||||||
tableBsOptions = tableBs.data('bootstrap.table').options,
|
|
||||||
row = null,
|
|
||||||
newData = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < table.tBodies[0].rows.length; i++) {
|
|
||||||
row = $(table.tBodies[0].rows[i]);
|
|
||||||
newData.push(tableBsOptions.data[row.data('index')]);
|
|
||||||
row.data('index', i).attr('data-index', i);
|
|
||||||
}
|
|
||||||
|
|
||||||
tableBsOptions.data = tableBsOptions.data.slice(0, tableBsData.pageFrom - 1)
|
|
||||||
.concat(newData)
|
|
||||||
.concat(tableBsOptions.data.slice(tableBsData.pageTo));
|
|
||||||
|
|
||||||
//Call the user defined function
|
|
||||||
tableBsOptions.onReorderRowsDrop.apply(table, [table, droppedRow]);
|
|
||||||
|
|
||||||
//Call the event reorder-row
|
|
||||||
tableBsData.trigger('reorder-row', newData);
|
|
||||||
};
|
|
||||||
})(jQuery);
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/**
|
||||||
|
* @author: Dennis Hernández
|
||||||
|
* @webSite: http://djhvscf.github.io/Blog
|
||||||
|
* @update zhixin wen <wenzhixin2010@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
const rowAttr = (row, index) => ({
|
||||||
|
id: `customId_${index}`
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
reorderableRows: false,
|
||||||
|
onDragStyle: null,
|
||||||
|
onDropStyle: null,
|
||||||
|
onDragClass: 'reorder_rows_onDragClass',
|
||||||
|
dragHandle: '>tbody>tr>td',
|
||||||
|
useRowAttrFunc: false,
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
onReorderRowsDrag (row) {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
onReorderRowsDrop (row) {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
onReorderRow (newData) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
||||||
|
'reorder-row.bs.table': 'onReorderRow'
|
||||||
|
})
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
init (...args) {
|
||||||
|
if (!this.options.reorderableRows) {
|
||||||
|
super.init(...args)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.useRowAttrFunc) {
|
||||||
|
this.options.rowAttributes = rowAttr
|
||||||
|
}
|
||||||
|
|
||||||
|
const onPostBody = this.options.onPostBody
|
||||||
|
|
||||||
|
this.options.onPostBody = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.makeRowsReorderable()
|
||||||
|
onPostBody.call(this.options, this.options.data)
|
||||||
|
}, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
super.init(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
makeRowsReorderable () {
|
||||||
|
this.$el.tableDnD({
|
||||||
|
onDragStyle: this.options.onDragStyle,
|
||||||
|
onDropStyle: this.options.onDropStyle,
|
||||||
|
onDragClass: this.options.onDragClass,
|
||||||
|
onDragStart: (table, droppedRow) => this.onDropStart(table, droppedRow),
|
||||||
|
onDrop: (table, droppedRow) => this.onDrop(table, droppedRow),
|
||||||
|
dragHandle: this.options.dragHandle
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onDropStart (table, draggingTd) {
|
||||||
|
this.$draggingTd = $(draggingTd).css('cursor', 'move')
|
||||||
|
this.draggingIndex = $(this.$draggingTd.parent()).data('index')
|
||||||
|
// Call the user defined function
|
||||||
|
this.options.onReorderRowsDrag(this.data[this.draggingIndex])
|
||||||
|
}
|
||||||
|
|
||||||
|
onDrop (table) {
|
||||||
|
this.$draggingTd.css('cursor', '')
|
||||||
|
const newData = []
|
||||||
|
|
||||||
|
for (let i = 0; i < table.tBodies[0].rows.length; i++) {
|
||||||
|
const $tr = $(table.tBodies[0].rows[i])
|
||||||
|
|
||||||
|
newData.push(this.data[$tr.data('index')])
|
||||||
|
$tr.data('index', i)
|
||||||
|
}
|
||||||
|
|
||||||
|
const draggingRow = this.data[this.draggingIndex]
|
||||||
|
const droppedIndex = newData.indexOf(this.data[this.draggingIndex])
|
||||||
|
const droppedRow = this.data[droppedIndex]
|
||||||
|
const index = this.options.data.indexOf(this.data[droppedIndex])
|
||||||
|
|
||||||
|
this.options.data.splice(this.options.data.indexOf(draggingRow), 1)
|
||||||
|
this.options.data.splice(index, 0, draggingRow)
|
||||||
|
|
||||||
|
// Call the user defined function
|
||||||
|
this.options.onReorderRowsDrop(droppedRow)
|
||||||
|
|
||||||
|
// Call the event reorder-row
|
||||||
|
this.trigger('reorder-row', newData, draggingRow, droppedRow)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* @author: Dennis Hernández
|
||||||
|
* @webSite: http://djhvscf.github.io/Blog
|
||||||
|
* @version: v2.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
const isInit = that => that.$el.data('resizableColumns') !== undefined
|
||||||
|
|
||||||
|
const initResizable = that => {
|
||||||
|
if (
|
||||||
|
that.options.resizable &&
|
||||||
|
!that.options.cardView &&
|
||||||
|
!isInit(that) &&
|
||||||
|
that.$el.is(':visible')
|
||||||
|
) {
|
||||||
|
that.$el.resizableColumns({
|
||||||
|
store: window.store
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const destroy = that => {
|
||||||
|
if (isInit(that)) {
|
||||||
|
that.$el.data('resizableColumns').destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const reInitResizable = that => {
|
||||||
|
destroy(that)
|
||||||
|
initResizable(that)
|
||||||
|
}
|
||||||
|
|
||||||
|
$.extend($.fn.bootstrapTable.defaults, {
|
||||||
|
resizable: false
|
||||||
|
})
|
||||||
|
|
||||||
|
$.BootstrapTable = class extends $.BootstrapTable {
|
||||||
|
|
||||||
|
initBody (...args) {
|
||||||
|
super.initBody(...args)
|
||||||
|
|
||||||
|
this.$el.off('column-switch.bs.table page-change.bs.table')
|
||||||
|
.on('column-switch.bs.table page-change.bs.table', () => {
|
||||||
|
reInitResizable(this)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleView (...args) {
|
||||||
|
super.toggleView(...args)
|
||||||
|
|
||||||
|
if (this.options.resizable && this.options.cardView) {
|
||||||
|
// Destroy the plugin
|
||||||
|
destroy(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resetView (...args) {
|
||||||
|
super.resetView(...args)
|
||||||
|
|
||||||
|
if (this.options.resizable) {
|
||||||
|
// because in fitHeader function, we use setTimeout(func, 100);
|
||||||
|
setTimeout(() => {
|
||||||
|
initResizable(this)
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div th:include="include :: footer"></div>
|
<div th:include="include :: footer"></div>
|
||||||
<th:block th:include="include :: bootstrap-table-reorder-row-js" />
|
<th:block th:include="include :: bootstrap-table-reorder-rows-js" />
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
var prefix = ctx + "demo/table";
|
var prefix = ctx + "demo/table";
|
||||||
var datas = [[${@dict.getType('sys_normal_disable')}]];
|
var datas = [[${@dict.getType('sys_normal_disable')}]];
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||||
<link th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
|
<link th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
|
||||||
<!-- bootstrap-table 表格插件样式 -->
|
<!-- bootstrap-table 表格插件样式 -->
|
||||||
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=20210202}" rel="stylesheet"/>
|
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=20210602}" rel="stylesheet"/>
|
||||||
<link th:href="@{/css/animate.min.css}" rel="stylesheet"/>
|
<link th:href="@{/css/animate.min.css}" rel="stylesheet"/>
|
||||||
<link th:href="@{/css/style.min.css?v=20200903}" rel="stylesheet"/>
|
<link th:href="@{/css/style.min.css?v=20200903}" rel="stylesheet"/>
|
||||||
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.1}" rel="stylesheet"/>
|
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.6.1}" rel="stylesheet"/>
|
||||||
|
@ -23,15 +23,15 @@
|
||||||
<script th:src="@{/js/jquery.min.js}"></script>
|
<script th:src="@{/js/jquery.min.js}"></script>
|
||||||
<script th:src="@{/js/bootstrap.min.js}"></script>
|
<script th:src="@{/js/bootstrap.min.js}"></script>
|
||||||
<!-- bootstrap-table 表格插件 -->
|
<!-- bootstrap-table 表格插件 -->
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js?v=20210202}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js?v=20210602}"></script>
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/locale/bootstrap-table-zh-CN.min.js?v=20210202}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/locale/bootstrap-table-zh-CN.min.js?v=20210602}"></script>
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/mobile/bootstrap-table-mobile.min.js?v=20210202}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/mobile/bootstrap-table-mobile.js?v=20210602}"></script>
|
||||||
<!-- jquery-validate 表单验证插件 -->
|
<!-- jquery-validate 表单验证插件 -->
|
||||||
<script th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
|
<script th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
|
||||||
<script th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
|
<script th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
|
||||||
<script th:src="@{/ajax/libs/validate/jquery.validate.extend.js}"></script>
|
<script th:src="@{/ajax/libs/validate/jquery.validate.extend.js}"></script>
|
||||||
<!-- jquery-validate 表单树插件 -->
|
<!-- jquery-validate 表单树插件 -->
|
||||||
<script th:src="@{/ajax/libs/bootstrap-treetable/bootstrap-treetable.min.js?v=20210526}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/tree/bootstrap-table-tree.min.js?v=20210602}"></script>
|
||||||
<!-- 遮罩层 -->
|
<!-- 遮罩层 -->
|
||||||
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
|
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
|
||||||
<script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
|
<script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
|
||||||
|
@ -171,21 +171,21 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格行拖拽插件 -->
|
<!-- 表格行拖拽插件 -->
|
||||||
<div th:fragment="bootstrap-table-reorder-row-js">
|
<div th:fragment="bootstrap-table-reorder-rows-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-row/bootstrap-table-reorder.js}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-rows/bootstrap-table-reorder-rows.js?v=20210602}"></script>
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-row/jquery.tablednd.js}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-rows/jquery.tablednd.js}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格列拖拽插件 -->
|
<!-- 表格列拖拽插件 -->
|
||||||
<div th:fragment="bootstrap-table-reorder-columns-js">
|
<div th:fragment="bootstrap-table-reorder-columns-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-columns/jquery.dragtable.js}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-columns/jquery.dragtable.js}"></script>
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-columns/bootstrap-table-reorder.min.js?v=20210203}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder-columns/bootstrap-table-reorder-columns.js?v=20210602}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格列宽拖动插件 -->
|
<!-- 表格列宽拖动插件 -->
|
||||||
<div th:fragment="bootstrap-table-resizable-js">
|
<div th:fragment="bootstrap-table-resizable-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/jquery.resizableColumns.min.js}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/jquery.resizableColumns.min.js}"></script>
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/bootstrap-table-resizable.min.js?v=20210202}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/resizable/bootstrap-table-resizable.js?v=20210602}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格行内编辑插件 -->
|
<!-- 表格行内编辑插件 -->
|
||||||
|
@ -194,26 +194,26 @@
|
||||||
</div>
|
</div>
|
||||||
<div th:fragment="bootstrap-table-editable-js">
|
<div th:fragment="bootstrap-table-editable-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js}"></script>
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-table-editable.min.js?v=20210202}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/editable/bootstrap-table-editable.js?v=20210602}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格导出插件 -->
|
<!-- 表格导出插件 -->
|
||||||
<div th:fragment="bootstrap-table-export-js">
|
<div th:fragment="bootstrap-table-export-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/bootstrap-table-export.min.js?v=20210523}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/bootstrap-table-export.js?v=20210602}"></script>
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/tableExport.min.js?v=20210523}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/export/tableExport.min.js}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格冻结列插件 -->
|
<!-- 表格冻结列插件 -->
|
||||||
<div th:fragment="bootstrap-table-fixed-columns-js">
|
<div th:fragment="bootstrap-table-fixed-columns-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.min.js?v=20210202}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js?v=20210602}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格自动刷新插件 -->
|
<!-- 表格自动刷新插件 -->
|
||||||
<div th:fragment="bootstrap-table-auto-refresh-js">
|
<div th:fragment="bootstrap-table-auto-refresh-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js?v=20210202}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js?v=20210602}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格打印插件 -->
|
<!-- 表格打印插件 -->
|
||||||
<div th:fragment="bootstrap-table-print-js">
|
<div th:fragment="bootstrap-table-print-js">
|
||||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/print/bootstrap-table-print.min.js?v=20200729}"></script>
|
<script th:src="@{/ajax/libs/bootstrap-table/extensions/print/bootstrap-table-print.js?v=20210602}"></script>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -257,7 +257,7 @@
|
||||||
</section>
|
</section>
|
||||||
<th:block th:include="include :: footer" />
|
<th:block th:include="include :: footer" />
|
||||||
<th:block th:include="include :: select2-js" />
|
<th:block th:include="include :: select2-js" />
|
||||||
<th:block th:include="include :: bootstrap-table-reorder-row-js" />
|
<th:block th:include="include :: bootstrap-table-reorder-rows-js" />
|
||||||
<script th:src="@{/js/jquery.tmpl.js}"></script>
|
<script th:src="@{/js/jquery.tmpl.js}"></script>
|
||||||
<th:block th:include="include :: jquery-cxselect-js" />
|
<th:block th:include="include :: jquery-cxselect-js" />
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
|
|
Loading…
Reference in New Issue