lightning-datatableの使い方
表示結果
- 取引先のレコードページへ追加
- LWCのapiVersionは47.0
使用した属性
- key-field
- data
- columns
- show-row-number-column
- hide-checkbox-column
- resize-column-disabled
[Attribute] key-field
必須だが詳細がよくわからない...
Referenceには以下の記載あり。取り合えず "id" を指定しておけば良いのかな。
Required for better performance. Associates each row with a unique ID.
[Attribute] data
テーブルに表示する行の__データ配列__を指定する。
今回はSOQLで取得したリストが対象となる。(js側で少し加工するけど)
[Attribute] columns
テーブルに表示する列の__データ型配列__を指定する。
Salesforce標準ではName項目は自動でリンクとなるが、lightning-datatableではそうならない。
もし同じような動きにしたければ、少し工夫が必要。
列の定義をtype=urlとし、データ取得時にダミー項目(CaseUrl)に加工したurlを設定してあげる。
{ label: 'ケース番号', fieldName: 'CaseUrl', type: 'url',
typeAttributes: { label: { fieldName: 'CaseNumber' }, tooltip: { fieldName: 'CaseNumber' } } },
c.CaseUrl = '/lightning/r/' + c.Id + '/view'; ← 「'/' + c.Id」のほうが汎用的だけど不要なリダイレクトが発生したのでやめた
また、fieldNameに取得したSOQLのカラムを指定すると自動でバインドされるが、クロスオブジェクト(例:Owner.Name)はサポートされていない(指定してもエラーにはならないが、空白表示となる)ため、こちらも少し工夫が必要となる。
urlと同様にデータ取得時にダミー項目(OwnerNameやContactName)にクロスオブジェクトを設定してあげるだけ。
{ label: '所有者', fieldName: 'OwnerUrl', type: 'url',
typeAttributes: { label: { fieldName: 'OwnerName' }, tooltip: { fieldName: 'OwnerName' } } },
{ label: '取引先責任者', fieldName: 'ContactUrl', type: 'url',
typeAttributes: { label: { fieldName: 'ContactName' }, tooltip: { fieldName: 'ContactName' } } },
c.OwnerName = c.Owner.Name;
c.ContactName = c.ContactId ? c.Contact.Name : ''; ← Ownerは必ず設定されるけど、ContactIdはそうではないため存在チェックしている
[Attribute] show-row-number-column
行番号を表示したい場合に指定する。
[Attribute] hide-checkbox-column
行選択のチェックボックスを非表示にしたい場合に指定する。
[Attribute] resize-column-disabled
列のサイズ変更をさせたくない場合に指定する。
Reference
気になった点
- js側で加工したけどデータ量が多い場合はパフォーマンスに注意が必要そう。
- columnsに指定する列のlabel名をリテラルで記載しているが、getObjectInfoを使えばスキーマ情報から取得できそう?
- レコードページでコンポーネントが表示されない場合は、「私のドメイン」の設定とLWCのjs-meta.xmlの中身を確認。
ソース
public with sharing class CaseListVeiwController {
private CaseListVeiwController() {
}
@AuraEnabled
public static List<Case> getCaseListVeiw(Id accountId) {
return [
SELECT
Id,
CaseNumber,
TOLABEL(Status),
TOLABEL(Priority),
TOLABEL(Type),
TOLABEL(Origin),
TOLABEL(Reason),
Subject,
ClosedDate,
OwnerId,
Owner.Name,
CreatedDate,
CreatedById,
LastModifiedDate,
LastModifiedById,
ContactId,
Contact.Name
FROM
Case
WHERE
AccountId = :accountId
ORDER BY
LastModifiedDate DESC
];
}
}
import { LightningElement, api, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import getCaseListVeiw from '@salesforce/apex/CaseListVeiwController.getCaseListVeiw';
const columns = [
{ label: 'ケース番号', fieldName: 'CaseUrl', type: 'url',
typeAttributes: { label: { fieldName: 'CaseNumber' }, tooltip: { fieldName: 'CaseNumber' } } },
{ label: '状況', fieldName: 'Status', type: 'text', },
{ label: '優先度', fieldName: 'Priority', type: 'text', },
{ label: '種別', fieldName: 'Type', type: 'text', },
{ label: '発生源', fieldName: 'Origin', type: 'text', },
{ label: '原因', fieldName: 'Reason', type: 'text', },
{ label: '件名', fieldName: 'Subject', type: 'text', },
{ label: '作成日', fieldName: 'CreatedDate', type: 'date',
typeAttributes: { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' } },
{ label: '完了日', fieldName: 'ClosedDate', type: 'date',
typeAttributes: { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' } },
{ label: '所有者', fieldName: 'OwnerUrl', type: 'url',
typeAttributes: { label: { fieldName: 'OwnerName' }, tooltip: { fieldName: 'OwnerName' } } },
{ label: '取引先責任者', fieldName: 'ContactUrl', type: 'url',
typeAttributes: { label: { fieldName: 'ContactName' }, tooltip: { fieldName: 'ContactName' } } },
];
export default class CaseListVeiw extends LightningElement {
@api recordId;
@track columns = columns;
@track records = [];
@track loaded = false;
connectedCallback() {
getCaseListVeiw({
accountId: this.recordId
})
.then(data => {
data.forEach(c => {
c.CaseUrl = '/lightning/r/' + c.Id + '/view';
c.OwnerUrl = '/lightning/r/' + c.Owner.Id + '/view';
c.OwnerName = c.Owner.Name;
c.ContactUrl = c.ContactId ? '/lightning/r/' + c.ContactId + '/view' : '';
c.ContactName = c.ContactId ? c.Contact.Name : '';
});
this.records = data;
this.loaded = true;
})
.catch(error => {
this.loaded = true;
this.showToast(error.message);
});
}
showToast(message) {
const event = new ShowToastEvent({
title: 'エラーが発生しました',
message: message,
variant: 'error',
mode: 'pester'
});
this.dispatchEvent(event);
}
refresh(event) {
this.loaded = false;
this.connectedCallback();
}
}
<template>
<lightning-card icon-name="standard:case">
<h1 slot="title"><strong>取引先に紐づくケース</strong></h1>
<lightning-button-icon slot="actions" icon-name="utility:refresh" alternative-text="Refresh" onclick={refresh}></lightning-button-icon>
<template if:true={records}>
<div class="slds-m-around_x-small">
<lightning-datatable
key-field="id"
data={records}
columns={columns}
show-row-number-column
hide-checkbox-column
resize-column-disabled>
</lightning-datatable>
</div>
</template>
<template if:false={loaded}>
<lightning-spinner alternative-text="Loading"></lightning-spinner>
</template>
</lightning-card>
</template>