本篇参考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组件实现的更多相关文章

  1. Salesforce LWC学习(十七) 前端知识之 onclick & onblur & onmousedown

    在Salesforce LWC学习(八) Look Up组件实现篇中,我们实现了公用的lookup组件,使用的过程中,会发现当我们输入内容以后,搜索出来的列表便无法被清空. 针对此种情况我们打算优化一 ...

  2. Salesforce LWC学习(三十) lwc superbadge项目实现

    本篇参考:https://trailhead.salesforce.com/content/learn/superbadges/superbadge_lwc_specialist 我们做lwc的学习时 ...

  3. Salesforce LWC学习(三十九) lwc下quick action的recordId的问题和解决方案

    本篇参考: https://developer.salesforce.com/docs/component-library/bundle/force:hasRecordId/documentation ...

  4. Salesforce LWC学习(四十) dynamic interaction 浅入浅出

    本篇参考: Configure a Component for Dynamic Interactions in the Lightning App Builder - Salesforce Light ...

  5. Salesforce LWC学习(十五) Async 以及 Picklist 公用方法的实现

    本篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) https://developer.salesfo ...

  6. Salesforce LWC学习(三) import & export / api & track

    我们使用vs code创建lwc 时,文件会默认生成包含 template作为头的html文件,包含了 import LightningElement的 js文件以及对应的.js-meta.xml文件 ...

  7. Salesforce LWC学习(十六) Validity 在form中的使用浅谈

    本篇参考: https://developer.salesforce.com/docs/component-library/bundle/lightning-input/documentation h ...

  8. Salesforce LWC学习(二十一) Error浅谈

    本篇参考:https://developer.salesforce.com/docs/component-library/documentation/en/lwc/data_error https:/ ...

  9. Salesforce LWC学习(三十六) Quick Action 支持选择 LWC了

    本篇参考: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.use_quick_act ...

随机推荐

  1. 前端跨域之Jsonp实现原理及.Net下Jsonp的实现

    jsonp的本质是通过script标签的src属性请求到服务端,拿到到服务端返回的数据 ,因为src是可以跨域的.前端通过src发送跨域请求时在请求的url带上回调函数,服务端收到请求时,接受前端传过 ...

  2. EntityFrameworkCore Db First 生成Model时出错 PowerShell 版本过低

    一般Windows7默认安装的是PowerShell 2.0 使用Vs2017开发.Net Core时.使用 EntityFrameworkCore Db First自动生成实体时需要用到下面命令: ...

  3. JavaScript学习思维导图

    JS基本概念 JS操作符 JS基本语法 JS数组 JS Date用法 JS 字符串用法 JS编程风格 JS实践

  4. template might not exist or might not be accessible by any of the configured Template Resolvers 完美解决

    初学者在maven spring boot web项目中使用thymeleaf 模板,经常会遇到  “template might not exist or might not be accessib ...

  5. Linux用户管理(4)

    Linux系统是一个多用户多任务的操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统.Linux用户至少属于一个组. 1.添加用户 useradd ...

  6. 联盟链IBM的超级账本Hyperledger Fabric框架,JP Morgan’s Quorum

    联盟链IBM的超级账本Hyperledger Fabric框架,JP Morgan’s Quorum JP Morgan’s Quorum https://www.coindesk.com/jpmor ...

  7. XSS相关Payload及Bypass的备忘录(上)

    翻译学习准备自用,同时分享给大家, 来自于: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injecti ...

  8. Qt选择文件路径

    QString file_path = QFileDialog::getExistingDirectory(this, "请选择文件路径...", "./"); ...

  9. OpenSSL 安装 (Linux系统)

    OpenSSL 编译安装 操作系统:CentOS 7 OpenSSL Version: openssl-1.1.1d.tar.gz OpenSSL下载地址为:https://www.openssl.o ...

  10. springboot集成spring data ElasticSearch

    ES支持SpringBoot使用类似于Spring Data Jpa的方式查询,使得查询更加方便. 1.依赖引入 compile “org.springframework.boot:spring-bo ...