【LWC】datatableで選択リストを使用する

#はじめに

今回はdatatableで選択リストの表示について調べたので書いていきます。
datatableは標準のリストビューのようなレコードをテーブル形式で表示するコンポーネントです。リストビューと同様にインライン編集が出来ますが、選択リストはリストビューと違いテキスト形式での編集になってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407598/fa858a5c-2bca-ee88-d904-a103ff1f6150.png)
選択リスト形式で編集できるようにするにはCustom Data Typeを使う必要があります。
Custom Data Typeについて書かれている方は見かけたのですが、選択リスト型についてのサイトは日本語では見かけなかったので海外の方を参考に調べてみました。

※標準で使えるData Type
https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/documentation

#つくるもの

今回作成するのは下のような選択リスト型で編集できるdatatableです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407598/68bd227a-69c0-06a8-cd5a-8631b3df3537.png)

#作成物
作成するコンポーネントは以下の３つです。
- customDatatableDemo
- customDataTable
- datatablePicklist

#datatablePicklist
まずは選択リストとして使用するコンポーネントを作成していきます。LWCではlightning-comboboxが標準としてあるのでそちらを使用します。

```html:datatablePicklist.html
<template>
  <div class="picklist-container">
      <lightning-combobox name="picklist" label={label} value={value} placeholder={placeholder} options={options}
          onchange={handleChange}></lightning-combobox>
  </div>
</template>
```
```javascript:datatablePicklist.js
import { LightningElement, api } from 'lwc';

export default class DatatablePicklist extends LightningElement {
    @api label;
    @api placeholder;
    @api options;
    @api value;
    @api context;
}
```
#customDataTable
次はlightning-datatableを継承したものを作ります。Custom Data Typeを使うには必須らしいです。いつも何気なくextends LightningElementを使ってますが、LightningDatatableも継承できるなんて知らなかった...

```html:customDataTable.html
<template>
  <c-datatable-picklist label={typeAttributes.label} value={typeAttributes.value}
      placeholder={typeAttributes.placeholder} options={typeAttributes.options} context={typeAttributes.context}>
  </c-datatable-picklist>
</template>
```
```javascript:customDataTable.js
import LightningDatatable from 'lightning/datatable';
//import the template so that it can be reused
// import DatatablePicklistTemplate from './picklist-template.html';
import DatatablePicklistTemplate from './customDataTable.html';
import {
    loadStyle
} from 'lightning/platformResourceLoader';
import CustomDataTableResource from '@salesforce/resourceUrl/CustomDataTable';

export default class CustomDataTable extends LightningDatatable {
  static customTypes = {
    picklist: {
        template: DatatablePicklistTemplate,
        typeAttributes: ['label', 'placeholder', 'options', 'value', 'context'],
    },
  };

  constructor() {
    super();
    Promise.all([
        loadStyle(this, CustomDataTableResource),
    ]).then(() => {})
  }
}
```
customTypesでCustom Data Typeを作成します。今回はpicklistというタイプを作成しました。
templateには利用するテンプレートを入れます。typeAttributes.labelなどはcustomDataTableDemoコンポーネントで指定する値が入ります。
customDataTable.htmlを使用せず、pickListTemplate.htmlのようなファイルを作成している人もいました。中身は同じなのでどちらでも動作はします。

#customDatatableDemo
最後に表示用のコンポーネントを作成します。通常のdatatableと同様にdataとcolumnsを指定します。

```html:customDatatableDemo.html
<template>
  <template if:true={data}>
      <c-custom-data-table 
          key-field="Id" 
          data={data} 
          columns={columns} 
          hide-checkbox-column>
      </c-custom-data-table>
  </template>
</template>
```
```javascript:customDatatableDemo.js
import { LightningElement, track } from 'lwc';
import getAccountListWithRating from '@salesforce/apex/AccountTableViewController.getAccountListWithRating';

export default class CustomDatatableDemo extends LightningElement {
  @track data = [];
  
  connectedCallback() {
    this.columns = [
        { label: 'Name', fieldName: 'Name', editable: true },
        { label: 'Account Number', fieldName: 'AccountNumber', editable: true },
        { label: 'Phone', fieldName: 'phone', type: 'phone', editable: true },
        {
            label: 'Rating', fieldName: 'Rating', type: 'picklist', typeAttributes: {
                placeholder: 'Choose rating', options: [
                    { label: 'Hot', value: 'Hot' },
                    { label: 'Warm', value: 'Warm' },
                    { label: 'Cold', value: 'Cold' },
                ] // list of all picklist options
                , value: { fieldName: 'Rating' } 
                , context: { fieldName: 'Id' } to be returned back
            }
        }
    ];

    getAccountListWithRating()
    .then(data => {
      this.data = data;
    })
  }
}
```
columnsのtype: 'picklist'でcustomDataTable.jsで作成したcustomTypesを使用することを明記します。
インライン編集したときのロジックがまだ完成していませんのでまた実装したらアップしたいと思います。

まだまだLWCについては知らないことが多そうなので引き続き勉強していきます。