Salesforce LWC学习(八) Look Up组件实现
本篇参考https://www.salesforcelwc.in/2019/10/lookup-in-lwc.html,感谢前人种树。
我们做lightning的时候经常会遇到Look up 或者MD字段在页面搜索展示的需求,在标准的页面很常见,而且很好看。但是很遗憾的是在自定义组件中还没有现成的标准组件去搞定。下面介绍两种方式去实现展示lookup / MD字段的组件样式。

一. record-edit-form搭配 lightning-input-field 曲线救国
标准功能也不是100%的不近人情,还是给出一个workaround的方案去实现,实现的方式为在后台声明一个Lookup / MD的组件,然后使用lightning-input-field去实现。此组件会根据字段的类型去自动转换成其相应的样式进行展示,效果很像classic中的apex:inputField或者lightning aura中的lightning:inputField。使用lightning-record-edit-form来指定某个表的LDS,使用lightning-input-field进行效果展示,然后提交的操作时阻止默认的submit操作并且在event detail中获取到我们选择的Look up/MD对应的ID即可。demo中在Account上新建一个字段Test_User__c,类型为Look up (User).
testLookUpForLwc.html:使用LDS设置object api name为Account,这样下面就可以通过lightning-input-field针对Account的字段的类型动态展示相关的样式
<template>
<lightning-record-edit-form
object-api-name='Account'
onsubmit={handleSubmit}
>
<lightning-input-field field-name="Test_User__c"></lightning-input-field>
<lightning-button type="submit" label="get test user id" variant="brand">
</lightning-button>
</lightning-record-edit-form>
</template>
testLookUpForLwc.js:针对submit事件首先组织提交免得生成不需要的记录,然后通过event.detail.fields.Test_User__c便可以获取到所选择的Test_User__c的ID。
import { LightningElement,track } from 'lwc';
export default class TestLookUpForLwc extends LightningElement {
handleSubmit(event) {
event.preventDefault();
console.log(JSON.stringify(event.detail.fields.Test_User__c));
}
}
结果展示:选择一个用户以后,点击get test user id便可以获取到当前选择的user的id。

