インライン編集を使用したテーブルでのデータの表示

テーブルで Salesforce データを表示するには、lightning-datatable コンポーネントを使用します。このコンポーネントはインライン編集をサポートするため、ユーザはレコードに移動せずに項目値を更新できます。

レコードのリストを読み込むには、getListUi (Deprecated) ワイヤアダプタを使用するか、Apex メソッドで SOQL を使用します。「データガイドライン」を参照してください。

次の例では、Apex メソッドで SOQL を使用して取引先レコードの取引先責任者を読み込んでいます。

1public with sharing class ContactController {
2
3    @AuraEnabled(cacheable=true)
4    public static List<Contact> getContacts(String accId) {
5        return [
6            SELECT AccountId, Id, FirstName, LastName, Title, Phone, Email
7            FROM Contact
8            WHERE AccountId = :accId
9            WITH SECURITY_ENFORCED
10        ];
11    }
12}

@AuraEnabled(cacheable=true) アノテーションは、メソッドを Lightning コンポーネントに公開し、クライアント上の取引先責任者のリストをキャッシュします。accId パラメータを使用して、特定の取引先レコードの取引先責任者を絞り込みます。

LWC Recipes サンプルアプリケーションで緑色のバナーとして表示されているトースト通知。

Apex メソッドがデータを返すと、HTML テンプレートは編集可能な名項目と姓項目 (1) が含まれる lightning-datatable コンポーネントを表示します。項目を編集すると、[保存] ボタンが表示されます。このボタンをクリックして、取引先責任者レコードを更新できます。取引先責任者レコードが正常に更新されると、関連リスト (2) のレコードデータや、Lightning データサービスで管理されているページの他のコンポーネントも更新されます。

インライン編集の実装 

この例は、lwc-recipes リポジトリの datatableInlineEditWithUiApi コンポーネントに基づいています。このバージョンは、データテーブルをレコードページで使用できるようにするために若干異なっています。

Tip

インライン編集を有効にするには、次の apexContactsForAccount テンプレートのように lightning-datatable コンポーネントを設定します。

1<!-- apexContactsForAccount.html -->
2<template>
3  <lightning-card title="Datatable Example" icon-name="custom:custom63">
4    <div class="slds-m-around_medium">
5      <template lwc:if={contacts.data}>
6        <lightning-datatable
7          key-field="Id"
8          data={contacts.data}
9          columns={columns}
10          onsave={handleSave}
11          draft-values={draftValues}
12        >
13        </lightning-datatable>
14      </template>
15      <template lwc:if={contacts.error}>
16        <!-- Handle Apex error -->
17      </template>
18    </div>
19  </lightning-card>
20</template>

必須の key-field 属性は、各行を取引先責任者レコードに関連付けます。data 属性は、ワイヤサービスによって Apex メソッドまたはワイヤアダプタから取得されたデータを保持します。columns 属性は、レコード項目を各列に割り当てて、列の動作をカスタマイズします。ユーザがセルを編集すると、更新された値が draft-values に格納されます。

[保存] ボタンをクリックすると save イベントがトリガされます。onsave イベントハンドラを使用して、変更内容をデータテーブルに格納します。この例では、onsave イベントハンドラが updateRecord(recordInput, clientOptions) をコールして、レコードの変更を保存します。

属性とサポートされる機能のリストは、lightning-datatable を参照してください。

Note

列のインライン編集の有効化 

1 行のデータは 1 つのレコードに対応し、各列にはそのレコードの項目の 1 つの値が表示されます。インライン編集を有効にするには、列定義で editable: true を設定することで編集できる項目を指定します。この例では、First Name 項目と Last Name 項目は編集可能です。取引先責任者の名前項目は複合項目であるため、First Name 項目と Last Name 項目を使用する必要があります。

1// apexContactsForAccount.js
2
3import { LightningElement, wire, api } from "lwc";
4import getContacts from "@salesforce/apex/ContactController.getContactList";
5import { refreshApex } from "@salesforce/apex";
6import { updateRecord } from "lightning/uiRecordApi";
7
8import { ShowToastEvent } from "lightning/platformShowToastEvent";
9import FIRSTNAME_FIELD from "@salesforce/schema/Contact.FirstName";
10import LASTNAME_FIELD from "@salesforce/schema/Contact.LastName";
11import TITLE_FIELD from "@salesforce/schema/Contact.Title";
12import PHONE_FIELD from "@salesforce/schema/Contact.Phone";
13import EMAIL_FIELD from "@salesforce/schema/Contact.Email";
14import ID_FIELD from "@salesforce/schema/Contact.Id";
15
16const COLS = [
17  {
18    label: "First Name",
19    fieldName: FIRSTNAME_FIELD.fieldApiName,
20    editable: true,
21  },
22  {
23    label: "Last Name",
24    fieldName: LASTNAME_FIELD.fieldApiName,
25    editable: true,
26  },
27  { label: "Title", fieldName: TITLE_FIELD.fieldApiName, editable: true },
28  {
29    label: "Phone",
30    fieldName: PHONE_FIELD.fieldApiName,
31    type: "phone",
32    editable: true,
33  },
34  {
35    label: "Email",
36    fieldName: EMAIL_FIELD.fieldApiName,
37    type: "email",
38    editable: true,
39  },
40];
41export default class DatatableInlineEditWithUiApi extends LightningElement {
42  @api recordId;
43  columns = COLS;
44  draftValues = [];
45
46  @wire(getContacts, { accId: "$recordId" })
47  contacts;
48
49  async handleSave(event) {
50    // Convert datatable draft values into record objects
51    const records = event.detail.draftValues.slice().map((draftValue) => {
52      const fields = Object.assign({}, draftValue);
53      return { fields };
54    });
55
56    // Clear all datatable draft values
57    this.draftValues = [];
58
59    try {
60      // Update all records in parallel thanks to the UI API
61      const recordUpdatePromises = records.map((record) => updateRecord(record));
62      await Promise.all(recordUpdatePromises);
63
64      // Report success with a toast
65      this.dispatchEvent(
66        new ShowToastEvent({
67          title: "Success",
68          message: "Contacts updated",
69          variant: "success",
70        }),
71      );
72
73      // Display fresh data in the datatable
74      await refreshApex(this.contacts);
75    } catch (error) {
76      this.dispatchEvent(
77        new ShowToastEvent({
78          title: "Error updating or reloading contacts",
79          message: error.body.message,
80          variant: "error",
81        }),
82      );
83    }
84  }
85}

