今回は、LWCを用いた検索機能の実装についてです。
最近初めてLWCで検索機能を実装しました。ほぼ手探りですが。。。
一応それっぽい機能ができたということで公開しておきます。
参考程度に~
要件
今回は以下のような要件で実装してみました。
- ユーザーが入力した取引先名と業種を使用して、取引先を検索する機能がある。
- 取引先名は部分一致で検索され、業種は完全一致で検索される。
- 検索結果が0件の場合、エラーメッセージ “検索結果がありません” を表示する。
- 検索結果がある場合は、取引先名、電話、業種、ウェブサイトの情報がテーブル形式で表示される。
- 業種の選択肢は、取引先オブジェクトの業種(Industry)項目から取得される値を使用する。
- 入力フィールドに値が入力されていない場合、エラーメッセージ “取引先名、もしくは業種を選択してください” を表示する。
実装
まず最初に、HTMLを見てみましょう。ここでは、取引先名と業種の入力フィールドが表示され、検索ボタンが配置されています。検索結果がある場合は、取引先の情報がテーブル形式で表示されます。
<template>
<lightning-card title="取引先検索" icon-name="custom:custom21">
<div class="slds-p-around--medium">
<div class="slds-m-bottom_small" style="display:block;">
<lightning-layout>
<lightning-layout-item>
<lightning-input type="text" value={keyValName} label="取引先名 "
onchange={handleNameChange}></lightning-input>
<div if:true={industryOptions.data} class="wrapper">
<lightning-combobox label="業種" value={keyValInd} options={industryOptions.data.values}
data-field-name="Industry" onchange={handleIndustryChange}></lightning-combobox>
</div>
</lightning-layout-item>
<lightning-layout-item class="slds-m-top--large slds-m-left--small">
<lightning-button label="Search" onclick={searchAction} variant="brand"></lightning-button>
</lightning-layout-item>
</lightning-layout>
</div>
<div if:true={resultList}>
<lightning-layout class="slds-p-around--medium">
<table
class="slds-table slds-table_header-fixed slds-table_bordered slds-table_col-bordered slds-table_resizable-cols">
<thead>
<tr>
<th style="padding:5px;">取引先名</th>
<th style="padding:5px;">電話</th>
<th style="padding:5px;">業種</th>
<th style="padding:5px;">ウェブサイト</th>
</tr>
</thead>
<tbody>
<template for:each={resultList} for:item="cardItem">
<tr class="slds-hint-parent" key={cardItem.Id}>
<td>
<div class="slds-truncate">{cardItem.Name}</div>
</td>
<td>
<div class="slds-truncate">
<lightning-formatted-phone
value={cardItem.Phone}></lightning-formatted-phone>
</div>
</td>
<td>
<div class="slds-truncate">
<lightning-formatted-text
value={cardItem.Industry}></lightning-formatted-text>
</div>
</td>
<td>
<div class="slds-truncate">
<lightning-formatted-URL value={cardItem.Website}></lightning-formatted-URL>
</div>
</td>
</tr>
</template>
</tbody>
</table>
</lightning-layout>
</div>
</div>
</lightning-card>
</template>
次に、JavaScriptを見てみましょう。このコンポーネントでは、Apexコントローラから取引先リストを取得し、それを画面に表示します。また、ユーザーが入力した取引先名と業種を検索クエリに渡します。業種の選択肢は選択リスト項目から取得し、画面から選択できるようになっています。
import { LightningElement, track, wire } from 'lwc';
import getAcc from '@salesforce/apex/AccountContactSearchController.getAcc';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
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 RecordSearchLwc extends LightningElement {
recordTypeId = null;
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
accountObjectInfo;
@wire(getPicklistValues, { recordTypeId: '$accountObjectInfo.data.defaultRecordTypeId', fieldApiName: ACCOUNT_INDUSTRY_FIELD })
industryOptions;
@track keyValName = '';
@track keyValInd = '';
@track resultList;
searchAction(){
if(this.keyValName !== '' || this.keyValInd !== ''){
getAcc({searchName:this.keyValName, searchInd:this.keyValInd})
.then(result => {
this.resultList = result;
})
.catch(error => {
const event = new ShowToastEvent({
title: 'エラー',
variant: 'error',
message: error.body.message,
});
this.dispatchEvent(event);
this.resiltList = null;
});
}else {
const event = new ShowToastEvent({
variant: 'error',
message: '「取引先名」、もしくは「業種」を選択してください',
});
this.dispatchEvent(event);
}
}
handleIndustryChange(event){
this.keyValInd = event.detail.value;
}
handleNameChange(event){
this.keyValName = event.detail.value;
}
}
最後に、Apexクラス です。このクラスは、検索クエリを処理して該当する取引先のリストを取得します。getAcc
メソッドを使用して、検索名と業種を引数に取り、その結果をリストとして返します。検索結果が0件の場合は、エラーメッセージを表示します。
public with sharing class AccountSearchController {
@AuraEnabled(cacheable=true)
public static List<Account> getAcc(String searchName, String searchInd){
String searchKeyName = '%' + searchName + '%';
List<Account> accList = new List<Account>();
for(Account acc:[Select Id, Name, Phone, Industry, Website From Account Where Name Like :searchKeyName And Industry =: searchInd]){
accList.add(acc);
}
if(accList.isEmpty()){
throw new AuraHandledException('検索結果がありません');
}
return accList;
}
}
おわりに
今回はLWCを使用した取引先の検索機能についてでした。
検索機能自体はvisualforceやAura Componentと仕組み自体は同じですが、デコレータを使用したLWCならではの値の取得や受け渡しはまだ慣れないですね。
まだまだ自分はLWCでの実装経験が浅いですが、少しずつできることを増やしていきたいと思います。
おわりです。
コメント