|
@@ -946,11 +946,12 @@ class BootstrapTable {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let s = this.searchText && (this.fromHtml ? Utils.escapeHTML(this.searchText) : this.searchText).toLowerCase()
|
|
|
|
|
|
|
+ const rawSearchText = this.searchText && (this.fromHtml ? Utils.escapeHTML(this.searchText) : this.searchText)
|
|
|
|
|
+ let searchText = rawSearchText.toLowerCase()
|
|
|
const f = Utils.isEmptyObject(this.filterColumns) ? null : this.filterColumns
|
|
const f = Utils.isEmptyObject(this.filterColumns) ? null : this.filterColumns
|
|
|
|
|
|
|
|
if (this.options.searchAccentNeutralise) {
|
|
if (this.options.searchAccentNeutralise) {
|
|
|
- s = Utils.normalizeAccent(s)
|
|
|
|
|
|
|
+ searchText = Utils.normalizeAccent(searchText)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Check filter
|
|
// Check filter
|
|
@@ -994,7 +995,7 @@ class BootstrapTable {
|
|
|
|
|
|
|
|
const visibleFields = this.getVisibleFields()
|
|
const visibleFields = this.getVisibleFields()
|
|
|
|
|
|
|
|
- this.data = s ? this.data.filter((item, i) => {
|
|
|
|
|
|
|
+ this.data = searchText ? this.data.filter((item, i) => {
|
|
|
for (let j = 0; j < this.header.fields.length; j++) {
|
|
for (let j = 0; j < this.header.fields.length; j++) {
|
|
|
if (!this.header.searchables[j] || (this.options.visibleSearch && visibleFields.indexOf(this.header.fields[j]) === -1)) {
|
|
if (!this.header.searchables[j] || (this.options.visibleSearch && visibleFields.indexOf(this.header.fields[j]) === -1)) {
|
|
|
continue
|
|
continue
|
|
@@ -1028,51 +1029,52 @@ class BootstrapTable {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (typeof value === 'string' || typeof value === 'number') {
|
|
if (typeof value === 'string' || typeof value === 'number') {
|
|
|
- if (this.options.strictSearch) {
|
|
|
|
|
- if ((`${value}`).toLowerCase() === s) {
|
|
|
|
|
- return true
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- const largerSmallerEqualsRegex = /(?:(<=|=>|=<|>=|>|<)(?:\s+)?(-?\d+)?|(-?\d+)?(\s+)?(<=|=>|=<|>=|>|<))/gm
|
|
|
|
|
- const matches = largerSmallerEqualsRegex.exec(this.searchText)
|
|
|
|
|
- let comparisonCheck = false
|
|
|
|
|
-
|
|
|
|
|
- if (matches) {
|
|
|
|
|
- const operator = matches[1] || `${matches[5]}l`
|
|
|
|
|
- const comparisonValue = matches[2] || matches[3]
|
|
|
|
|
- const int = parseInt(value, 10)
|
|
|
|
|
- const comparisonInt = parseInt(comparisonValue, 10)
|
|
|
|
|
-
|
|
|
|
|
- switch (operator) {
|
|
|
|
|
- case '>':
|
|
|
|
|
- case '<l':
|
|
|
|
|
- comparisonCheck = int > comparisonInt
|
|
|
|
|
- break
|
|
|
|
|
- case '<':
|
|
|
|
|
- case '>l':
|
|
|
|
|
- comparisonCheck = int < comparisonInt
|
|
|
|
|
- break
|
|
|
|
|
- case '<=':
|
|
|
|
|
- case '=<':
|
|
|
|
|
- case '>=l':
|
|
|
|
|
- case '=>l':
|
|
|
|
|
- comparisonCheck = int <= comparisonInt
|
|
|
|
|
- break
|
|
|
|
|
- case '>=':
|
|
|
|
|
- case '=>':
|
|
|
|
|
- case '<=l':
|
|
|
|
|
- case '=<l':
|
|
|
|
|
- comparisonCheck = int >= comparisonInt
|
|
|
|
|
- break
|
|
|
|
|
- default:
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (
|
|
|
|
|
+ this.options.strictSearch && (`${value}`).toLowerCase() === searchText ||
|
|
|
|
|
+ (this.options.regexSearch && Utils.regexCompare(value, rawSearchText))
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (comparisonCheck || (`${value}`).toLowerCase().includes(s)) {
|
|
|
|
|
- return true
|
|
|
|
|
|
|
+ const largerSmallerEqualsRegex = /(?:(<=|=>|=<|>=|>|<)(?:\s+)?(-?\d+)?|(-?\d+)?(\s+)?(<=|=>|=<|>=|>|<))/gm
|
|
|
|
|
+ const matches = largerSmallerEqualsRegex.exec(this.searchText)
|
|
|
|
|
+ let comparisonCheck = false
|
|
|
|
|
+
|
|
|
|
|
+ if (matches) {
|
|
|
|
|
+ const operator = matches[1] || `${matches[5]}l`
|
|
|
|
|
+ const comparisonValue = matches[2] || matches[3]
|
|
|
|
|
+ const int = parseInt(value, 10)
|
|
|
|
|
+ const comparisonInt = parseInt(comparisonValue, 10)
|
|
|
|
|
+
|
|
|
|
|
+ switch (operator) {
|
|
|
|
|
+ case '>':
|
|
|
|
|
+ case '<l':
|
|
|
|
|
+ comparisonCheck = int > comparisonInt
|
|
|
|
|
+ break
|
|
|
|
|
+ case '<':
|
|
|
|
|
+ case '>l':
|
|
|
|
|
+ comparisonCheck = int < comparisonInt
|
|
|
|
|
+ break
|
|
|
|
|
+ case '<=':
|
|
|
|
|
+ case '=<':
|
|
|
|
|
+ case '>=l':
|
|
|
|
|
+ case '=>l':
|
|
|
|
|
+ comparisonCheck = int <= comparisonInt
|
|
|
|
|
+ break
|
|
|
|
|
+ case '>=':
|
|
|
|
|
+ case '=>':
|
|
|
|
|
+ case '<=l':
|
|
|
|
|
+ case '=<l':
|
|
|
|
|
+ comparisonCheck = int >= comparisonInt
|
|
|
|
|
+ break
|
|
|
|
|
+ default:
|
|
|
|
|
+ break
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if (comparisonCheck || (`${value}`).toLowerCase().includes(searchText)) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
return false
|
|
return false
|
|
@@ -1658,7 +1660,7 @@ class BootstrapTable {
|
|
|
return html.join('')
|
|
return html.join('')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- initBody (fixedScroll) {
|
|
|
|
|
|
|
+ initBody (fixedScroll, updatedUid) {
|
|
|
const data = this.getData()
|
|
const data = this.getData()
|
|
|
|
|
|
|
|
this.trigger('pre-body', data)
|
|
this.trigger('pre-body', data)
|
|
@@ -1677,15 +1679,35 @@ class BootstrapTable {
|
|
|
const rows = []
|
|
const rows = []
|
|
|
const trFragments = $(document.createDocumentFragment())
|
|
const trFragments = $(document.createDocumentFragment())
|
|
|
let hasTr = false
|
|
let hasTr = false
|
|
|
|
|
+ const toExpand = []
|
|
|
|
|
|
|
|
this.autoMergeCells = Utils.checkAutoMergeCells(data.slice(this.pageFrom - 1, this.pageTo))
|
|
this.autoMergeCells = Utils.checkAutoMergeCells(data.slice(this.pageFrom - 1, this.pageTo))
|
|
|
|
|
|
|
|
for (let i = this.pageFrom - 1; i < this.pageTo; i++) {
|
|
for (let i = this.pageFrom - 1; i < this.pageTo; i++) {
|
|
|
const item = data[i]
|
|
const item = data[i]
|
|
|
- const tr = this.initRow(item, i, data, trFragments)
|
|
|
|
|
|
|
+ let tr = this.initRow(item, i, data, trFragments)
|
|
|
|
|
|
|
|
hasTr = hasTr || !!tr
|
|
hasTr = hasTr || !!tr
|
|
|
if (tr && typeof tr === 'string') {
|
|
if (tr && typeof tr === 'string') {
|
|
|
|
|
+
|
|
|
|
|
+ const uniqueId = this.options.uniqueId
|
|
|
|
|
+
|
|
|
|
|
+ if (uniqueId && item.hasOwnProperty(uniqueId)) {
|
|
|
|
|
+ const itemUniqueId = item[uniqueId]
|
|
|
|
|
+
|
|
|
|
|
+ const oldTr = this.$body.find(Utils.sprintf('> tr[data-uniqueid="%s"][data-has-detail-view]', itemUniqueId))
|
|
|
|
|
+ const oldTrNext = oldTr.next()
|
|
|
|
|
+
|
|
|
|
|
+ if (oldTrNext.is('tr.detail-view')) {
|
|
|
|
|
+
|
|
|
|
|
+ toExpand.push(i)
|
|
|
|
|
+
|
|
|
|
|
+ if (!updatedUid || itemUniqueId !== updatedUid) {
|
|
|
|
|
+ tr += oldTrNext[0].outerHTML
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (!this.options.virtualScroll) {
|
|
if (!this.options.virtualScroll) {
|
|
|
trFragments.append(tr)
|
|
trFragments.append(tr)
|
|
|
} else {
|
|
} else {
|
|
@@ -1718,6 +1740,8 @@ class BootstrapTable {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ toExpand.forEach(index => { this.expandRow(index) })
|
|
|
|
|
+
|
|
|
if (!fixedScroll) {
|
|
if (!fixedScroll) {
|
|
|
this.scrollTo(0)
|
|
this.scrollTo(0)
|
|
|
}
|
|
}
|
|
@@ -2549,6 +2573,7 @@ class BootstrapTable {
|
|
|
|
|
|
|
|
updateByUniqueId (params) {
|
|
updateByUniqueId (params) {
|
|
|
const allParams = Array.isArray(params) ? params : [params]
|
|
const allParams = Array.isArray(params) ? params : [params]
|
|
|
|
|
+ let updatedUid = null
|
|
|
|
|
|
|
|
for (const params of allParams) {
|
|
for (const params of allParams) {
|
|
|
if (!params.hasOwnProperty('id') || !params.hasOwnProperty('row')) {
|
|
if (!params.hasOwnProperty('id') || !params.hasOwnProperty('row')) {
|
|
@@ -2566,12 +2591,13 @@ class BootstrapTable {
|
|
|
} else {
|
|
} else {
|
|
|
$.extend(this.options.data[rowId], params.row)
|
|
$.extend(this.options.data[rowId], params.row)
|
|
|
}
|
|
}
|
|
|
|
|
+ updatedUid = params.id
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
this.initSearch()
|
|
this.initSearch()
|
|
|
this.initPagination()
|
|
this.initPagination()
|
|
|
this.initSort()
|
|
this.initSort()
|
|
|
- this.initBody(true)
|
|
|
|
|
|
|
+ this.initBody(true, updatedUid)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
removeByUniqueId (id) {
|
|
removeByUniqueId (id) {
|
|
@@ -3150,14 +3176,14 @@ class BootstrapTable {
|
|
|
const row = this.data[index]
|
|
const row = this.data[index]
|
|
|
const $tr = this.$body.find(Utils.sprintf('> tr[data-index="%s"][data-has-detail-view]', index))
|
|
const $tr = this.$body.find(Utils.sprintf('> tr[data-index="%s"][data-has-detail-view]', index))
|
|
|
|
|
|
|
|
- if ($tr.next().is('tr.detail-view')) {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (this.options.detailViewIcon) {
|
|
if (this.options.detailViewIcon) {
|
|
|
$tr.find('a.detail-icon').html(Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, this.options.icons.detailClose))
|
|
$tr.find('a.detail-icon').html(Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, this.options.icons.detailClose))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if ($tr.next().is('tr.detail-view')) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
$tr.after(Utils.sprintf('<tr class="detail-view"><td colspan="%s"></td></tr>', $tr.children('td').length))
|
|
$tr.after(Utils.sprintf('<tr class="detail-view"><td colspan="%s"></td></tr>', $tr.children('td').length))
|
|
|
|
|
|
|
|
const $element = $tr.next().find('td')
|
|
const $element = $tr.next().find('td')
|