LWCで選択リスト項目を扱う (lightning-combobox)


`lightning-record-form`や`lightning-record-edit-form`を使わずに、プルダウンに選択リスト項目を使用するTipsです。
`lightning-record-form`については[こちら](https://developer.salesforce.com/docs/component-library/documentation/ja-jp/54.0/lwc/lwc.data_get_user_input_intro)。

## 選択リストの選択肢を項目定義から取得する
wireサービスを使用することでApexコードなしに選択リストの選択肢を使用することができます。

![combobox001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/a3d89bc2-e9ae-9b69-d40f-dee7ea48e02b.jpeg)

```html
<template>
    <div lwc:if={industryOptions.data} class="wrapper">
        <lightning-combobox
            label="業種"
            options={industryOptions.data.values}
        ></lightning-combobox>
    </div>
</template>
```

```js
import { LightningElement, wire } from 'lwc';
import { getPicklistValues, getObjectInfo } from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import ACCOUNT_INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';

export default class Sample extends LightningElement {
    @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    accountObjectInfo;

    @wire(getPicklistValues, { recordTypeId: '$accountObjectInfo.data.defaultRecordTypeId', fieldApiName: ACCOUNT_INDUSTRY_FIELD })
    industryOptions;
}
```

### 選択なしを追加する
選択なしを追加する場合は、getPicklistValuesで取得したリストに空の値を追加する必要があります。
```js
    get _industryOptions() {
        return [
            { label: "--なし--", value: "" },
            ...this.industryOptions.data.values
        ];
    }
```

## 画面から入力された値を取得する
comboboxに限らないですが、画面から入力された値を変数に代入するときは、`onchange`のイベント属性を使用します。
初期値を設定する場合はvalue属性を使用します。
入力項目が多い場合はdata属性を使用するとコードの記述量を減らすことができます。

![combobox003.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/ff42d55b-4a28-9c11-da59-535706b7d23c.gif)


```html
<template>
    <div lwc:if={industryOptions.data} class="wrapper">
        選択した値：{account.Industry}
        <lightning-combobox
            label="業種"
            options={_industryOptions}
            data-field-name="Industry"
            value={account.Industry}
            onchange={handleChange}
        ></lightning-combobox>
    </div>
</template>
```

```js
@track account = {
    Industry: ""
};

handleChange(event) {
    this.account = {
        ...this.account,
        [event.target.dataset.fieldName]: event.detail.value
    };
}
```

## バリデーションを実施する
data属性とquerySelectAllを使ってバリデーションを実装できます。

![combobox002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125621/0bcc97f5-fb32-b0cf-3df3-a9afba1259ed.jpeg)

```html
<template>
    <div lwc:if={industryOptions.data} class="wrapper">
        選択した値：{account.Industry}

        <lightning-combobox
            data-id="input"
            label="業種"
            options={_industryOptions}
            data-field-name="Industry"
            value={account.Industry}
            onchange={handleChange}
            required
        ></lightning-combobox>

        <lightning-button label="OK" variant="brand" onclick={handleClick}></lightning-button>
    </div>
</template>

```

```js
handleClick() {
    this.validate();
}

validate() {
    return [...this.template.querySelectorAll('[data-id="input"]')].reduce((validSoFar, inputCmp) => {
        // inputCmp.setCustomValidity(''); カスタムバリデーションを使用している場合はリセットする必要がある。使用していない場合は不要。
        inputCmp.reportValidity();
        return validSoFar && inputCmp.checkValidity();
    }, true);
}
```

## 参照
- [lightning-combobox - Salesforce Lightning Component Library](https://developer.salesforce.com/docs/component-library/bundle/lightning-combobox/example)