二.自定义组件实现
上面的方式好是好,但是此种写法没法更改相关的label信息,国内项目可能新创建个字段进行translation也可以实现,后台进行匹配也可以,但是对日项目可能管理严格,所以需要考虑自定义组件实现。自定义组件的实现的原理相对简单,难得是UI的构建,好在前辈有画好的功能直接使用,对上面的链接中的代码进行简单的修改即可使用。
customLookUpForLwc.html:展示UI,上面是一个lightning-pill / lightning-input,通过isValue来判断当前是输入框还是展示pill,下面是列表。当列表选择以后触发事件父进行处理。
<template>
<div>
<div class="slds-form-element">
<div class="slds-form-element__control">
<div class="slds-combobox_container">
<div id="box" class={boxClass} aria-expanded="true" aria-haspopup="listbox" role="combobox">
{searchLabel}
<div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">
<template if:true={isValue}>
<div id="lookup-pill" class="slds-pill-container">
<lightning-pill class="pillSize" label={valueObj} name={valueObj} onremove={handleRemovePill}>
<lightning-icon icon-name={iconName} alternative-text="acc" ></lightning-icon>
</lightning-pill>
</div>
</template>
<template if:false={isValue}>
<div class="slds-p-top_none">
<lightning-input class={inputClass} type="search" id="input" value={searchTerm}
onclick={handleClick} onchange={onChange}
variant="label-hidden" autocomplete="off" placeholder="Search..." label='account search'>
</lightning-input>
</div>
</template>
</div>
<div id="listbox-id-1" class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox">
<ul class="slds-listbox slds-listbox_vertical" role="presentation">
<template for:each={options} for:item="item">
<li key={item.Id} onclick={onSelect} data-id={item.Id} role="presentation">
<span class="slds-lookup__item-action slds-lookup__item-action--label" role="option">
<lightning-icon class="slds-icon slds-icon--small slds-icon-text-default" icon-name={iconName} alternative-text={objName} size="small"></lightning-icon>
<span class="slds-truncate">{item.Name}</span>
</span>
</li>
</template>
</ul>
</div>
</div>
</div>
</div>
</div>
</div> </template>
customLookUpForLwc.js
/* eslint-disable no-console */
/* eslint-disable @lwc/lwc/no-async-operation */ import lookUp from '@salesforce/apex/CustomLookUpForLwcController.lookUp';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import { getRecord } from 'lightning/uiRecordApi';
import { api, LightningElement, track, wire } from 'lwc'; export default class CustomLookUpForLwc extends LightningElement {
//store object record id
@api valueId;
//record API name
@api objName;
//record icon name,see Lightning Design System to choose
@api iconName; @api filter = '';
//unique key used to mark the unique component. several component use this component need to mapping
@api uniqueKey;
//used to set the field to fetch.eg: ['Account.Name'] means we need to search account name field as filter
@api fields; //search label show in lookup component
@api searchLabel; @track searchTerm;
//record name value
@track valueObj;
//record href
@track href;
//fetch result
@track options;
//is available value to show in lightning-pill
@track isValue = false; @track blurTimeout; //css
@track boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus';
@track inputClass = ''; @wire(lookUp, {searchTerm : '$searchTerm', myObject : '$objName', filter : '$filter'})
wiredRecords({ error, data }) {
if (data) {
this.record = data;
this.error = undefined;
this.options = this.record;
console.log("common this.options", JSON.stringify(this.options));
} else if (error) {
this.error = error;
this.record = undefined;
console.log("wire.error",this.error);
}
} //To get preselected or selected record
@wire(getRecord, { recordId: '$valueId', fields: '$fields' })
wiredOptions({ error, data }) {
if (data) {
console.log('execute1');
this.record = data;
this.error = undefined;
this.valueObj = this.record.fields.Name.value;
this.href = '/'+this.record.id;
this.isValue = true;
console.log("this.href", this.href);
console.log("this.record", JSON.stringify(this.record));
} else if (error) {
console.log('execute2');
this.error = error;
this.record = undefined;
console.log("this.error", this.error);
}
} handleClick() {
console.log("In handleClick"); this.searchTerm = '';
this.inputClass = 'slds-has-focus';
this.boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus slds-is-open';
} onSelect(event) {
console.log("In onSelect");
let ele = event.currentTarget;
let selectedId = ele.dataset.id;
console.log("selectedId", selectedId);
//As a best practise sending selected value to parent and inreturn parent sends the value to @api valueId
let key = this.uniqueKey;
const valueSelectedEvent = new CustomEvent('valueselect', {
detail: { selectedId, key },
});
this.dispatchEvent(valueSelectedEvent); // if(this.blurTimeout) {
// clearTimeout(this.blurTimeout);
// }
console.log(this.isValue);
this.boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus';
} onChange(event) {
console.log("In onChange");
this.searchTerm = event.target.value;
console.log("searchTerm",this.searchTerm);
} handleRemovePill() {
console.log("In handleRemovePill");
this.isValue = false;
let selectedId = '';
let key = this.uniqueKey;
const valueSelectedEvent = new CustomEvent('valueselect', {
detail: { selectedId, key },
});
this.dispatchEvent(valueSelectedEvent);
} }
testLookUpForLwc.html:引入组件,设置几个必填的参数,其中icon-name赋值可以选择链接中的以下内容进行查找https://lightningdesignsystem.com/icons/。使用accountId用来获取前台组件传递过来的ID。
<template>
<c-custom-look-up-for-lwc
unique-key={item.Id}
value-id={accountId}
obj-name="Account"
icon-name="standard:account"
search-label="Search Account"
onvalueselect={handleSelection}
search-label
fields={item.fields}>
</c-custom-look-up-for-lwc>
</template>
testLookUpForLwc.js:handleSelection用来获取accountId
import { LightningElement,track } from 'lwc';
export default class TestLookUpForLwc extends LightningElement {
@track item = {
id:'xxx',
fields:['Account.Name']
};
@track accountId;
handleSelection(event) {
console.log(event.detail.selectedId);
this.accountId = event.detail.selectedId;
}
}
效果展示:

