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

@ -830,10 +830,10 @@ class Grid(object):
if self.sortable:
self.active_sorters = []
for i in range(1, settings['sorters.length'] + 1):
self.active_sorters.append((
settings[f'sorters.{i}.key'],
settings[f'sorters.{i}.dir'],
))
self.active_sorters.append({
'field': settings[f'sorters.{i}.key'],
'order': settings[f'sorters.{i}.dir'],
})
if self.pageable:
self.pagesize = settings['pagesize']
self.page = settings['page']
@ -1229,28 +1229,52 @@ class Grid(object):
if not self.active_sorters:
return data
# convert sort settings into a 'sortspec' for use with sa-filters
full_spec = []
for sortkey, sortdir in self.active_sorters:
sortfunc = self.sorters.get(sortkey)
if sortfunc:
spec = {
'sortkey': sortkey,
'model': sortfunc._class.__name__,
'field': sortfunc._column.name,
'direction': sortdir or 'asc',
}
# spec.sortkey = sortkey
full_spec.append(spec)
# TODO: is there a better way to check for SA sorting?
if self.model_class:
# apply joins needed for this sort spec
for spec in full_spec:
sortkey = spec['sortkey']
# convert sort settings into a 'sortspec' for use with sa-filters
full_spec = []
for sorter in self.active_sorters:
sortkey = sorter['field']
sortdir = sorter['order']
sortfunc = self.sorters.get(sortkey)
if sortfunc:
spec = {
'sortkey': sortkey,
'model': sortfunc._class.__name__,
'field': sortfunc._column.name,
'direction': sortdir or 'asc',
}
full_spec.append(spec)
# apply joins needed for this sort spec
for spec in full_spec:
sortkey = spec['sortkey']
if sortkey in self.joiners and sortkey not in self.joined:
data = self.joiners[sortkey](data)
self.joined.add(sortkey)
return apply_sort(data, full_spec)
else:
# not a SQLAlchemy grid, custom sorter
assert len(self.active_sorters) < 2
sortkey = self.active_sorters[0]['field']
sortdir = self.active_sorters[0]['order'] or 'asc'
# Cannot sort unless we have a sort function.
sortfunc = self.sorters.get(sortkey)
if not sortfunc:
return data
# apply joins needed for this sorter
if sortkey in self.joiners and sortkey not in self.joined:
data = self.joiners[sortkey](data)
self.joined.add(sortkey)
return apply_sort(data, full_spec)
return sortfunc(data, sortdir)
def paginate_data(self, data):
"""