Goalist Developers Blog

ngx-datatableでソートしつつ特定の行を固定する!

angularでデータグリッド表示するのにngx-datatable使ってます

github.com

フロント側でのソート機能がついていますが、こんな感じで合計行まで動いてしまうのですよね

f:id:y-iio:20180413180915g:plain

突っ込んだデータの合計行だけは一番下に固定したいという望みを叶えるべく
ゴリラ的な方法でズズイと無理やりやってみました

マルチソートの対応はしない。漢らしい!

<ngx-datatable
        #dataTable
        [rows]="rows"
        [columns]="columns"
        [sorts]="sorts"
        (sort)="onSorted($event)">
</ngx-datatable>
public rows = [];
public columns = [];
public sorts = [];

@ViewChild('dataTable') private dataTable: DatatableComponent;
private ascSortedColumn: string = '';

public onSorted(event): void {
    // ここにくるとき、this.dataTable._internalRowsは常に昇順ソートがかかった状態になっている
    const columnName: string = event['column']['name'];
    // 一度明示的に昇順ソートした後だったら、ここで無理やり降順ソートの設定に書き換える
    if (this.ascSortedColumn === columnName) {
        this.ascSortedColumn = '';
        event['sorts'][0]['dir'] = 'desc';
        this.sorts = [{
            prop: event['sorts'][0]['prop'],
            dir: 'desc'
        }];
        this.rows = [...this.rows]; // 降順ソートを適用
        setTimeout(() => {
            this.moveSumRow(); // ライブラリ側の降順ソート処理が終わった頃合いを見計らう
        }, 100);
    } else {
        this.ascSortedColumn = columnName;
        this.moveSumRow();
    }
}

// ライブラリ側のソート処理が終わってから、合計行をいちばん後ろに移動させる
private moveSumRow(): void {
    const tmpRows = this.dataTable._internalRows.concat();
    const sumRowIndex: number = tmpRows.findIndex((row) => row.hasOwnProperty('x1field') && row['x1field'] === '合計');
    if (sumRowIndex < 0) {
        return;
    }
    const sumRow = tmpRows[sumRowIndex];
    tmpRows.splice(sumRowIndex, 1); // 合計行をいちばん後ろに移動
    tmpRows.push(sumRow);
    this.sorts = []; // テーブルのソートを解除 // ここで解除しておかないと合計行含めてソートし直されてしまう
    this.dataTable.sorts = []; // ほんとうにむりやりテーブルのソートを解除
    this.rows = [...tmpRows]; // 表を再描画
}

こんなかんじで、一瞬ペイッ!ガタッ!と動きます

f:id:y-iio:20180413180948g:plain

すごい力技だ!
現在選ばれているソート条件アイコンを見えなくすることで全てをうやむやにする!

力という名のパワーで全てを解決しました
男にはやらなきゃならねえ""瞬間とき""がある