Lightning Web コンポーネントアクションについて知る
学習の目的
この単元を完了すると、次のことができるようになります。
- ユーザー入力に基づいて項目に入力し、フィードバックメッセージをユーザーに表示する Lightning Web コンポーネントやアクションを作成する。
- JavaScript カスタムボタンの機能の Lightning 対応の代替法への移行を開始する。
Lightning Web コンポーネントアクション: スマート、スピーディ、柔軟
これまで、Lightning Experience と Salesforce Classic の両方で機能し、JavaScript ボタンの優れた代替法となるいくつかのソリューションを見てきました。ただし、こうした宣言型やプログラム型のソリューションではすべての使用事例に対処できないことを当社は認識しています。幸い、これらのソリューション以外にも手段があります。ではここで、Lightning Web コンポーネントをコールするクイックアクション、Lightning Web コンポーネントアクションをご紹介します。
Lightning Web コンポーネントアクションは、既存の Lightning Web コンポーネントフレームワーク上に構築されます。既存の Lightning Web コンポーネントを簡単にアクションに変換して、Lightning Experience で使用することができます。
Lightning Web コンポーネントをアクションとして起動可能にするために、コンポーネントのメタデータ設定 XML ファイルにターゲットとして lightning__RecordAction
を追加し、targetConfigs
に actionType
を指定します。Salesforce で定義されたモーダルウィンドウにアクションを表示するには、actionType を ScreenAction
に設定します。モーダルなしでアクションを実行する、またはカスタムモーダルウィンドウを定義するには、actionType を Action
に設定します。
Lightning Web コンポーネントアクション用のもう 1 つの有用なプロパティは recordId
で、Lightning レコードページからの起動時にそのレコードコンテキストをコンポーネントに提供します。レコードのデータまたはメタデータにアクセスするには、コンポーネントの JavaScript クラスで、@api
デコレーターを使用して recordId
公開プロパティを作成します。
では、Lightning Web コンポーネントアクションを詳しく見ていきましょう。次は、JavaScript ボタンの機能のうち、Lightning Web コンポーネントアクションで代用できるものについて説明します。たとえば、ユーザー入力に基づいて項目に入力し、ユーザー入力に基づいて項目に入力し、データ入力中にフィードバックメッセージを表示するなどです。
ユーザー入力に基づく項目への入力およびフィードバックメッセージのユーザーへの表示
現在、JavaScript ボタンを使用して、データを検証または操作し、ユーザーがレコードを使って作業するときにフィードバックや指示を表示しているとします。この例では、ユーザーがレコードを作成または更新する前に、Lightning Web コンポーネントでデータをいかに簡単に検証または操作できるかを示します。
サンプル組織に、さまざまな研究プロジェクトの追跡に使用する Case Study (事例) というカスタムオブジェクトを作成しました。また、新しいテストユーザーを事例に追加し、名前とメールアドレスを取得できるように、テストユーザーカスタムオブジェクトも用意されています。メールアドレスは当社の主要な連絡手段であるため、正しく入力されるようにしたいと考えています。また、テストユーザーの匿名性を確保するために、事例の各ユーザーに一意のニックネームを作成することにします。
名前項目とメールアドレス項目を表示して、メールアドレスを検証し、名と乱数を組み合わせてニックネームを自動生成する Lightning Web コンポーネントアクションを作成していきます。
この Lightning Web コンポーネントアクションがコールするコンポーネントのコードは、次のとおりです。
- createUser.html: アクションを開いたときに表示される Lightning Web コンポーネントの構造。UI 実装 (テキスト項目、ボタン、アクションのタイトルなど) が含まれます。
- createUser.js: コンポーネントと、表示ライフサイクル、テキスト入力、ボタンのクリックなど発生したすべての UI イベントをリスンするコントローラー。JavaScript メソッドは、入力、データ、イベント、状態への変更などの処理を定義して、コンポーネントを動作させます。
- createUser.js-meta.xml: Lightning Experience での使用を目的とするコンポーネントの設計設定など、コンポーネントのメタデータを定義するコード。
createUser.html
<template> <lightning-quick-action-panel header="Add Test User to Case Study"> <lightning-input type="text" data-field="firstName" label="User's First Name" onblur={updateNickName} required ></lightning-input> <lightning-input type="text" data-field="lastName" label="User's Last Name" required ></lightning-input> <lightning-input type="text" data-field="nickName" label="Nickname" required ></lightning-input> <lightning-input type="email" data-field="email" label="User's Email" onblur={handleEmailBlur} required ></lightning-input> <lightning-input type="password" data-field="password" label="User's Password" onblur={handlePasswordBlur} required ></lightning-input> <div slot="footer"> <lightning-button variant="neutral" label="Cancel" onclick={handleCancel} ></lightning-button> <lightning-button variant="brand" label="Save User" onclick={handleSave} ></lightning-button> </div> </lightning-quick-action-panel> </template>
createUser.js
import { LightningElement, api } from 'lwc'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; import { CloseActionScreenEvent } from 'lightning/actions'; import { createRecord } from 'lightning/uiRecordApi'; import TEST_USER_OBJECT from '@salesforce/schema/Test_User__c'; import NAME_FIELD from '@salesforce/schema/Test_User__c.Name'; import PASSWORD_FIELD from '@salesforce/schema/Test_User__c.Password__c'; import EMAIL_FIELD from '@salesforce/schema/Test_User__c.Email__c'; import NICKNAME_FIELD from '@salesforce/schema/Test_User__c.Nickname__c'; import CASE_STUDY_FIELD from '@salesforce/schema/Test_User__c.Case_Study__c'; export default class CreateUser extends LightningElement { @api recordId; async handleSave() { // query form elements const firstNameEl = this.template.querySelector('[data-field="firstName"]'); const lastNameEl = this.template.querySelector('[data-field="lastName"]'); const nickNameEl = this.template.querySelector('[data-field="nickName"]'); const emailEl = this.template.querySelector('[data-field="email"]'); const passwordEl = this.template.querySelector('[data-field="password"]'); // check for errors on form elements (custom or otherwise) const isFirstNameValid = firstNameEl.reportValidity(); const isLastNameValid = lastNameEl.reportValidity(); const isNickNameValid = nickNameEl.reportValidity(); const isPasswordValid = passwordEl.reportValidity(); const isEmailValid = emailEl.reportValidity(); if(!isFirstNameValid || !isLastNameValid || !isNickNameValid || !isPasswordValid || !isEmailValid) { return; } const recordInput = { apiName: TEST_USER_OBJECT.objectApiName, fields: { [NAME_FIELD.fieldApiName]: `${firstNameEl.value} ${lastNameEl.value}`, [PASSWORD_FIELD.fieldApiName]: passwordEl.value, [EMAIL_FIELD.fieldApiName]: emailEl.value, [NICKNAME_FIELD.fieldApiName]: nickNameEl.value, [CASE_STUDY_FIELD.fieldApiName]: this.recordId, } }; try { await createRecord(recordInput); this.dispatchEvent( new ShowToastEvent({ title: 'Success!', message: 'The test user has been created.', variant: 'success' }) ); this.dispatchEvent(new CloseActionScreenEvent()); } catch (error) { new ShowToastEvent({ title: 'Error creating the test user, try again...', message: error.body.message, variant: 'error' }); } } updateNickName() { const firstName = this.template.querySelector('[data-field="firstName"]').value; const nickNameEl = this.template.querySelector('[data-field="nickName"]'); if(firstName && !nickNameEl.value) { const today = new Date(); nickNameEl.value = firstName + today.valueOf(today) } } handleCancel() { this.dispatchEvent(new CloseActionScreenEvent()); } handlePasswordBlur() { const passwordEl = this.template.querySelector('[data-field="password"]'); // clear custom errors passwordEl.setCustomValidity(''); this.validatePassword(passwordEl); } validatePassword(input) { // check lightning-input validity if(input.reportValidity()) { // perform custom validation const value = input.value; if (value === undefined) { input.setCustomValidity('You must enter a password.'); } else if (value.length < 7) { input.setCustomValidity('The password is the wrong length (must be >= 7): ' + value.length); } else if (value.length > 15) { input.setCustomValidity('The password is the wrong length (must be <= 15): ' + value.length); } else if (value.search(/[0-9]+/) === -1) { input.setCustomValidity('The password must contain at least one number.'); } else if (value.search(/[a-zA-Z]+/) === -1) { input.setCustomValidity('The password must contain at least one letter.'); } // display custom validation errors (if any) input.reportValidity(); } } handleEmailBlur() { const emailEl = this.template.querySelector('[data-field="email"]'); // clear Custom Errors emailEl.setCustomValidity(''); this.validateEmail(emailEl); } validateEmail(input) { // check lightning-input validity if (input.reportValidity()) { const value = input.value; if (!/@gmail\.com$/.test(value)) { input.setCustomValidity('Email must be a Gmail account.'); } // display custom validation errors (if any) input.reportValidity(); } } }
createUser.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?> <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"> <apiVersion>57.0</apiVersion> <isExposed>true</isExposed> <targets> <target>lightning__RecordAction</target> </targets> <targetConfigs> <targetConfig targets="lightning__RecordAction"> <actionType>ScreenAction</actionType> </targetConfig> </targetConfigs> </LightningComponentBundle>
Lightning Web コンポーネントアクションを作成する
Lightning Web コンポーネントを作成したら、アクションに割り当てます。Case Study のオブジェクト管理設定で、[ボタン、リンク、およびアクション] に移動して、[新規アクション] をクリックし、以下のパラメーターを使用してアクションを設定します。
項目 | 値 |
---|---|
アクション種別 |
|
Lightning Web コンポーネント |
|
表示ラベル |
|
名前 |
|
次に、新しい Lightning Web コンポーネントアクションを Case Study ページレイアウトに追加します。ユーザーが [Case Study (事例)] レコード詳細ページからこのアクションを起動すると、作成した Lightning Web コンポーネントアクションが表示されます。
Lightning Web コンポーネントアクションは、Lightning Experience の未来形のプログラム型アクションです。当社では、この一連のソリューションを、JavaScript ボタンの優れた代替法として考えていただくことを期待しています。
JavaScript ボタンを使用するパートナーアプリケーションを多用しているという方には、当社の多数のパートナーがすでにアプリケーションを Lightning に移行およびアップグレードし始めていることは朗報でしょう。AppExchange では、Lightning Experience 用に更新されたアプリケーションが増えています。