Help us understand the problem. What is going on with this article?

lightning-datatableのCustom Data Typeの使い方

More than 1 year has passed since last update.

はじめに

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

lightning-datatableコンポーネントはいわゆるSalesforceの一般的なテーブルUIを実現するコンポーネントです。
しかし、リンクが貼れないボタンが置けない、などなかなかカスタマイズが効きません。

追記(2019/04/08)
ボタンは type:'button'type:'button-icon' で置けました。

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

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

作るもの

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

image.png

ソースコード

リポジトリ作って置いておきました。
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プロパティの値が取得できます。

image.png

こういうファイル構造になります。
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使えないなあと思っていましたが、意外と使えるかもしれません。
マウスオーバーしたらポップオーバーを表示するデータ型なんかを作りたいなと思います。
次のリリースでそんなデータ型が標準で追加されそうですが…

atskimura
株式会社co-meeetingのCEO。最近はSalesforce上で動くアプリを作ってます。コピペテックはじめました😀
http://www.co-meeting.co.jp/
co-meeting
株式会社co-meetingでは、創業以来スローガンである「Happy Work! Happy Life!」を掲げ、世界中の「働く人」の人生を豊かにするソフトウェアサービスを開発・提供することを目標とすると同時に、社員みんなが楽しく充実した仕事ができる会社を目指しています。
https://www.co-meeting.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした