diff --git a/site/docs/extensions/filter-control.md b/site/docs/extensions/filter-control.md index 00d9e0acda..472293d9ba 100644 --- a/site/docs/extensions/filter-control.md +++ b/site/docs/extensions/filter-control.md @@ -273,13 +273,37 @@ toc: true ## Events -### onColumnSearch(column-search.bs.table) +### onColumnSearch -* Fired when we are searching into the column data +- **jQuery Event:** `column-search.bs.table` -### onCreatedControls(created-controls.bs.table) +- **Parameter:** `` -* Fired when we are searching into the column data +- **Detail:** + + Fired when we are searching into the column data. + +### onCreatedControls + +- **jQuery Event:** `created-controls.bs.table` + +- **Parameter:** `` + +- **Detail:** + + Fired when we are searching into the column data. + +### onOptionsAdded + +- **jQuery Event:** `options-added.bs.table` + +- **Parameter:** `selectControl` + +- **Detail:** + + Fired when the options are added to a select control. The parameters contain: + + * `selectControl`: the select control where the options were added. ## Methods diff --git a/src/extensions/filter-control/bootstrap-table-filter-control.js b/src/extensions/filter-control/bootstrap-table-filter-control.js index 84ac6585c5..606ecc9d90 100644 --- a/src/extensions/filter-control/bootstrap-table-filter-control.js +++ b/src/extensions/filter-control/bootstrap-table-filter-control.js @@ -80,7 +80,8 @@ $.extend($.fn.bootstrapTable.columnDefaults, { $.extend($.fn.bootstrapTable.Constructor.EVENTS, { 'column-search.bs.table': 'onColumnSearch', - 'created-controls.bs.table': 'onCreatedControls' + 'created-controls.bs.table': 'onCreatedControls', + 'options-added.bs.table': 'onOptionsAdded' }) $.extend($.fn.bootstrapTable.defaults.icons, { @@ -171,10 +172,10 @@ $.BootstrapTable = class extends $.BootstrapTable { if (!this.options.filterControl) { return } - setTimeout(() => { + Utils.debounce(() => { UtilsFilterControl.initFilterSelectControls(this) UtilsFilterControl.setValues(this) - }, 3) + }, 3)() } load (data) { @@ -412,7 +413,6 @@ $.BootstrapTable = class extends $.BootstrapTable { const controls = UtilsFilterControl.getSearchControls(that) // const search = Utils.getSearchInput(this) let hasValues = false - let timeoutId = 0 // Clear cache values $.each(that._valuesFilterControl, (i, item) => { @@ -429,8 +429,7 @@ $.BootstrapTable = class extends $.BootstrapTable { UtilsFilterControl.setValues(that) // clear cookies once the filters are clean - clearTimeout(timeoutId) - timeoutId = setTimeout(() => { + Utils.debounce(() => { if (cookies && cookies.length > 0) { $.each(cookies, (i, item) => { if (that.deleteCookie !== undefined) { @@ -438,7 +437,7 @@ $.BootstrapTable = class extends $.BootstrapTable { } }) } - }, that.options.searchTimeOut) + }, that.options.searchTimeOut)() // If there is not any value in the controls exit this method if (!hasValues) { diff --git a/src/extensions/filter-control/utils.js b/src/extensions/filter-control/utils.js index a32a273c35..740aef1fe8 100644 --- a/src/extensions/filter-control/utils.js +++ b/src/extensions/filter-control/utils.js @@ -48,12 +48,16 @@ export function hideUnusedSelectOptions (selectControl, uniqueValues) { export function existOptionInSelectControl (selectControl, value) { const options = getOptionsFromSelectControl(selectControl) + const _value = Utils.unescapeHTML(value) + const len = options.length + let i = 0 - for (let i = 0; i < options.length; i++) { - if (options[i].value === Utils.unescapeHTML(value)) { + while (i < len) { + if (options[i].value === _value) { // The value is not valid to add return true } + i++ } // If we get here, the value is valid to add @@ -61,9 +65,8 @@ export function existOptionInSelectControl (selectControl, value) { } export function addOptionToSelectControl (selectControl, _value, text, selected, shouldCompareText) { - let value = (_value === undefined || _value === null) ? '' : _value.toString().trim() + const value = (_value === undefined || _value === null) ? '' : Utils.removeHTML(_value.toString().trim()) - value = Utils.removeHTML(value) text = Utils.removeHTML(text) if (existOptionInSelectControl(selectControl, value)) { @@ -293,51 +296,53 @@ export function initFilterSelectControls (that) { const column = that.columns[that.fieldsColumnsIndex[field]] const selectControl = getControlContainer(that).find(`select.bootstrap-table-filter-control-${escapeID(column.field)}`) - if (isColumnSearchableViaSelect(column) && isFilterDataNotGiven(column) && hasSelectControlElement(selectControl)) { - if (!selectControl[0].multiple && selectControl.get(selectControl.length - 1).options.length === 0) { - // Added the default option, must use a non-breaking space( ) to pass the W3C validator - addOptionToSelectControl(selectControl, '', column.filterControlPlaceholder || ' ', column.filterDefault) - } - - const uniqueValues = {} + if (!isColumnSearchableViaSelect(column) || !isFilterDataNotGiven(column) || !hasSelectControlElement(selectControl)) { + return + } - for (let i = 0; i < data.length; i++) { - // Added a new value - let fieldValue = Utils.getItemField(data[i], field, false) - const formatter = that.options.editable && column.editable ? column._formatter : that.header.formatters[j] - let formattedValue = Utils.calculateObjectValue(that.header, formatter, [fieldValue, data[i], i], fieldValue) + if (!selectControl[0].multiple && selectControl[0].options.length === 0) { + // Added the default option, must use a non-breaking space( ) to pass the W3C validator + addOptionToSelectControl(selectControl, '', column.filterControlPlaceholder || ' ', column.filterDefault) + } - if (!fieldValue) { - fieldValue = formattedValue - column._forceFormatter = true - } + const uniqueValues = {} - if (column.filterDataCollector) { - formattedValue = Utils.calculateObjectValue(that.header, column.filterDataCollector, [fieldValue, data[i], formattedValue], formattedValue) - } + for (let i = 0; i < data.length; i++) { + // Added a new value + let fieldValue = Utils.getItemField(data[i], field, false) + const formatter = that.options.editable && column.editable ? column._formatter : that.header.formatters[j] + let formattedValue = Utils.calculateObjectValue(that.header, formatter, [fieldValue, data[i], i], fieldValue) - if (column.searchFormatter) { - fieldValue = formattedValue - } - uniqueValues[formattedValue] = fieldValue + if (!fieldValue) { + fieldValue = formattedValue + column._forceFormatter = true + } - if (typeof formattedValue === 'object' && formattedValue !== null) { - formattedValue.forEach(value => { - addOptionToSelectControl(selectControl, value, value, column.filterDefault) - }) - continue - } + if (column.filterDataCollector) { + formattedValue = Utils.calculateObjectValue(that.header, column.filterDataCollector, [fieldValue, data[i], formattedValue], formattedValue) } - // eslint-disable-next-line guard-for-in - for (const key in uniqueValues) { - addOptionToSelectControl(selectControl, uniqueValues[key], key, column.filterDefault) + if (column.searchFormatter) { + fieldValue = formattedValue } + uniqueValues[formattedValue] = fieldValue - if (that.options.sortSelectOptions) { - sortSelectControl(selectControl, 'asc', that.options) + if (typeof formattedValue === 'object' && formattedValue !== null) { + formattedValue.forEach(value => { + addOptionToSelectControl(selectControl, value, value, column.filterDefault) + }) } } + + for (const key of Object.keys(uniqueValues)) { + addOptionToSelectControl(selectControl, uniqueValues[key], key, column.filterDefault) + } + + that.trigger('options-added', selectControl) + + if (that.options.sortSelectOptions) { + sortSelectControl(selectControl, 'asc', that.options) + } }) } @@ -459,10 +464,9 @@ export function createControls (that, header) { return } - clearTimeout(currentTarget.timeoutId || 0) - currentTarget.timeoutId = setTimeout(() => { + Utils.debounce(() => { that.onColumnSearch({ currentTarget, keyCode }) - }, that.options.searchTimeOut) + }, that.options.searchTimeOut)() }) header.off('change', 'select', '.fc-multipleselect').on('change', 'select', '.fc-multipleselect', ({ currentTarget, keyCode }) => { @@ -483,10 +487,9 @@ export function createControls (that, header) { $selectControl.find('option[selected]').removeAttr('selected') } - clearTimeout(currentTarget.timeoutId || 0) - currentTarget.timeoutId = setTimeout(() => { + Utils.debounce(() => { that.onColumnSearch({ currentTarget, keyCode }) - }, that.options.searchTimeOut) + }, that.options.searchTimeOut)() }) header.off('mouseup', 'input:not([type=radio])').on('mouseup', 'input:not([type=radio])', ({ currentTarget, keyCode }) => { @@ -497,23 +500,21 @@ export function createControls (that, header) { return } - setTimeout(() => { + Utils.debounce(() => { const newValue = $input.val() if (newValue === '') { - clearTimeout(currentTarget.timeoutId || 0) - currentTarget.timeoutId = setTimeout(() => { + Utils.debounce(() => { that.onColumnSearch({ currentTarget, keyCode }) }, that.options.searchTimeOut) } - }, 1) + }, 1)() }) header.off('change', 'input[type=radio]').on('change', 'input[type=radio]', ({ currentTarget, keyCode }) => { - clearTimeout(currentTarget.timeoutId || 0) - currentTarget.timeoutId = setTimeout(() => { + Utils.debounce(() => { that.onColumnSearch({ currentTarget, keyCode }) - }, that.options.searchTimeOut) + }, that.options.searchTimeOut)() }) // See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date @@ -543,10 +544,9 @@ export function createControls (that, header) { } $datepicker.on('change', ({ currentTarget }) => { - clearTimeout(currentTarget.timeoutId || 0) - currentTarget.timeoutId = setTimeout(() => { + Utils.debounce(() => { that.onColumnSearch({ currentTarget }) - }, that.options.searchTimeOut) + }, that.options.searchTimeOut)() }) } })