- Salesforce Development 45
- NEWBIE
- 0 Points
- Member since 2020
-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
2Questions
-
1Replies
Not able to see lookup values selected in the search box from 2nd row
Here is the code I'm using to get account information via a lookup, I can see the values selected in the first row but when I add a new row i can't see the value selected in the search box. However, when I save the component the values I selected in the rows are being saved. The only problem is the values selected are not visible in the search box from 2nd row.
1) LightningLookupEvent.evt
2) LightningLoookup.cmp
3) LightningLookUpController.js
4) LightningLookUp.css
5)LightningLookupController.apxc
1) LightningLookupEvent.evt
<aura:event type="COMPONENT" description="by this event we are pass the selected record id in the parent component"> <aura:attribute name="recordIdByAccEvent" type="String"/> <!-- <aura:attribute name="ObjectAPIName" type="String"/> --> </aura:event>
2) LightningLoookup.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global" controller="LightningLookupController"> <!--<ltng:require styles="{!$Resource.SLDS213 +'/assets/styles/salesforce-lightning-design-system.css'}"/>--> <!-- For External Use --> <aura:attribute name="objectAPIName" type="String" /> <aura:attribute name="serialno" type="Integer" /> <aura:attribute name="listSize" type="Integer" default="5"/> <aura:attribute name="readOnly" type="boolean"/> <!-- <aura:attribute name="IconName" type="string" default=""/> --> <aura:attribute name="nameIcon" type="String" required="true" default="custom:custom57"/> <!-- <aura:attribute name="selectedRecord" type="sObject" default="{}" description="Use,for store SELECTED sObject Record"/> --> <!-- For External Use --> <!-- For Internal Use --> <aura:attribute name="queryString" type="String"/> <aura:attribute name="templateSearchList" type="Object"/> <aura:attribute name="NoResultBooleanValue" type="boolean"/> <aura:attribute name="spinnerLoad" type="Boolean" default="" /> <aura:attribute name="valueSelectedId" type="String" /> <aura:attribute name="valueSelectedName" type="String" /> <!-- For Internal Use --> <!-- aura handler for spinner --> <!-- <aura:handler event="aura:waiting" action="{!c.showSpinner}"/> --> <!-- <aura:handler event="aura:doneWaiting" action="{!c.hideSpinner}"/> --> <!-- Event for passing the selected record to parent component --> <aura:registerEvent name="selectRecordIdEvent" type="c:LightningLookUpEvent"/> <form aura:id="lookupForm" > <div> <!-- this is lookup pill, it will display when user select any value from the list --> <div id="{!'lookuppill'+v.objectAPIName}" class="slds-pill-container slds-hide" onmouseover="{!c.onCrossChange}" onmouseout="{!c.onCrossChangeOut}"> <span class="slds-pill" style="width:100%"> <span class="slds-icon_container slds-combobox__input-entity-icon" title="record"> <lightning:icon iconName="{!v.nameIcon}" size="x-small"/> <span class="slds-assistive-text"></span> </span> <span aura:id="recordList" class="slds-pill__label slds-p-left_x-large" onmouseover="{!c.onCrossChange}" onmouseout="{!c.onCrossChangeOut}"> {!v.valueSelectedName} </span> <img class="slds-icon slds-input__icon slds-input__icon_right slds-icon-text-default" src="{!$Resource.LookUpPNGImage+ '/IP_Lightning/Close.PNG'}" style="width:24px; cursor: pointer; height:25px;margin-top: -0.115remrem;margin-right: -0.0rem;" id="{!'closeButton1'+v.objectAPIName}" onclick="{!c.removePill}" title="Close" draggable="false" /> <img class="slds-hide slds-icon slds-input__icon slds-input__icon_right slds-icon-text-default" src="{!$Resource.LookUpPNGImage+ '/IP_Lightning/CloseForLookUp.PNG'}" style="width:24px; cursor: pointer; height:25px;margin-top: -0.115remrem;margin-right: -0.0rem;" id="{!'closeButton2'+v.objectAPIName}" onclick="{!c.removePill}" title="Close" draggable="false" /> </span> </div> <!--This section is to show the input text box for Searching template--> <div id="{!'smallDiv'+v.objectAPIName}" class="slds-show slds-input-has-icon slds-input-has-icon--right"> <aura:if isTrue="{!v.spinnerLoad}"> <div class="slds-float_right" aura:id="spinner"> <lightning:spinner class="slds-spinner_brand slds-float_right" size="small" /> </div> </aura:if> <img class="slds-show slds-icon slds-input__icon slds-input__icon_right slds-icon-text-default" src="{!$Resource.LookUpPNGImage+ '/IP_Lightning/Search.PNG'}" style="width:24px; cursor: pointer; height:25px;margin-top: -0.66rem;margin-right: -0.4rem;" id="{!'searchbutton'+v.objectAPIName}" title="Search" draggable="false"/> <input type="text" id="{!'inputMain'+v.objectAPIName}" class="slds-input slds-has-input-focus" value="{!v.queryString}" onkeyup="{!c.onValueChange}" placeholder="Search.." autocomplete="off" /> </div> <!--This section is to show the list of records names as a drop down list after the user types a string and the search result is retrieved--> <div class="slds-show" id="{!'listShow'+v.objectAPIName}"> <ul class="customdropdown" role="presentation" style="display: block; min-width: auto; max-width: 100% ; width: 100%;"> <!-- <ul style="min-height:40px;margin-top:0px !important" class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid slds-lookup__menu slds" role="listbox"> --> <aura:iteration items="{!v.templateSearchList}" var="list" > <div class="slds-box slds-box_xx-small slds-show slds-input-has-icon" > <li class="slds-dropdown__item " data-id="{!list.Id}" data-name="{!list.Name}" onclick="{!c.selectedTemplate}" role="presentation"> <a href="javascript:void(0);" data-id="{!list.Id}" data-name="{!list.Name}" data-value="{!list}" role="menuitem" tabindex="0" > <span class="slds-icon_container slds-combobox__input-entity-icon" title="record"> <lightning:icon iconName="{!v.nameIcon}" size="x-small"/> <span class="slds-assistive-text"></span> </span> <span data-name="{!list.Name}" data-id="{!list.Id}" data-value="{!list}" class="FontNotification slds-text-align_left slds-truncate slds-p-left_large">{!list.Name}</span> </a> </li> </div> </aura:iteration> </ul> </div> <!-- this section will display if there are no matching values with the searched string --> <ul class="{!v.NoResultBooleanValue == true ? 'slds-dropdown__list' : 'slds-hide'}" role="menu"> <div class="slds-box slds-box_xx-small"> <li class="slds-dropdown__item" role="presentation"> <span class="slds-truncate slds-p-left_medium"><b>No Match Found</b></span> </li> </div> </ul> </div> </form> </aura:component>
3) LightningLookUpController.js
({ onValueChange : function(component, event, helper) { var target = event.target; console.log('target.value :: '+target.value); var objectName = component.get("v.objectAPIName"); var inputBox=document.getElementById("inputMain"+objectName); //Clear the timer clearTimeout(window.timer); //Setting the timer to 0.5 second / 500 ms. After the user stops typing, 0.5 seconds later the below server call will be made window.timer = setTimeout($A.getCallback(function(){ // if the input text box is blank, template search list is given null value if(target.value==''){ console.log('inside query empty string'); component.set('v.templateSearchList', null); component.set('v.queryString',null); }else{ var action = component.get('c.getObjectNameList'); action.setParams({ "typedString" : target.value, "objectApi" : component.get("v.objectAPIName"), "num" : component.get("v.listSize") }); action.setCallback(this,function(response){ var state = response.getState(); if(state =='SUCCESS'){ // Result contains the list of template names along with its IDs var result = response.getReturnValue(); console.log('Success and the template list are-->'+JSON.stringify(result, null, 4)); if(result != null){ // set the list of templates retrieved from server as a drop down list below the inputText box in the component if(result.length>0){ component.set("v.NoResultBooleanValue",false); }else{ console.log('Inside another lse of null '); component.set("v.NoResultBooleanValue",true); } var tempList = document.getElementById("listShow"+objectName); $A.util.removeClass(tempList, 'slds-hide'); component.set('v.templateSearchList', result); }else{ // If there is no result, show a message saying no result found } } }); $A.enqueueAction(action); } }),500); }, //show spinner showSpinner : function (component) { component.set("v.spinnerLoad","true"); }, //Hide spinner hideSpinner : function (component) { component.set("v.spinnerLoad","false"); }, //when user will click on the value in a the record list selectedTemplate : function(component, event, helper){ var target =event.target || event.srcElement; console.log('clicked on select template -->'); var recordsId = target.dataset.id; var objectName = component.get("v.objectAPIName"); var recordsName = target.dataset.name; console.log('recordsName-->'+recordsName); console.log('recordsId-->'+recordsId); //Populate the textinput field with the complete name of the Objects Record template since it is selected by the user. component.set("v.valueSelectedId",recordsId); component.set("v.valueSelectedName",recordsName); var recordIdForEvent = component.get("v.valueSelectedId"); // call the event var compEvent = component.getEvent("selectRecordIdEvent"); console.log('compEvent value :: '+compEvent); // set the Selected sObject Record to the event attribute. compEvent.setParams({"recordIdByAccEvent" : recordsId, "objectAPINameEvent" : objectName}); // fire the event compEvent.fire(); //hide input textbox after clicking on the record from the list //var tempBoxx = document.getElementById("smallDiv"+objectName); var tempBoxx = document.querySelectorAll("smallDiv"+objectName);; for(var i=0; i<tempBoxx.length; i++) { console.log('dom tempBoxx :: '+tempBoxx[i]); $A.util.removeClass(tempBoxx[i], 'slds-show'); $A.util.addClass(tempBoxx[i], 'slds-hide'); } //show lookup pill with selected value after clicking on the record from the list // var pill = document.getElementById("lookuppill"+objectName); var pill = document.querySelectorAll("lookuppill"+objectName); for(var i=0; i<pill.length; i++) { console.log('pill :: '+pill); $A.util.removeClass(pill[i], 'slds-hide'); $A.util.addClass(pill[i], 'slds-show'); } //Hide the iterating list of template names var tempList = document.getElementById("listShow"+objectName); console.log('Checking tempList :: '+tempList); $A.util.removeClass(tempList, 'slds-show'); $A.util.addClass(tempList, 'slds-hide'); component.set('v.templateSearchList', null); component.set("v.valueSelectedId",null); }, //when user will click on the cross button in the looup pill removePill : function(component, event, helper){ var objectName = component.get("v.objectAPIName"); //hide lookup pill with selected value after clicking on the cross button in the looup pill var pill = document.getElementById("lookuppill"+objectName); console.log('dom pill :: '+pill); $A.util.removeClass(pill, 'slds-show'); $A.util.addClass(pill, 'slds-hide'); //show input textbox after clicking on the cross button in the looup pill var tempBoxx = document.getElementById("smallDiv"+objectName); console.log('dom tempBoxx :: '+tempBoxx); $A.util.removeClass(tempBoxx, 'slds-hide'); $A.util.addClass(tempBoxx, 'slds-show'); component.set("v.queryString",null); component.set("v.templateSearchList",null); component.set("v.valueSelectedId",null); component.set("v.valueSelectedName",null); }, //when user will hover on the cross button cross button will be live onCrossChange : function(component, event, helper){ console.log('onCrossChange onCrossChange onCrossChange :: '); var objectName = component.get("v.objectAPIName"); var close1 = document.getElementById("closeButton1"+objectName); console.log('dom close1 :: '+close1); $A.util.removeClass(close1, 'slds-show'); $A.util.addClass(close1, 'slds-hide'); var close2 = document.getElementById("closeButton2"+objectName); console.log('dom closeButton2 :: '+close2); $A.util.removeClass(close2, 'slds-hide'); $A.util.addClass(close2, 'slds-show'); }, //when user will hover on the cross button cross button will be live onCrossChangeOut : function(component, event, helper){ console.log('onCrossChangeOut onCrossChangeOut onCrossChangeOut :: '); var objectName = component.get("v.objectAPIName"); var close2 = document.getElementById("closeButton2"+objectName); console.log('dom closeButton2 :: '+close2); $A.util.removeClass(close2, 'slds-show'); $A.util.addClass(close2, 'slds-hide'); var close1 = document.getElementById("closeButton1"+objectName); console.log('dom close1 :: '+close1); $A.util.removeClass(close1, 'slds-hide'); $A.util.addClass(close1, 'slds-show'); }, })
4) LightningLookUp.css
.THIS .customdropdown{ left: 0%; position: absolute; background-color: white; }
5)LightningLookupController.apxc
public class LightningLookupController { @AuraEnabled public static List < sObject > getObjectNameList(String typedString, String objectApi, Integer num) { system.debug('ObjectName-->' + objectApi); String searchKey = '%'+ typedString + '%'; List < sObject > returnList = new List < sObject > (); // Create a Dynamic SOQL Query For Fetch Record List with LIMIT 5 String sQuery = 'select id, Name from ' +objectApi + ' where Name LIKE: searchKey order by createdDate DESC limit '+num; List < sObject > lstOfRecords = Database.query(sQuery); for (sObject obj: lstOfRecords) { returnList.add(obj); } return returnList; } }
- Salesforce Development 45
- March 11, 2020
- Like
- 0
Not able to Insert value selected from a lookup field using add/delete rows while using custom re-usable lookup field
Hello Salesforce Gurus, I am pretty new to Salesforce development and I am trying to create a custom lightning component with add/delete rows functionality with lookup fields in the grid. I can successfully select the values for lookup fields. However, when I try to save the values of lookup fields the values don't get passed over to the Intended object and it shows blank values. Any help would be really appreciated, I've been working on this lookup field for like last three days without much success.
Thank you all for the help!
Thank you all for the help!
This is the lightning component where I am selecting the lookup field 'User', added a custom field User in accounts and this component has been named as Sample.cmp <aura:component controller="AuraSampleController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction,lightning:isUrlAddressable,lightning:actionOverride" access="global"> <aura:attribute name="accountList" type="Account[]"/> <aura:attribute name="selectedLookUpRecord" type="sObject" default="{}"/> <div class="slds-m-around--xx-large"> <div class="slds-float_right slds-p-bottom_small"> <h1 class="slds-page-header__title">Add Row <lightning:buttonIcon iconName="utility:add" size="large" variant="bare" alternativeText="Add" onclick="{!c.addRow}"/> </h1> </div> <div class="container-fluid"> <table class="slds-table slds-table_bordered slds-table_cell-buffer"> <thead> <tr class="slds-text-title_caps"> <th scope="col"> <div class="slds-truncate">#</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Name">Account Name</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Number">Account Number</div> </th> <th scope="col"> <div class="slds-truncate" title="Phone">Phone</div> </th> <th scope="col"> <div class="slds-truncate" title="Action">User</div> </th> <th scope="col"> <div class="slds-truncate" title="Action">Action</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.accountList}" var="acc" indexVar="index"> <tr> <td> {!index + 1} </td> <td> <lightning:input name="accName" type="text" required="true" maxlength="50" label="Account Name" value="{!acc.Name}" /> </td> <td> <lightning:input name="accNumber" type="text" maxlength="10" label="Account Number" value="{!acc.AccountNumber}" /> </td> <td> <lightning:input name="accPhone" type="phone" maxlength="10" label="Phone" value="{!acc.Phone}" /> </td> <td> <c:customLookup objectAPIName="User" IconName="standard:Contact" selectedRecord="{!v.selectedLookUpRecord}"/> <!-- <c:LightningLookUp objectAPIName="account" NameIcon="standard:account" /> --> </td> <td> <a onclick="{!c.removeRow}" data-record="{!index}"> <lightning:icon iconName="utility:delete" size="small" alternativeText="Delete"/> <span class="slds-assistive-text">Delete</span> </a> </td> </tr> </aura:iteration> </tbody> </table> <div class="slds-align_absolute-center slds-p-top_small"> <lightning:button variant="brand" label="Submit" title="Brand action" onclick="{!c.save}" /> </div> </div> </div> </aura:component>
SampleController.js ({ addRow: function(component, event, helper) { helper.addAccountRecord(component, event); }, removeRow: function(component, event, helper) { //Get the account list var accountList = component.get("v.accountList"); //Get the target object var selectedItem = event.currentTarget; //Get the selected item index var index = selectedItem.dataset.record; accountList.splice(index, 1); component.set("v.accountList", accountList); }, save: function(component, event, helper) { if (helper.validateAccountList(component, event)) { helper.saveAccountList(component, event); } }, })
SampleHelper.js ({ addAccountRecord: function(component, event) { //get the account List from component var accountList = component.get("v.accountList"); //Add New Account Record accountList.push({ 'sobjectType': 'Account', 'Name': '', 'AccountNumber': '', 'Phone': '', 'User__c':'' }); component.set("v.accountList", accountList); }, validateAccountList: function(component, event) { //Validate all account records var isValid = true; var accountList = component.get("v.accountList"); for (var i = 0; i < accountList.length; i++) { if (accountList[i].Name == '') { isValid = false; alert('Account Name cannot be blank on row number ' + (i + 1)); } } return isValid; }, saveAccountList: function(component, event, helper) { //Call Apex class and pass account list parameters var action = component.get("c.saveAccounts"); action.setParams({ "accList": component.get("v.accountList") }); action.setCallback(this, function(response) { var state = response.getState(); if (state === "SUCCESS") { component.set("v.accountList", []); alert('Account records saved successfully'); } }); $A.enqueueAction(action); }, })
AuraSampleController.apxc public with sharing class AuraSampleController{ @AuraEnabled public static void saveAccounts(List<Account> accList){ Insert accList; } }
customLookup.cmp <aura:component controller="customLookUpController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global"> <!--declare attributes--> <aura:attribute name="selectedRecord" type="sObject" default="{}" description="Use,for store SELECTED sObject Record"/> <aura:attribute name="listOfSearchRecords" type="List" description="Use,for store the list of search records which returns from apex class"/> <aura:attribute name="SearchKeyWord" type="string"/> <aura:attribute name="objectAPIName" type="string" default=""/> <aura:attribute name="IconName" type="string" default=""/> <aura:attribute name="label" type="string" default=""/> <aura:attribute name="Message" type="String" default=""/> <!--declare events hendlers--> <aura:handler name="oSelectedRecordEvent" event="c:selectedsObjectRecordEvent" action="{!c.handleComponentEvent}"/> <aura:registerevent name ="selectRecordIdEvent" type="c:LightningLookUpEvent"/> <!-- https://www.lightningdesignsystem.com/components/lookups/ --> <div onmouseleave="{!c.onblur}" aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single"> <label class="slds-form-element__label" for="lookup-348">{!v.label}</label> <!--This part is for display search bar for lookup--> <div class="slds-form-element__control"> <div class="slds-input-has-icon slds-input-has-icon--right"> <!-- This markup is for when an record is selected --> <div aura:id="lookup-pill" class="slds-pill-container slds-hide"> <lightning:pill class="pillSize" label="{!v.selectedRecord.Name}" name="{!v.selectedRecord.Name}" onremove="{! c.clear }"> <aura:set attribute="media"> <lightning:icon iconName="{!v.IconName}" size="x-small" alternativeText="{!v.IconName}"/> </aura:set> </lightning:pill> </div> <div aura:id="lookupField" class="slds-show"> <lightning:icon class="slds-input__icon slds-show" iconName="utility:search" size="x-small" alternativeText="search"/> <span class="slds-icon_container slds-combobox__input-entity-icon" title="record"> <lightning:icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" iconName="{!v.IconName}" size="x-small" alternativeText="icon"/> <span class="slds-assistive-text"></span> </span> <ui:inputText click="{!c.onfocus}" updateOn="keyup" keyup="{!c.keyPressController}" class="slds-lookup__search-input slds-input leftPaddingClass" value="{!v.SearchKeyWord}" placeholder="search.."/> </div> </div> </div> <!--This part is for Display typehead lookup result List--> <ul style="min-height:40px;margin-top:0px !important" class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid slds-lookup__menu slds" role="listbox"> <lightning:spinner class="slds-hide" variant="brand" size="small" aura:id="mySpinner"/> <center> {!v.Message}</center> <aura:iteration items="{!v.listOfSearchRecords}" var="singleRec"> <c:customLookupResults oRecord="{!singleRec}" IconName="{!v.IconName}"/> </aura:iteration> </ul> </div> </aura:component>
customLookupController.js ({ onfocus : function(component,event,helper){ $A.util.addClass(component.find("mySpinner"), "slds-show"); var forOpen = component.find("searchRes"); $A.util.addClass(forOpen, 'slds-is-open'); $A.util.removeClass(forOpen, 'slds-is-close'); // Get Default 5 Records order by createdDate DESC var getInputkeyWord = ''; helper.searchHelper(component,event,getInputkeyWord); }, onblur : function(component,event,helper){ component.set("v.listOfSearchRecords", null ); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); }, keyPressController : function(component, event, helper) { // get the search Input keyword var getInputkeyWord = component.get("v.SearchKeyWord"); // check if getInputKeyWord size id more then 0 then open the lookup result List and // call the helper // else close the lookup result List part. if( getInputkeyWord.length > 0 ){ var forOpen = component.find("searchRes"); $A.util.addClass(forOpen, 'slds-is-open'); $A.util.removeClass(forOpen, 'slds-is-close'); helper.searchHelper(component,event,getInputkeyWord); } else{ component.set("v.listOfSearchRecords", null ); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); } }, // function for clear the Record Selaction clear :function(component,event,heplper){ var pillTarget = component.find("lookup-pill"); var lookUpTarget = component.find("lookupField"); $A.util.addClass(pillTarget, 'slds-hide'); $A.util.removeClass(pillTarget, 'slds-show'); $A.util.addClass(lookUpTarget, 'slds-show'); $A.util.removeClass(lookUpTarget, 'slds-hide'); component.set("v.SearchKeyWord",null); component.set("v.listOfSearchRecords", null ); component.set("v.selectedRecord", {} ); }, // This function call when the end User Select any record from the result list. handleComponentEvent : function(component, event, helper) { // get the selected Account record from the COMPONETN event var selectedAccountGetFromEvent = event.getParam("recordByEvent"); component.set("v.selectedRecord" , selectedAccountGetFromEvent); var forclose = component.find("lookup-pill"); $A.util.addClass(forclose, 'slds-show'); $A.util.removeClass(forclose, 'slds-hide'); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); var lookUpTarget = component.find("lookupField"); $A.util.addClass(lookUpTarget, 'slds-hide'); $A.util.removeClass(lookUpTarget, 'slds-show'); }, })
customLookupHelper.js ({ searchHelper : function(component,event,getInputkeyWord) { // call the apex class method var action = component.get("c.fetchLookUpValues"); // set param to method action.setParams({ 'searchKeyWord': getInputkeyWord, 'ObjectName' : component.get("v.objectAPIName") }); // set a callBack action.setCallback(this, function(response) { $A.util.removeClass(component.find("mySpinner"), "slds-show"); var state = response.getState(); if (state === "SUCCESS") { var storeResponse = response.getReturnValue(); // if storeResponse size is equal 0 ,display No Result Found... message on screen. } if (storeResponse.length == 0) { component.set("v.Message", 'No Result Found...'); } else { component.set("v.Message", ''); } // set searchResult list with return value from server. component.set("v.listOfSearchRecords", storeResponse); } }); // enqueue the Action $A.enqueueAction(action); }, })
customLookup.css .THIS .leftPaddingClass { padding-left: 2rem; } .THIS .pillSize{ width:100%; }
customLookUpController.apxc public class customLookUpController { @AuraEnabled public static List < sObject > fetchLookUpValues(String searchKeyWord, String ObjectName) { system.debug('ObjectName-->' + ObjectName); String searchKey = searchKeyWord + '%'; List < sObject > returnList = new List < sObject > (); // Create a Dynamic SOQL Query For Fetch Record List with LIMIT 5 String sQuery = 'select id, Name from ' +ObjectName + ' where Name LIKE: searchKey order by createdDate DESC limit 5'; List < sObject > lstOfRecords = Database.query(sQuery); for (sObject obj: lstOfRecords) { returnList.add(obj); } return returnList; } }
customLookupResults.cmp <aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global"> <aura:attribute name="oRecord" type="sObject" /> <aura:attribute name="IconName" type="string"/> <!--Register the component level event--> <aura:registerEvent name="oSelectedRecordEvent" type="c:selectedsObjectRecordEvent"/> <li role="presentation" class="slds-listbox__item" onclick="{!c.selectRecord}"> <span id="listbox-option-unique-id-01" class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option"> <span class="slds-media__figure"> <span class="slds-icon_container" title="Description of icon when needed"> <lightning:icon iconName="{!v.IconName}" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/> <span class="slds-assistive-text">Description of icon</span> </span> </span> <span class="slds-media__body"> <span class="slds-listbox__option-text slds-listbox__option-text_entity">{!v.oRecord.Name}</span> </span> </span> </li> </aura:component>
customLookupResultsController.js ({ selectRecord : function(component, event, helper){ // get the selected record from list var getSelectRecord = component.get("v.oRecord"); // call the event var compEvent = component.getEvent("oSelectedRecordEvent"); // set the Selected sObject Record to the event attribute. compEvent.setParams({"recordByEvent" : getSelectRecord }); // fire the event compEvent.fire(); }, })
selectedsObjectRecordEvent.evt <aura:event type="COMPONENT" description="by this event we are pass the selected sObject(lookup list record) in the parent component"> <aura:attribute name="recordByEvent" type="sObject"/> </aura:event>
- Salesforce Development 45
- March 05, 2020
- Like
- 0
Not able to Insert value selected from a lookup field using add/delete rows while using custom re-usable lookup field
Hello Salesforce Gurus, I am pretty new to Salesforce development and I am trying to create a custom lightning component with add/delete rows functionality with lookup fields in the grid. I can successfully select the values for lookup fields. However, when I try to save the values of lookup fields the values don't get passed over to the Intended object and it shows blank values. Any help would be really appreciated, I've been working on this lookup field for like last three days without much success.
Thank you all for the help!
Thank you all for the help!
This is the lightning component where I am selecting the lookup field 'User', added a custom field User in accounts and this component has been named as Sample.cmp <aura:component controller="AuraSampleController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction,lightning:isUrlAddressable,lightning:actionOverride" access="global"> <aura:attribute name="accountList" type="Account[]"/> <aura:attribute name="selectedLookUpRecord" type="sObject" default="{}"/> <div class="slds-m-around--xx-large"> <div class="slds-float_right slds-p-bottom_small"> <h1 class="slds-page-header__title">Add Row <lightning:buttonIcon iconName="utility:add" size="large" variant="bare" alternativeText="Add" onclick="{!c.addRow}"/> </h1> </div> <div class="container-fluid"> <table class="slds-table slds-table_bordered slds-table_cell-buffer"> <thead> <tr class="slds-text-title_caps"> <th scope="col"> <div class="slds-truncate">#</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Name">Account Name</div> </th> <th scope="col"> <div class="slds-truncate" title="Account Number">Account Number</div> </th> <th scope="col"> <div class="slds-truncate" title="Phone">Phone</div> </th> <th scope="col"> <div class="slds-truncate" title="Action">User</div> </th> <th scope="col"> <div class="slds-truncate" title="Action">Action</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.accountList}" var="acc" indexVar="index"> <tr> <td> {!index + 1} </td> <td> <lightning:input name="accName" type="text" required="true" maxlength="50" label="Account Name" value="{!acc.Name}" /> </td> <td> <lightning:input name="accNumber" type="text" maxlength="10" label="Account Number" value="{!acc.AccountNumber}" /> </td> <td> <lightning:input name="accPhone" type="phone" maxlength="10" label="Phone" value="{!acc.Phone}" /> </td> <td> <c:customLookup objectAPIName="User" IconName="standard:Contact" selectedRecord="{!v.selectedLookUpRecord}"/> <!-- <c:LightningLookUp objectAPIName="account" NameIcon="standard:account" /> --> </td> <td> <a onclick="{!c.removeRow}" data-record="{!index}"> <lightning:icon iconName="utility:delete" size="small" alternativeText="Delete"/> <span class="slds-assistive-text">Delete</span> </a> </td> </tr> </aura:iteration> </tbody> </table> <div class="slds-align_absolute-center slds-p-top_small"> <lightning:button variant="brand" label="Submit" title="Brand action" onclick="{!c.save}" /> </div> </div> </div> </aura:component>
SampleController.js ({ addRow: function(component, event, helper) { helper.addAccountRecord(component, event); }, removeRow: function(component, event, helper) { //Get the account list var accountList = component.get("v.accountList"); //Get the target object var selectedItem = event.currentTarget; //Get the selected item index var index = selectedItem.dataset.record; accountList.splice(index, 1); component.set("v.accountList", accountList); }, save: function(component, event, helper) { if (helper.validateAccountList(component, event)) { helper.saveAccountList(component, event); } }, })
SampleHelper.js ({ addAccountRecord: function(component, event) { //get the account List from component var accountList = component.get("v.accountList"); //Add New Account Record accountList.push({ 'sobjectType': 'Account', 'Name': '', 'AccountNumber': '', 'Phone': '', 'User__c':'' }); component.set("v.accountList", accountList); }, validateAccountList: function(component, event) { //Validate all account records var isValid = true; var accountList = component.get("v.accountList"); for (var i = 0; i < accountList.length; i++) { if (accountList[i].Name == '') { isValid = false; alert('Account Name cannot be blank on row number ' + (i + 1)); } } return isValid; }, saveAccountList: function(component, event, helper) { //Call Apex class and pass account list parameters var action = component.get("c.saveAccounts"); action.setParams({ "accList": component.get("v.accountList") }); action.setCallback(this, function(response) { var state = response.getState(); if (state === "SUCCESS") { component.set("v.accountList", []); alert('Account records saved successfully'); } }); $A.enqueueAction(action); }, })
AuraSampleController.apxc public with sharing class AuraSampleController{ @AuraEnabled public static void saveAccounts(List<Account> accList){ Insert accList; } }
customLookup.cmp <aura:component controller="customLookUpController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global"> <!--declare attributes--> <aura:attribute name="selectedRecord" type="sObject" default="{}" description="Use,for store SELECTED sObject Record"/> <aura:attribute name="listOfSearchRecords" type="List" description="Use,for store the list of search records which returns from apex class"/> <aura:attribute name="SearchKeyWord" type="string"/> <aura:attribute name="objectAPIName" type="string" default=""/> <aura:attribute name="IconName" type="string" default=""/> <aura:attribute name="label" type="string" default=""/> <aura:attribute name="Message" type="String" default=""/> <!--declare events hendlers--> <aura:handler name="oSelectedRecordEvent" event="c:selectedsObjectRecordEvent" action="{!c.handleComponentEvent}"/> <aura:registerevent name ="selectRecordIdEvent" type="c:LightningLookUpEvent"/> <!-- https://www.lightningdesignsystem.com/components/lookups/ --> <div onmouseleave="{!c.onblur}" aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single"> <label class="slds-form-element__label" for="lookup-348">{!v.label}</label> <!--This part is for display search bar for lookup--> <div class="slds-form-element__control"> <div class="slds-input-has-icon slds-input-has-icon--right"> <!-- This markup is for when an record is selected --> <div aura:id="lookup-pill" class="slds-pill-container slds-hide"> <lightning:pill class="pillSize" label="{!v.selectedRecord.Name}" name="{!v.selectedRecord.Name}" onremove="{! c.clear }"> <aura:set attribute="media"> <lightning:icon iconName="{!v.IconName}" size="x-small" alternativeText="{!v.IconName}"/> </aura:set> </lightning:pill> </div> <div aura:id="lookupField" class="slds-show"> <lightning:icon class="slds-input__icon slds-show" iconName="utility:search" size="x-small" alternativeText="search"/> <span class="slds-icon_container slds-combobox__input-entity-icon" title="record"> <lightning:icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" iconName="{!v.IconName}" size="x-small" alternativeText="icon"/> <span class="slds-assistive-text"></span> </span> <ui:inputText click="{!c.onfocus}" updateOn="keyup" keyup="{!c.keyPressController}" class="slds-lookup__search-input slds-input leftPaddingClass" value="{!v.SearchKeyWord}" placeholder="search.."/> </div> </div> </div> <!--This part is for Display typehead lookup result List--> <ul style="min-height:40px;margin-top:0px !important" class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid slds-lookup__menu slds" role="listbox"> <lightning:spinner class="slds-hide" variant="brand" size="small" aura:id="mySpinner"/> <center> {!v.Message}</center> <aura:iteration items="{!v.listOfSearchRecords}" var="singleRec"> <c:customLookupResults oRecord="{!singleRec}" IconName="{!v.IconName}"/> </aura:iteration> </ul> </div> </aura:component>
customLookupController.js ({ onfocus : function(component,event,helper){ $A.util.addClass(component.find("mySpinner"), "slds-show"); var forOpen = component.find("searchRes"); $A.util.addClass(forOpen, 'slds-is-open'); $A.util.removeClass(forOpen, 'slds-is-close'); // Get Default 5 Records order by createdDate DESC var getInputkeyWord = ''; helper.searchHelper(component,event,getInputkeyWord); }, onblur : function(component,event,helper){ component.set("v.listOfSearchRecords", null ); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); }, keyPressController : function(component, event, helper) { // get the search Input keyword var getInputkeyWord = component.get("v.SearchKeyWord"); // check if getInputKeyWord size id more then 0 then open the lookup result List and // call the helper // else close the lookup result List part. if( getInputkeyWord.length > 0 ){ var forOpen = component.find("searchRes"); $A.util.addClass(forOpen, 'slds-is-open'); $A.util.removeClass(forOpen, 'slds-is-close'); helper.searchHelper(component,event,getInputkeyWord); } else{ component.set("v.listOfSearchRecords", null ); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); } }, // function for clear the Record Selaction clear :function(component,event,heplper){ var pillTarget = component.find("lookup-pill"); var lookUpTarget = component.find("lookupField"); $A.util.addClass(pillTarget, 'slds-hide'); $A.util.removeClass(pillTarget, 'slds-show'); $A.util.addClass(lookUpTarget, 'slds-show'); $A.util.removeClass(lookUpTarget, 'slds-hide'); component.set("v.SearchKeyWord",null); component.set("v.listOfSearchRecords", null ); component.set("v.selectedRecord", {} ); }, // This function call when the end User Select any record from the result list. handleComponentEvent : function(component, event, helper) { // get the selected Account record from the COMPONETN event var selectedAccountGetFromEvent = event.getParam("recordByEvent"); component.set("v.selectedRecord" , selectedAccountGetFromEvent); var forclose = component.find("lookup-pill"); $A.util.addClass(forclose, 'slds-show'); $A.util.removeClass(forclose, 'slds-hide'); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); var lookUpTarget = component.find("lookupField"); $A.util.addClass(lookUpTarget, 'slds-hide'); $A.util.removeClass(lookUpTarget, 'slds-show'); }, })
customLookupHelper.js ({ searchHelper : function(component,event,getInputkeyWord) { // call the apex class method var action = component.get("c.fetchLookUpValues"); // set param to method action.setParams({ 'searchKeyWord': getInputkeyWord, 'ObjectName' : component.get("v.objectAPIName") }); // set a callBack action.setCallback(this, function(response) { $A.util.removeClass(component.find("mySpinner"), "slds-show"); var state = response.getState(); if (state === "SUCCESS") { var storeResponse = response.getReturnValue(); // if storeResponse size is equal 0 ,display No Result Found... message on screen. } if (storeResponse.length == 0) { component.set("v.Message", 'No Result Found...'); } else { component.set("v.Message", ''); } // set searchResult list with return value from server. component.set("v.listOfSearchRecords", storeResponse); } }); // enqueue the Action $A.enqueueAction(action); }, })
customLookup.css .THIS .leftPaddingClass { padding-left: 2rem; } .THIS .pillSize{ width:100%; }
customLookUpController.apxc public class customLookUpController { @AuraEnabled public static List < sObject > fetchLookUpValues(String searchKeyWord, String ObjectName) { system.debug('ObjectName-->' + ObjectName); String searchKey = searchKeyWord + '%'; List < sObject > returnList = new List < sObject > (); // Create a Dynamic SOQL Query For Fetch Record List with LIMIT 5 String sQuery = 'select id, Name from ' +ObjectName + ' where Name LIKE: searchKey order by createdDate DESC limit 5'; List < sObject > lstOfRecords = Database.query(sQuery); for (sObject obj: lstOfRecords) { returnList.add(obj); } return returnList; } }
customLookupResults.cmp <aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global"> <aura:attribute name="oRecord" type="sObject" /> <aura:attribute name="IconName" type="string"/> <!--Register the component level event--> <aura:registerEvent name="oSelectedRecordEvent" type="c:selectedsObjectRecordEvent"/> <li role="presentation" class="slds-listbox__item" onclick="{!c.selectRecord}"> <span id="listbox-option-unique-id-01" class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option"> <span class="slds-media__figure"> <span class="slds-icon_container" title="Description of icon when needed"> <lightning:icon iconName="{!v.IconName}" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/> <span class="slds-assistive-text">Description of icon</span> </span> </span> <span class="slds-media__body"> <span class="slds-listbox__option-text slds-listbox__option-text_entity">{!v.oRecord.Name}</span> </span> </span> </li> </aura:component>
customLookupResultsController.js ({ selectRecord : function(component, event, helper){ // get the selected record from list var getSelectRecord = component.get("v.oRecord"); // call the event var compEvent = component.getEvent("oSelectedRecordEvent"); // set the Selected sObject Record to the event attribute. compEvent.setParams({"recordByEvent" : getSelectRecord }); // fire the event compEvent.fire(); }, })
selectedsObjectRecordEvent.evt <aura:event type="COMPONENT" description="by this event we are pass the selected sObject(lookup list record) in the parent component"> <aura:attribute name="recordByEvent" type="sObject"/> </aura:event>
- Salesforce Development 45
- March 05, 2020
- Like
- 0