ember-table icon indicating copy to clipboard operation
ember-table copied to clipboard

sorting and queryParams

Open basz opened this issue 6 years ago • 2 comments

Hi,

I'm looking for a way to have paging and sorting accessible via query params (for navigation purposes (back button)). For paging I got this working now, but the sorting logic is hardcoded with a click handler which (seems to) means I cannot easily use a link-to helper with its query property in a custom header template.

What would be the recommended manner to achieve sorting via query params?

<t.head
    @columns={{this.columns}}
    @sorts={{this.sorts}}
    @onUpdateSorts={{action "onUpdateSorts"}} as |h|>

    <h.row as |r|>
      <r.cell as |columnValue columnMeta|>
        {{#if columnMeta.isSortable}}
          <EmberTh::SortIndicator @columnMeta={{columnMeta}} />
          <LinkTo @query={{hash sort=columnValue.valuePath}}>{{columnValue.name}}</LinkTo>
        {{/if}}

        <EmberTh::ResizeHandle @columnMeta={{columnMeta}} />
      </r.cell>
    </h.row>
</t.head>

basz avatar Sep 09 '19 08:09 basz

To answer myself; just use an onUpdateSorts action and transition into a new route.

@action
  onUpdateSorts(sorts) {
    this.router.transitionTo(this.router.currentRouteName, { queryParams: { page: 1, sort: Sorting.toQueryValue(sorts) } });
  }

basz avatar Sep 27 '21 09:09 basz

@basz The approach I've used with much success is to persist the value for @sorts on the Controller like any other query param. I additionally implement a custom get/set to serialize the sorts array to a JSON string for the QP and deserialize it back to an array of objects for ember-table. Here's an example (in TypeScript) of the base Controller class that I use for Controllers that will persist an ember-table sorts to QP:

import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { EmberTableSort } from 'ember-table';

export default class extends Controller {
  queryParams = ['sorts'];
  @tracked sorts: string | null = null;

  get sortsValue(): EmberTableSort[] | undefined {
    let { sorts } = this;
    if (!sorts) {
      return undefined;
    }

    return JSON.parse(sorts) as EmberTableSort[];
  }
  set sortsValue(value: EmberTableSort[] | undefined) {
    this.sorts = value?.length ? JSON.stringify(value) : null;
  }

  @action updateSorts(sorts?: EmberTableSort[]): void {
    this.sortsValue = sorts;
  }
}

kpfefferle avatar Oct 11 '21 19:10 kpfefferle