salesforce lightning零基础学习(十二) 自定义Lookup组件的实现
本篇参考:http://sfdcmonkey.com/2017/01/07/custom-lookup-lightning-component/,在参考的demo中进行了简单的改动和优化。
我们在https://www.cnblogs.com/zero-zyq/p/7463016.html 中使用jquery的DataTable做出来类似增强版的Lookup组件效果,通过Name可以搜索出指定的数据,选中以后获取选中的object的名称以及ID信息。此篇主要内容为lightning下使用aura框架的公用Lookup组件的实现。
本篇中的组件主要有以下几个功能:
1. 当输入两位以上字符情况下,从后台数据库检索并且放在搜索框列表中展示;
2. 当选中搜索框列表中某个指定的单元后,选中的单元会以pill的方式展示在输入框中,同时输入框隐藏,列表选择框隐藏;
3. 删除选中的单元以后,输入框变成可用状态。
实现方式如下:
1. 首先将slds的文件夹放在static resource中,demo中的路径为:slds_resource。下载的文件路径为:https://www.lightningdesignsystem.com/downloads/
包打开的结构如下:
2. 创建svg.component,用于显示slds提供的icon
svg.component
1 <aura:component > 2 <aura:attribute name="class" type="String" description="CSS classname for the SVG element" /> 3 <aura:attribute name="xlinkHref" type="String" description="SLDS icon path. Ex: /icons/utility-sprite/svg/symbols.svg#download" /> 4 <aura:attribute name="aria-hidden" type="String" default="true" description="aria-hidden true or false. defaults to true" /> 5 </aura:component>
svgRenderer.js
1 ({ 2 render: function(component, helper) { 3 var classname = component.get("v.class"); 4 var xlinkhref = component.get("v.xlinkHref"); 5 var ariaHidden = component.get("v.aria-hidden"); 6 7 var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 8 svg.setAttribute('class', classname); 9 svg.setAttribute('aria-hidden', ariaHidden); 10 svg.innerHTML = '<use xlink:href="'+xlinkhref+'"></use>'; 11 return svg; 12 } 13 })
3. selectedObjectEvent.evt:用于当搜索出来的列表选中某个指定的单元后,传递给父组件。
1 <aura:event type="COMPONENT" description=" pass the selected sObject in the parent component"> 2 <aura:attribute name="objectByEvent" type="sObject"/> 3 </aura:event>
4. customLookUpResult.cmp:用于显示搜索出来的结果的每个单元的展示组件,当选中单元后触发上面的事件。
1 <aura:component > 2 <aura:attribute name="selectedObj" type="sObject" /> 3 <aura:registerEvent name="selectedObjectEvent" type="c:selectedObjectEvent"/> 4 <li role="presentation"> 5 <span class="slds-lookup__item-action slds-media slds-media--center" role="option"> 6 <div class="slds-media__body"> 7 <div class="slds-lookup__result-text" onclick="{!c.selectObject}">{!v.selectedObj.Name} 8 </div> 9 </div> 10 </span> 11 </li> 12 </aura:component>
customLookUpResultController.js
1 ({ 2 selectObject : function(component, event, helper){ 3 var selectedObject = component.get("v.selectedObj"); 4 var compEvent = component.getEvent("selectedObjectEvent"); 5 compEvent.setParams({"objectByEvent" : selectedObject}); 6 compEvent.fire(); 7 } 8 })
5. customLookUp.cmp :主要包括几部分主要内容:
- 根据传递过来的 object 的API Name获取Label动态显示搜索的 object的Label信息;
- 展示搜索按钮,搜索后触发controller的handler来控制后台结果集的展示;
- 搜索时spinner的展示和隐藏;
- 移除选中的单元后,启用输入状态等。
1 <aura:component controller="lookUpController" implements="flexipage:availableForAllPageTypes,force:appHostable,flexipage:availableForRecordHome,force:lightningQuickActionWithoutHeader,force:hasRecordId"> 2 3 <ltng:require styles="{!$Resource.slds_resource + '/styles/salesforce-lightning-design-system.css'}"/> 4 5 <aura:attribute name="selectedRecord" type="sObject" description="store selected sObject information"/> 6 7 <aura:attribute name="objectType" type="String" description="store object type"/> 8 9 <aura:attribute name="objectLabel" type="String" description="store object label name"/> 10 11 <aura:attribute name="searchObjList" type="sObject[]" description="store sObject list, this list return from apex fetched"/> 12 13 <aura:attribute name="SearchKeyWord" type="string"/> 14 15 <aura:attribute name="Message" type="String" default="Searching..."/> 16 17 <aura:handler name="selectedObjectEvent" event="c:selectedObjectEvent" action="{!c.selectedObjectHandler}"/> 18 19 <aura:handler event="aura:waiting" action="{!c.showSpinner}"/> 20 21 <aura:handler event="aura:doneWaiting" action="{!c.hideSpinner}"/> 22 23 <aura:handler name="init" value="{!this}" action="{!c.initialData}"/> 24 25 <div class="slds-m-around--large"> 26 <div aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single"> 27 <label class="slds-form-element__label" for="resultListDiv"> {!v.objectLabel} Name</label> 28 29 <div class="slds-form-element__control"> 30 <div class="slds-input-has-icon slds-input-has-icon--right"> 31 <c:svg class="slds-input__icon slds-show" xlinkHref="{!$Resource.slds_resource + '/icons/utility-sprite/svg/symbols.svg#search'}" /> 32 33 <div aura:id="lookup-pill" class="slds-pill-container slds-hide"> 34 <span class="slds-pill"> 35 <span class="slds-pill__label"> 36 {!v.selectedRecord.Name} 37 </span> 38 <button class="slds-button slds-button--icon slds-pill__remove" onclick="{!c.clearSelectedHandler}"> 39 <c:svg class="slds-button__icon" xlinkHref="{!$Resource.slds_resource + '/icons/utility-sprite/svg/symbols.svg#close'}" /> 40 <span class="slds-assistive-text">Remove</span> 41 </button> 42 </span> 43 </div> 44 <div aura:id="lookupField" class="slds-show"> 45 <ui:inputText updateOn="keyup" keyup="{!c.fetchResultHandler}" class="slds-lookup__search-input slds-input " value="{!v.SearchKeyWord}" placeholder="must search more than 2 character" aura:id="searchValue"/> 46 </div> 47 </div> 48 </div> 49 50 <div class="slds-lookup__menu slds" id="resultListDiv"> 51 <div class="slds-lookup__item--label slds-text-body--small">{!v.Message}</div> 52 <center> <ui:spinner aura:id="spinner"/> </center> 53 <ul class="slds-lookup__list" role="listbox"> 54 <aura:iteration items="{!v.searchObjList}" var="singleRec"> 55 <c:customLookupResult selectedObj="{!singleRec}" /> 56 </aura:iteration> 57 </ul> 58 </div> 59 </div> 60 </div> 61 </aura:component>
customLookUpController.js
1 ({ 2 initialData : function(component,event,helper) { 3 var action = component.get('c.getObjectLabelByObjectName'); 4 action.setParam('objName', component.get('v.objectType')); 5 action.setCallback(this, function(response) { 6 if(response.getState() === 'SUCCESS') { 7 component.set('v.objectLabel', response.getReturnValue()); 8 } 9 }); 10 $A.enqueueAction(action); 11 }, 12 13 fetchResultHandler : function(component, event, helper) { 14 var keyWord = component.get("v.SearchKeyWord"); 15 var resultListDiv = component.find("searchRes"); 16 if( keyWord.length > 2){ 17 $A.util.addClass(resultListDiv, 'slds-is-open'); 18 $A.util.removeClass(resultListDiv, 'slds-is-close'); 19 helper.searchHelper(component,event,keyWord); 20 } 21 else{ 22 component.set("v.searchObjList", null ); 23 $A.util.addClass(resultListDiv, 'slds-is-close'); 24 $A.util.removeClass(resultListDiv, 'slds-is-open'); 25 } 26 }, 27 28 clearSelectedHandler :function(component,event,heplper){ 29 30 var pillTarget = component.find("lookup-pill"); 31 var lookUpTarget = component.find("lookupField"); 32 33 $A.util.addClass(pillTarget, 'slds-hide'); 34 $A.util.removeClass(pillTarget, 'slds-show'); 35 36 $A.util.addClass(lookUpTarget, 'slds-show'); 37 $A.util.removeClass(lookUpTarget, 'slds-hide'); 38 39 component.set("v.SearchKeyWord",null); 40 component.set("v.searchObjList", null ); 41 }, 42 43 44 selectedObjectHandler : function(component, event, helper) { 45 46 var selectedObject = event.getParam("objectByEvent"); 47 component.set("v.selectedRecord" , selectedObject); 48 var pillDiv = component.find("lookup-pill"); 49 $A.util.addClass(pillDiv, 'slds-show'); 50 $A.util.removeClass(pillDiv, 'slds-hide'); 51 52 var resultListDiv = component.find("searchRes"); 53 $A.util.addClass(resultListDiv, 'slds-is-close'); 54 $A.util.removeClass(resultListDiv, 'slds-is-open'); 55 56 var lookUpTarget = component.find("lookupField"); 57 $A.util.addClass(lookUpTarget, 'slds-hide'); 58 $A.util.removeClass(lookUpTarget, 'slds-show'); 59 60 }, 61 62 hideSpinner : function (component, event, helper) { 63 var spinner = component.find('spinner'); 64 var evt = spinner.get("e.toggle"); 65 evt.setParams({ isVisible : false }); 66 evt.fire(); 67 }, 68 69 showSpinner : function (component, event, helper) { 70 var spinner = component.find('spinner'); 71 var evt = spinner.get("e.toggle"); 72 evt.setParams({ isVisible : true }); 73 evt.fire(); 74 } 75 76 })
customLookUpHelper.js
1 ({ 2 searchHelper : function(component,event,getInputkeyWord) { 3 var action = component.get("c.fetchObjectList"); 4 action.setParams({ 5 'keyWord': getInputkeyWord, 6 'objectName' : component.get('v.objectType') 7 }); 8 9 action.setCallback(this, function(response) { 10 var state = response.getState(); 11 if (state === "SUCCESS") { 12 var resValue = response.getReturnValue(); 13 if (resValue.length == 0) { 14 component.set("v.Message", 'No Result Found.'); 15 } else { 16 component.set("v.Message", 'Search Result As Follows.'); 17 } 18 19 component.set("v.searchObjList", resValue); 20 } 21 }); 22 $A.enqueueAction(action); 23 } 24 })
6. 放在APP 里面调用
TestCustomLookUpApp.app
1 <aura:application extends="force:slds"> 2 <aura:attribute name="selectedUser" type="User"/> 3 <c:customLookUp selectedRecord="{!v.selectedUser}" objectType="User"/> 4 <lightning:button onclick="{!c.showInformation}" label="show information"/> 5 </aura:application>
TestCustomLookUpAppController.js
1 ({ 2 showInformation : function(component, event, helper) { 3 alert(component.get('v.selectedUser').Id); 4 } 5 })
结果展示:通过组件可以直接根据selectedUser获取选中的User的Id等信息。
总结:篇中只是简单的进行封装功能,并且只允许单选,对于多选感兴趣的可以实现。改动的点不是很多。篇中有错误的地方欢迎指出,不懂的欢迎留言。
作者:zero
博客地址:http://www.cnblogs.com/zero-zyq/
本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接
如果文章的内容对你有帮助,欢迎点赞~
为方便手机端查看博客,现正在将博客迁移至微信公众号:Salesforce零基础学习,欢迎各位关注。