Use autocomplete instead of dropdown for grid "add filter"

This commit is contained in:
Lance Edgar 2023-10-10 22:01:46 -05:00
parent 4328b9e385
commit 78deb5d09a
2 changed files with 80 additions and 19 deletions

View file

@ -358,7 +358,6 @@
let ${grid.component_studly}Data = { let ${grid.component_studly}Data = {
loading: false, loading: false,
selectedFilter: null,
ajaxDataUrl: ${json.dumps(grid.ajax_data_url)|n}, ajaxDataUrl: ${json.dumps(grid.ajax_data_url)|n},
data: ${grid.component_studly}CurrentData, data: ${grid.component_studly}CurrentData,
@ -401,7 +400,8 @@
## filterable: ${json.dumps(grid.filterable)|n}, ## filterable: ${json.dumps(grid.filterable)|n},
filters: ${json.dumps(filters_data if grid.filterable else None)|n}, filters: ${json.dumps(filters_data if grid.filterable else None)|n},
filtersSequence: ${json.dumps(filters_sequence if grid.filterable else None)|n}, filtersSequence: ${json.dumps(filters_sequence if grid.filterable else None)|n},
selectedFilter: null, addFilterTerm: '',
addFilterShow: false,
## dummy input value needed for sharing links on *insecure* sites ## dummy input value needed for sharing links on *insecure* sites
% if request.scheme == 'http': % if request.scheme == 'http':
@ -420,6 +420,39 @@
computed: { computed: {
addFilterChoices() {
// collect all filters, which are *not* already shown
let choices = []
for (let field of this.filtersSequence) {
let filtr = this.filters[field]
if (!filtr.visible) {
choices.push(filtr)
}
}
// parse list of search terms
let terms = []
for (let term of this.addFilterTerm.toLowerCase().split(' ')) {
term = term.trim()
if (term) {
terms.push(term)
}
}
// only filters matching all search terms are presented
// as choices to the user
return choices.filter(option => {
let label = option.label.toLowerCase()
for (let term of terms) {
if (label.indexOf(term) < 0) {
return false
}
}
return true
})
},
// note, can use this with v-model for hidden 'uuids' fields // note, can use this with v-model for hidden 'uuids' fields
selected_uuids: function() { selected_uuids: function() {
return this.checkedRowUUIDs().join(',') return this.checkedRowUUIDs().join(',')
@ -644,12 +677,29 @@
location.href = url location.href = url
}, },
addFilter(filter_key) { addFilterButton(event) {
this.addFilterShow = true
// reset dropdown so user again sees "Add Filter" placeholder this.$nextTick(() => {
this.$nextTick(function() { this.$refs.addFilterAutocomplete.focus()
this.selectedFilter = null
}) })
},
addFilterKeydown(event) {
// ESC will clear searchbox
if (event.which == 27) {
this.addFilterTerm = ''
this.addFilterShow = false
}
},
addFilterSelect(filtr) {
this.addFilter(filtr.key)
this.addFilterTerm = ''
this.addFilterShow = false
},
addFilter(filter_key) {
// show corresponding grid filter // show corresponding grid filter
this.filters[filter_key].visible = true this.filters[filter_key].visible = true

View file

@ -18,18 +18,29 @@
Apply Filters Apply Filters
</b-button> </b-button>
<b-select @input="addFilter" <b-button v-if="!addFilterShow"
icon-pack="fas"
icon-left="plus"
class="control"
@click="addFilterButton">
Add Filter
</b-button>
<b-autocomplete v-if="addFilterShow"
ref="addFilterAutocomplete"
:data="addFilterChoices"
v-model="addFilterTerm"
placeholder="Add Filter" placeholder="Add Filter"
v-model="selectedFilter"> field="key"
<option v-for="key in filtersSequence" :custom-formatter="filtr => filtr.label"
:key="key" open-on-focus
:value="key" keep-first
## TODO: previous code here was simpler; trying to track down icon-pack="fas"
## why disabled options don't appear so on Windows Chrome (?) clearable
:disabled="filters[key].visible ? 'disabled' : null"> clear-on-select
{{ filters[key].label }} @select="addFilterSelect"
</option> @keydown.native="addFilterKeydown">
</b-select> </b-autocomplete>
<b-button @click="resetView()" <b-button @click="resetView()"
icon-pack="fas" icon-pack="fas"