总结:篇中通过两种方式实现lookup功能及样式的实现,如果第一种能搞定强烈推荐使用第一种,因为标准的功能稳定性以及效率会好很多,如果第一种搞定不了可以考虑自定义。lwc不易,且开发且珍惜。
Salesforce LWC学习(八) Look Up组件实现的更多相关文章
- Salesforce LWC学习(十七) 前端知识之 onclick & onblur & onmousedown
在Salesforce LWC学习(八) Look Up组件实现篇中,我们实现了公用的lookup组件,使用的过程中,会发现当我们输入内容以后,搜索出来的列表便无法被清空. 针对此种情况我们打算优化一 ...
- Salesforce LWC学习(三十) lwc superbadge项目实现
本篇参考:https://trailhead.salesforce.com/content/learn/superbadges/superbadge_lwc_specialist 我们做lwc的学习时 ...
- Salesforce LWC学习(三十九) lwc下quick action的recordId的问题和解决方案
本篇参考: https://developer.salesforce.com/docs/component-library/bundle/force:hasRecordId/documentation ...
- Salesforce LWC学习(四十) dynamic interaction 浅入浅出
本篇参考: Configure a Component for Dynamic Interactions in the Lightning App Builder - Salesforce Light ...
- Salesforce LWC学习(十五) Async 以及 Picklist 公用方法的实现
本篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) https://developer.salesfo ...
- Salesforce LWC学习(三) import & export / api & track
我们使用vs code创建lwc 时,文件会默认生成包含 template作为头的html文件,包含了 import LightningElement的 js文件以及对应的.js-meta.xml文件 ...
- Salesforce LWC学习(十六) Validity 在form中的使用浅谈
本篇参考: https://developer.salesforce.com/docs/component-library/bundle/lightning-input/documentation h ...
- Salesforce LWC学习(二十一) Error浅谈
本篇参考:https://developer.salesforce.com/docs/component-library/documentation/en/lwc/data_error https:/ ...
- Salesforce LWC学习(三十六) Quick Action 支持选择 LWC了
本篇参考: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.use_quick_act ...
随机推荐
- AOP中获取自定义注解的参数值
目录 一.利用注解实现AOP的基本流程 1.1.创建一个注解,用来注解切点(pointcut) 1.2.创建一个service,使用上面定义的注解来指定切点 1.3.创建Aspect,增加业务逻辑 ...
- vb Replace 实现
今天改一个VB程序时发现程序自带的replace 函数不知什么原因竟然不好用了 所以就自己写了一个玩玩 记录一下 'XGZ '替换字符 Private Function Replace1(ByVal ...
- 使用Swagger创建Api
1.首先创建一个web项目,选择Mvc模板 2.右键点击引用.管理Nuget程序包,浏览 搜索Swagger,下载安装下面的包 3.安装完后在App_Start里面会出现SwaggerConfig.c ...
- C# Newtonsoft.Json JsonSerializerSettings配置序列化操作
https://blog.csdn.net/u011127019/article/details/72801033
- Linux组管理(6)
在linux中每个用户必须属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念. 文件/目录的所有者:一般为文件的创建者,谁创建了该文件,就自然成为该文件的所有者 查看文件 ...
- Python检测URL状态
需求:Python检测URL状态,并追加保存200的URL 代码一: #! /usr/bin/env python #coding=utf-8 import sys import requests d ...
- SPL06-001 气压计
歌尔是全球领先的MEMS厂家,最新推出新款气压传感器SPL06-001,定位精度可达5cm 手册地址 https://download.csdn.net/download/zhangxuechao_/ ...
- Android viewPager+fragment实现滑页效果
先上图,手指在手机向左或者向右滑就可以实现相应的页面切换. 先看activity_main.xml文件,非常简单,主要是三个标题TextView和viewpager <?xml version= ...
- VUE-v-if和v-else的使用
1.v-if和v-else <h2 v-if="true">v-if</h2> <h2 v-else>v-else</h2> 注:v ...
- 由MQTT topic的正则表达式匹配引发的特殊字符"/"匹配思考
正则表达式中的'/'替换 近期项目对接OneNET的MQTT物联网套件,需要完成命令下发流程. 流程要求: (1)设备在接收平台下发的命令(topic为$sys/{pid}/{device-name} ...