Edited at

lightning-datatableのCustom Data Typeの使い方


はじめに

Salesforceの新しいフロントエンドフレームワークであるLightning Web Componentのお話です。

lightning-datatableコンポーネントはいわゆるSalesforceの一般的なテーブルUIを実現するコンポーネントです。

しかし、リンクが貼れないボタンが置けない、などなかなかカスタマイズが効きません。


追記(2019/04/08)

ボタンは type:'button'type:'button-icon' で置けました。


ちゃんとドキュメントを読んでみると、Create Custom Data Typesという章があることに気づいたので、試してみました。

しかし、ちょっとつまずいたので、記事にまとめて、コードも公開しておきます。


作るもの

ドキュメントの例のようにカラムにdeleteRowButtonというデータ型を指定すると削除ボタンを表示するようにします。


ソースコード

リポジトリ作って置いておきました。

https://github.com/atskimura/lightning-datatable-custom-datatype-example


作り方

3つのコンポーネントを作る必要があります。


  • myDatatableDemo: 実際画面に配置するコンポーネント

  • myDatatable: lightning-datatableを継承したコンポーネント

  • datatableDeleteRowBtn: 削除ボタン部分のコンポーネント


myDatatableDemo

実際に画面に配置するコンポーネントです。カスタムdatatableコンポーネントを利用する側です。


myDatatableDemo.html

<template>

<c-my-datatable
key-field="id"
data={data}
columns={columns}
ondeleterow={deleteRow}
hide-checkbox-column>
</c-my-datatable>
</template>

ビューではこの後作るmyDatatableコンポーネントを利用しています。

ドキュメントと違って他のコンポーネントを利用するにはネームスペース(今回はローカルなのでc)が必要です。

ondeleterowはこの後作成するdatatableDeleteRowBtnで発火します。


myDatatableDemo.js

import { LightningElement, track } from 'lwc';

const columns = [
{
label: 'Name',
fieldName: 'name',
},
{
label: 'Delete',
type: 'deleteRowButton',
fieldName: 'id',
fixedWidth: 70,
typeAttributes: {
attrA: { fieldName: 'attrA' },
attrB: { fieldName: 'attrB' },
},
},
];

export default class MyDatatableDemo extends LightningElement {
@track data = [
{
id: '1',
name: 'Name1',
attrA: 'A1',
attrB: 'B1',
},
{
id: '2',
name: 'Name2',
attrA: 'A2',
attrB: 'B2',
}
];
@track columns = columns;

deleteRow(event) {
const { rowId } = event.detail;
window.console.log(rowId, event);
// Remove the row
}
}


columnslightning-datatableコンポーネントにはないdeleteRowButtonというタイプを指定しています。


myDatatable

lightning-datatableを継承したコンポーネントです。カスタムデータタイプを使用するには継承したコンポーネントを作る必要があります。面倒ですね。


myDatatable.js

import LightningDatatable from 'lightning/datatable';

import deleteRow from './deleteRow.html';

export default class MyDatatable extends LightningDatatable {
static customTypes = {
deleteRowButton: {
template: deleteRow,
// Provide template data here if needed
typeAttributes: ['attrA', 'attrB'],
}
//more custom types here
};
}


LightningDatatableを継承したクラスを作り、customTypesに追加したいカスタムデータ型を定義するだけです。

利用するテンプレート(template)と値を渡したいプロパティ名(typeAttributes)を設定します。


deleteRow.html

<template>

<c-datatable-delete-row-btn
data-navigation="enable"
row-id={value}
attr-a={typeAttributes.attrA}
attr-b={typeAttributes.attrB}>
</c-datatable-delete-row-btn>
</template>

テンプレートはdeleteRow.htmlとしてmyDatatable.jsと同階層に作ります。

datatableDeleteRowBtnコンポーネントを呼び出しています。

valueではcolumnsの定義でfieldNameに指定したプロパティ値が取得できます。

typeAttributes.attrAのようにするとそのカラムのデータのattrAプロパティの値が取得できます。

こういうファイル構造になります。

myDatatable.htmlは空でよいです。


datatableDeleteRowBtn

deleteRowButton型に対応する削除ボタン部分のコンポーネントです。

これは普通にコンポーネントを作ればよいです。


datatableDeleteRowBtn.html

<template>

<div style="text-align: center;">
<lightning-button-icon
icon-name="utility:delete"
onclick={fireDeleteRow}>
</lightning-button-icon>
</div>
</template>

ビューでは削除ボタンを置いているだけです。


datatableDeleteRowBtn.js

import { LightningElement, api } from 'lwc';

// Accessibility module
// import { baseNavigation } from 'lightning/datatableKeyboardMixins';
// For the render() method
// import template from './datatableDeleteRowBtn.html';

// export default class DatatableDeleteRowBtn extends baseNavigation(LightningElement) {
export default class DatatableDeleteRowBtn extends LightningElement {
@api rowId;
@api attrA;
@api attrB;

/* // Required for mixins
render() {
return template;
}*/

fireDeleteRow() {
const event = CustomEvent('deleterow', {
composed: true,
bubbles: true,
cancelable: true,
detail: {
rowId: this.rowId,
},
});
this.dispatchEvent(event);
}
}


datatableKeyboardMixinsを使うとテーブル内でキーボードナビゲーションが使えるようになるらしいんですが、これの使い方わかりませんでした。コメントアウトしている箇所のようにドキュメント通りに書くと、何も表示されなくなってしまいます。誰か使い方わかったら教えてください。

それ以外は普通にコンポーネント作るだけです。


終わりに

lightning-datatable使えないなあと思っていましたが、意外と使えるかもしれません。

マウスオーバーしたらポップオーバーを表示するデータ型なんかを作りたいなと思います。

次のリリースでそんなデータ型が標準で追加されそうですが…