Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions homedocs/src/pages/docs/tables/grid.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,10 @@ See also: [Row Drag and Drop](/docs/tables/row-drag-and-drop)
| `header` | `string \| object` | Text or configuration object for the column header. |
| `format` | `string` | Format string for cell values. |
| `align` | `string` | Column alignment: `left`, `right`, or `center`. |
| `value` | `selector` | Selector (binding, template, expression or computable) for the displayed cell value. Use it for computed values or columns without a direct record field. |
| `sortable` | `boolean` | Set to `true` to make the column sortable. |
| `sortField` | `string` | Alternative field used for sorting. |
| `sortValue` | `selector` | Selector used for sorting instead of the field or the displayed value. Takes precedence over all other sort sources. |
| `primarySortDirection` | `string` | Initial sort direction on first click: `ASC` or `DESC`. |
| `aggregate` | `string` | Aggregate function: `sum`, `count`, `distinct`, `avg`. |
| `aggregateField` | `string` | Field used for aggregation if different from `field`. |
Expand Down
40 changes: 26 additions & 14 deletions packages/cx/src/widgets/grid/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -919,10 +919,13 @@ export class Grid<T = unknown> extends ContainerBase<GridConfig<T>, GridInstance

let sortField = null;

if (isDefined(this.sortField) && isDefined(this.sortDirection)) {
// rebuild sorters from the sortField/sortDirection bindings only if a sort field
// is actually set; sorts identified by a value selector (columns without a field)
// live in data.sorters/state.sorters and cannot round-trip through a field name
if (isDefined(this.sortField) && isDefined(this.sortDirection) && data.sortField) {
let sorter = {
field: data.sortField,
direction: data.sortDirection,
direction: data.sortDirection || "ASC",
};
sortField = data.sortField;
data.sorters = [sorter];
Expand All @@ -939,11 +942,11 @@ export class Grid<T = unknown> extends ContainerBase<GridConfig<T>, GridInstance
}

if (sortField) {
for (let l = 1; l < 10; l++) {
for (let l = 0; l < 10; l++) {
let line = instance.row[`line${l}`];
let sortColumn = line && line.columns && line.columns.find((c: any) => c.field == sortField);
let sortColumn = line && line.columns && line.columns.find((c: any) => (c.sortField || c.field) == sortField);
if (sortColumn) {
data.sorters[0].value = sortColumn.sortValue || sortColumn.value;
data.sorters[0].value = isDefined(sortColumn.sortValue) ? sortColumn.sortValue : sortColumn.value;
data.sorters[0].comparer = sortColumn.comparer;
data.sorters[0].sortOptions = sortColumn.sortOptions;
break;
Expand Down Expand Up @@ -1307,8 +1310,18 @@ export class Grid<T = unknown> extends ContainerBase<GridConfig<T>, GridInstance

if (hdwidget.sortable && header.widget.allowSorting) {
mods.push("sortable");
if (data.sorters && data.sorters[0].field == (hdwidget.sortField || hdwidget.field)) {
mods.push("sorted-" + data.sorters[0].direction.toLowerCase());
let sorter = data.sorters && data.sorters[0];
let sortColumnField = hdwidget.sortField || hdwidget.field;
let sortColumnValue = isDefined(hdwidget.sortValue) ? hdwidget.sortValue : hdwidget.value;
// a sort is identified by its (field, value selector) pair, so columns
// sorting by the same field through different value selectors don't both match
let sorted =
sorter &&
!!sorter.direction &&
(sortColumnField ? sorter.field == sortColumnField : !sorter.field && isDefined(sortColumnValue)) &&
sorter.value === sortColumnValue;
if (sorted) {
mods.push("sorted-" + sorter.direction.toLowerCase());
sortIcon = <DropDownIcon className={CSS.element(baseClass, "column-sort-icon")} />;
}
}
Expand Down Expand Up @@ -1481,17 +1494,16 @@ export class Grid<T = unknown> extends ContainerBase<GridConfig<T>, GridInstance
let header = column.components[`header${headerLine + 1}`];

let field = column.sortField || column.field;
let value = column.sortValue || column.value;
let value = isDefined(column.sortValue) ? column.sortValue : column.value;
let comparer = column.comparer;
let sortOptions = column.sortOptions;

if (header && header.allowSorting && column.sortable && (field || value || data.sortField)) {
if (header && header.allowSorting && column.sortable && (field || isDefined(value))) {
let direction = column.primarySortDirection ?? "ASC";
if (
isNonEmptyArray(data.sorters) &&
((!!data.sorters[0].field && data.sorters[0].field == (field || data.sortField)) ||
(!!value && data.sorters[0].value == value))
) {
// the column matches the active sorter only if both the field and the value
// selector are the same; two columns may sort by the same field through
// different value selectors and represent different sorts
if (isNonEmptyArray(data.sorters) && data.sorters[0].field == field && data.sorters[0].value === value) {
if (data.sorters[0].direction == "ASC" && (!this.clearableSort || direction == "ASC")) direction = "DESC";
else if (data.sorters[0].direction == "DESC" && (!this.clearableSort || direction == "DESC"))
direction = "ASC";
Expand Down
Loading