Add front-end support for multi-column grid sorting

user must ctrl-click column header to engage multi-sort
This commit is contained in:
Lance Edgar 2023-10-08 16:38:13 -05:00
parent 6d7754cf2a
commit edb5393cdc
2 changed files with 128 additions and 30 deletions

View file

@ -202,9 +202,25 @@
% endif
% if grid.sortable:
:default-sort="sortingPriority[0]"
backend-sorting
@sort="onSort"
backend-sorting
@sort="onSort"
@sorting-priority-removed="sortingPriorityRemoved"
## TODO: there is a bug (?) which prevents the arrow from
## displaying for simple default single-column sort. so to
## work around that, we *disable* multi-sort until the
## component is mounted. seems to work for now..see also
## https://github.com/buefy/buefy/issues/2584
:sort-multiple="allowMultiSort"
## nb. specify default sort only if single-column
:default-sort="backendSorters.length == 1 ? [backendSorters[0].field, backendSorters[0].order] : null"
## nb. otherwise there may be default multi-column sort
:sort-multiple-data="sortingPriority"
## user must ctrl-click column header to do multi-sort
sort-multiple-key="ctrlKey"
% endif
% if grid.click_handlers:
@ -353,7 +369,25 @@
lastItem: ${json.dumps(grid_data['last_item'] if grid.pageable else None)|n},
% if grid.sortable:
sortingPriority: ${json.dumps(grid.active_sorters)|n},
## TODO: there is a bug (?) which prevents the arrow from
## displaying for simple default single-column sort. so to
## work around that, we *disable* multi-sort until the
## component is mounted. seems to work for now..see also
## https://github.com/buefy/buefy/issues/2584
allowMultiSort: false,
## nb. this contains all truly active sorters
backendSorters: ${json.dumps(grid.active_sorters)|n},
## nb. whereas this will only contain multi-column sorters,
## but will be *empty* for single-column sorting
% if len(grid.active_sorters) > 1:
sortingPriority: ${json.dumps(grid.active_sorters)|n},
% else:
sortingPriority: [],
% endif
% endif
## filterable: ${json.dumps(grid.filterable)|n},
@ -395,6 +429,15 @@
},
},
mounted() {
## TODO: there is a bug (?) which prevents the arrow from
## displaying for simple default single-column sort. so to
## work around that, we *disable* multi-sort until the
## component is mounted. seems to work for now..see also
## https://github.com/buefy/buefy/issues/2584
this.allowMultiSort = true
},
methods: {
% if grid.click_handlers:
@ -455,9 +498,9 @@
getBasicParams() {
let params = {}
% if grid.sortable:
for (let i = 1; i <= this.sortingPriority.length; i++) {
params['sort'+i+'key'] = this.sortingPriority[i-1][0]
params['sort'+i+'dir'] = this.sortingPriority[i-1][1]
for (let i = 1; i <= this.backendSorters.length; i++) {
params['sort'+i+'key'] = this.backendSorters[i-1].field
params['sort'+i+'dir'] = this.backendSorters[i-1].order
}
% endif
% if grid.pageable:
@ -537,14 +580,45 @@
this.loadAsyncData()
},
onSort(field, order) {
this.sortingPriority = [[field, order]]
onSort(field, order, event) {
if (event.ctrlKey) {
// engage or enhance multi-column sorting
let sorter = this.backendSorters.filter(i => i.field === field)[0]
if (sorter) {
sorter.order = sorter.order === 'desc' ? 'asc' : 'desc'
} else {
this.backendSorters.push({field, order})
}
this.sortingPriority = this.backendSorters
} else {
// sort by single column only
this.backendSorters = [{field, order}]
this.sortingPriority = []
}
// always reset to first page when changing sort options
// TODO: i mean..right? would we ever not want that?
this.currentPage = 1
this.loadAsyncData()
},
sortingPriorityRemoved(field) {
// prune field from active sorters
this.backendSorters = this.backendSorters.filter(
(sorter) => sorter.field !== field)
// nb. must keep active sorter list "as-is" even if
// there is only one sorter; buefy seems to expect it
this.sortingPriority = this.backendSorters
this.loadAsyncData()
},
resetView() {
this.loading = true