@wire(getContacts) は、データを contacts.data に、レコード ID を accId にプロビジョニングします。

項目を編集すると、編集後の項目値とレコード Id がオブジェクトの配列として event.detail.draftValues に格納されます。

1[
2  {
3    FirstName: "Sean",
4    Id: "003R0000002J2wHIAS",
5  },
6  {
7    FirstName: "Jack",
8    Id: "003R0000002J2wIIAS",
9  },
10];

変更後に Tab キーを押すかセルの外側をクリックすると、データテーブルのフッターに [キャンセル] ボタンと [保存] ボタンが表示されます。データベースフッタを非表示にするには、draftValues プロパティをクリアします。onsave イベントハンドラは、値をレコードオブジェクトにコピーした後に draftValues をクリアします。

updateRecord(recordInput, clientOptions) をコールすることで、新しい項目値がレコードに保存されます。

updateRecord() は、1 つのレコードのみを想定します。項目を更新する各レコードに対して recordInput オブジェクトを渡します。この例では、record パラメータに複数レコードの更新済み項目が格納されたオブジェクトが含まれます。複数のレコードを同時に更新するには、パラメータを updateRecord() に渡して処理します。

保存に成功すると、onsave イベントハンドラで ShowToastEvent イベントがディスパッチされ、成功トーストメッセージが表示されます。

レコードが更新されると、refreshApex(this.contacts) は、Apex メソッドから返された取引先責任者のリストを更新し、データテーブルが常に最新のデータを反映するようにします。

1 つのトランザクションでレコードを一括更新するには、Apex を使用することをお勧めします。**「Apex を使用したのインライン編集の有効化」**セクションを参照してください。

Note

Apex を使用したのインライン編集の有効化 

レコードを一括更新する場合、update データ操作言語 (DML) 操作をコールする Apex コントローラにレコードの変更内容を渡します。この例では、編集された項目値が updateContacts Apex コントローラに渡されます。レコードは Apex によって更新されるため、ユーザは notifyRecordUpdateAvailable(recordIds) 関数を使用して Lightning データサービス (LDS) に通知し、Lightning データサービスキャッシュおよびワイヤが更新されるようにする必要があります。

この例は、github.com/trailheadapps/lwc-recipes リポジトリの datatableInlineEditWithApex コンポーネントに基づいています。このバージョンは、LDS を使用せずに Apex を使用するという点で若干異なっています。

Note

前の例で作成した apexContactsForAccount.js ファイルで、Apex コントローラと notifyRecordUpdateAvailable 関数をインポートします。

1import updateContacts from "@salesforce/apex/ContactController.updateContacts";
2import { notifyRecordUpdateAvailable } from "lightning/uiRecordApi";

handleSave() 関数を更新して、編集された値を処理します。レコードの更新後に Apex を介して notifyRecordUpdateAvailable() がコールされるようにするには、async/await パターンまたは Promise チェーンを使用します。次の例では async/await を使用します。

1async handleSave(event) {
2    const updatedFields = event.detail.draftValues;
3
4    // Prepare the record IDs for notifyRecordUpdateAvailable()
5    const notifyChangeIds = updatedFields.map(row => { return { "recordId": row.Id } });
6
7    try {
8        // Pass edited fields to the updateContacts Apex controller
9        const result = await updateContacts({data: updatedFields});
10        console.log(JSON.stringify("Apex update result: "+ result));
11        this.dispatchEvent(
12            new ShowToastEvent({
13                title: 'Success',
14                message: 'Contact updated',
15                variant: 'success'
16            })
17        );
18
19        // Refresh LDS cache and wires
20        notifyRecordUpdateAvailable(notifyChangeIds);
21
22        // Display fresh data in the datatable
23        await refreshApex(this.contacts);
24            // Clear all draft values in the datatable
25            this.draftValues = [];
26        }
27   } catch(error) {
28           this.dispatchEvent(
29               new ShowToastEvent({
30                   title: 'Error updating or refreshing records',
31                   message: error.body.message,
32                   variant: 'error'
33               })
34         );
35    };
36}

updateContacts Apex コントローラは、更新された項目が含まれる JSON 文字列を取引先責任者オブジェクトにデシリアライズします。update DML 操作を使用して、変更されたレコードを更新します。

1@AuraEnabled
2public static string updateContacts(Object data) {
3    List<Contact> contactsForUpdate = (List<Contact>) JSON.deserialize(
4         JSON.serialize(data),
5         List<Contact>.class
6    );
7    try {
8        update contactsForUpdate;
9        return 'Success: contacts updated successfully';
10    }
11    catch (Exception e) {
12        return 'The following exception has occurred: ' + e.getMessage();
13    }
14}

関連トピック

The Japanese Summer '24 guide is now live

日本語の Summer '24 ガイドが公開されました! 「Component Reference (コンポーネントリファレンス)」は、以前と同様にコンポーネントライブラリにあります。