1. atskimura

    Posted

    atskimura
Changes in title
+lightning-datatableのCustom Data Typeの使い方
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,200 @@
+# はじめに
+
+Salesforceの新しいフロントエンドフレームワークである[Lightning Web Component](https://developer.salesforce.com/docs/component-library/documentation/lwc)のお話です。
+
+`lightning-datatable`コンポーネントはいわゆるSalesforceの一般的なテーブルUIを実現するコンポーネントです。
+しかし、**リンクが貼れない**、**ボタンが置けない**、などなかなかカスタマイズが効きません。
+
+ちゃんと[ドキュメント](https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/documentation)を読んでみると、`Create Custom Data Types`という章があることに気づいたので、試してみました。
+
+しかし、ちょっとつまずいたので、記事にまとめて、コードも公開しておきます。
+
+# 作るもの
+
+ドキュメントの例のようにカラムに`deleteRowButton`というデータ型を指定すると削除ボタンを表示するようにします。
+
+![image.png](https://qiita-image-store.s3.amazonaws.com/0/27267/1a279866-6854-c1a3-e601-72150f00fc6e.png)
+
+# ソースコード
+
+リポジトリ作って置いておきました。
+https://github.com/atskimura/lightning-datatable-custom-datatype-example
+
+# 作り方
+
+3つのコンポーネントを作る必要があります。
+
+* myDatatableDemo: 実際画面に配置するコンポーネント
+* myDatatable: lightning-datatableを継承したコンポーネント
+* datatableDeleteRowBtn: 削除ボタン部分のコンポーネント
+
+## myDatatableDemo
+
+実際に画面に配置するコンポーネントです。カスタムdatatableコンポーネントを利用する側です。
+
+```html: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`で発火します。
+
+```js: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
+ }
+}
+```
+
+`columns`で`lightning-datatable`コンポーネントにはない`deleteRowButton`というタイプを指定しています。
+
+## myDatatable
+
+lightning-datatableを継承したコンポーネントです。カスタムデータタイプを使用するには継承したコンポーネントを作る必要があります。面倒ですね。
+
+```js: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`)を設定します。
+
+```html: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`プロパティの値が取得できます。
+
+![image.png](https://qiita-image-store.s3.amazonaws.com/0/27267/970a534c-4a52-a9cf-5c21-91f4bff8d9b7.png)
+
+こういうファイル構造になります。
+`myDatatable.html`は空でよいです。
+
+## datatableDeleteRowBtn
+
+`deleteRowButton`型に対応する削除ボタン部分のコンポーネントです。
+これは普通にコンポーネントを作ればよいです。
+
+```html:datatableDeleteRowBtn.html
+<template>
+ <div style="text-align: center;">
+ <lightning-button-icon
+ icon-name="utility:delete"
+ onclick={fireDeleteRow}>
+ </lightning-button-icon>
+ </div>
+</template>
+```
+
+ビューでは削除ボタンを置いているだけです。
+
+```js: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`使えないなあと思っていましたが、意外と使えるかもしれません。
+マウスオーバーしたらポップオーバーを表示するデータ型なんかを作りたいなと思います。
+次のリリースでそんなデータ型が標準で追加されそうですが…