本篇參考: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等信息。
總結:篇中只是簡單的進行封裝功能,並且只允許單選,對於多選感興趣的可以實現。改動的點不是很多。篇中有錯誤的地方歡迎指出,不懂的歡迎留言。