• Nagendra Babu Lakkimsetti
  • NEWBIE
  • 0 Points
  • Member since 2022

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 2
    Replies
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!
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>

Hi

I am very new to Lightning Development. I am trying to learning developing Lightning components on my own.
I was trying to develop an Input form for Case Object. Now, I wanted to Attach files feature as well to the form at the very bottom.
Once I upload and save the form, a new Case record should be created with attachments in the record detail page.

I have used this to get the Input for upload a file:
 

<lightning:input type="file" label="Attachment" name="file" multiple="true" aura:id = "upButton" accept="image/png, .zip" onchange="{! c.handleFilesChange }"/>
 

Can someone share a simple code for the controller(handleFilesChange) as well as the Server-side class to save the data to Case object.

Thanks!