Friday, 23 February 2024

Spinner in lightning component salesforce

 

Spinners are CSS loading indicators that should be shown when retrieving data or performing any action which take time. lightning:spinner displays an animated spinner image to indicate that a request is loading.

What is aura:waiting and aura:doneWaiting?

aura:waiting : This event is automatically fired when a server side apex action is added using $A.enqueueAction(). This event is always fired before aura:doneWaiting. It is handled by a client-side (javaScript)controller. One component can have only one tag to handle this event.

  1. This event indicates that the app is waiting for the response to a server request.
  2. This event is fired before aura:doneWaiting.
  3. This event is automatically fired when a server-side action is added using $A.enqueueAction().
  4. The aura:waiting event is handled by a client-side controller.
  5. A component can have only one <aura:handler> tag to handle this event.

aura:doneWaiting : This event is automatically fired when all server response(apex)  complete. aura:doneWaiting indicate that the lightning component is done waiting for server response. This event is always fired after aura:waiting. It is handled by a client-side (javaScript)controller. One component can have only one tag to handle this event.

  1. This event indicates that the app is done waiting for the response to a server request.
  2. This event is fired after aura:waiting.
  3. This event is automatically fired if no more response from the server is expected.
  4. This event is also handled by a client-side controller.



Lightning Loading Spinner Example :

<aura:component controller="AccountController">
    <!--Aura handler with waiting and donewaiting events declare-->
<aura:handler event="aura:waiting" action="{!c.showSpinner}"/>
    <aura:handler event="aura:doneWaiting" action="{!c.hideSpinner}"/>
     
   
     
    <!--loading spinner start-->
    <div class="exampleHolder">
        <lightning:spinner aura:id="mySpinner" class="slds-hide"/>
    </div>
    <!-- Loading spinner end-->     
     
    <!-- Rest of the code goes here -->
   
</aura:component>

lightning spinner javascript controller

({
        
    // This function automatic called by aura:waiting event 
    showSpinner: function(component, event, helper) {
        // remove slds-hide class from mySpinner
        $A.util.removeClass(component.find("mySpinner"), "slds-hide");
    },
     
    // This function automatic called by aura:doneWaiting event
    hideSpinner : function(component,event,helper){
        // add slds-hide class to mySpinner   
        $A.util.addClass(component.find("mySpinner"), "slds-hide");
    }
})



Thursday, 3 August 2023

Lookup component in Salesforce Lightning

 Lookup component in Salesforce Lightning




Following source code is for Contact Lookup component.

<aura:component controller="ContactLookupController" >
   
    <aura:attribute name="listOfSearchRecords" type="object[]" description="Use,for store the list of search records which returns from apex class"/>
    <aura:attribute name="SearchKeyWord" type="string"/>
    <aura:attribute name="Message" type="String" default="Search Result.."/>
    <aura:attribute name="selectedRecordName" type="string"/>
    <aura:attribute name="selectedRecordId" type="string"/>
  
    <aura:handler event="aura:waiting" action="{!c.showSpinner}"/>
    <aura:handler event="aura:doneWaiting" action="{!c.hideSpinner}"/>
    
  
    <div class="">
        <div aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single">
            <!--<label class="slds-form-element__label" for="lookup-348"> Account Name </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">
                    <lightning:icon aura:id="SearchID" class="slds-input__icon slds-show" iconName="utility:search" size="x-small" alternativeText="icon" />               
                    <!-- This markup is for when an record is selected -->
                    <div aura:id="lookup-pill" class="slds-pill-container slds-hide">
                        <span class="slds-pill">
                            <span class="slds-pill__label">
                                {!v.selectedRecordName}
                            </span>
                            <button class="slds-button slds-button--icon slds-pill__remove" onclick="{!c.clear}">
                                <lightning:icon aura:id="RemoveID" class="slds-input__icon CloseIcn" iconName="utility:close" size="x-small" alternativeText="icon" />
                                <span class="slds-assistive-text">Remove</span>
                            </button>
                        </span>
                    </div>
                    <div aura:id="lookupField" class="slds-show">
                        <ui:inputText  updateOn="keyup" keyup="{!c.keyPressController}" class="slds-lookup__search-input slds-input " value="{!v.SearchKeyWord}" placeholder="search.."/>
                    </div>   
                </div>
            </div>
            <!--This part is for Display typehead lookup result List-->  
            <div class="slds-lookup__menu slds" id="lookup-348">
                <div class="slds-lookup__item--label slds-text-body--small">{!v.Message}</div>
                <center> <ui:spinner aura:id="spinner"/> </center>
                <ul class="slds-lookup__list" role="listbox">
                    <aura:iteration items="{!v.listOfSearchRecords}" var="singleRec">
                        <li role="presentation">
                            <span class="slds-lookup__item-action slds-media slds-media--center" id="lookup-option-350" role="option">
                                <div class="slds-media__body">
                                    <div class="slds-input-has-icon slds-input-has-icon--right">
                                        <!--Icon of Account -->
                                        <div class="slds-lookup__result-text" title="{!singleRec.Name}" >
                                            <a data-record="{!singleRec.Id+'#'+singleRec.Name}" onclick="{!c.selectAccount}">
                                                {!singleRec.Name}                                       
                                            </a>
                                        </div>
                                    </div>
                                </div>    
                            </span>
                        </li>                        
                    </aura:iteration>
                </ul>
            </div>
        </div>
    </div>
</aura:component>


Following source code is for ContactLookupController.js component.

({
    
    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 );
        
        $A.util.removeClass(component.find("SearchID"),'slds-hide')
        $A.util.addClass(component.find("SearchID"),'slds-show')
        
        $A.util.addClass(component.find("RemoveID"),'slds-hide')
        $A.util.removeClass(component.find("RemoveID"),'slds-show')
        
    },
        
    // automatically call when the component is done waiting for a response to a server request.  
    hideSpinner : function (component, event, helper) {
        var spinner = component.find('spinner');
        var evt = spinner.get("e.toggle");
        evt.setParams({ isVisible : false });
        evt.fire();    
    },
    // automatically call when the component is waiting for a response to a server request.
    showSpinner : function (component, event, helper) {
        var spinner = component.find('spinner');
        var evt = spinner.get("e.toggle");
        evt.setParams({ isVisible : true });
        evt.fire();    
    },
    
    selectAccount : function(component, event, helper){       
        var selectedItem = event.currentTarget;
        var data = selectedItem.dataset.record;
        
        var arr = data.split('#');
        console.log('Id='+arr[0]);
        console.log('Name='+arr[1]);
        
        component.set("v.selectedRecordId" , arr[0]);
        component.set("v.selectedRecordName" , arr[1]);         
        
        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'); 
        
        $A.util.addClass(component.find("SearchID"),'slds-hide')
        $A.util.removeClass(component.find("SearchID"),'slds-show')
        
        $A.util.addClass(component.find("RemoveID"),'slds-show')
        $A.util.removeClass(component.find("RemoveID"),'slds-hide')       
    },
    
})


Following source code is for ContactLookupHelper.js component.

({
    searchHelper : function(component,event,getInputkeyWord) {
        var action = component.get("c.fetchContact");
        action.setParams({
            'searchKeyWord': getInputkeyWord
        }); 
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                console.log('SUCCESS ====');
                var storeResponse = response.getReturnValue();
                 console.log('storeResponse ===='+storeResponse);
                if (storeResponse.length == 0) {
                    component.set("v.Message", 'No Result Found...');
                } else {
                    component.set("v.Message", 'Result...');
                }                
                component.set("v.listOfSearchRecords", storeResponse);
            }
            
        });
        $A.enqueueAction(action);    
    },
})

Following source code is for ContactLookup.css component.

.THIS .slds-pill{width: 100%;
    padding: 8px 10px;
}
.THIS .CloseIcn{
    position: absolute;
    top: 7px;
    right: 0px;
}


Following source code is for ContactLookupController apex class.

public class ContactLookupController {

    @AuraEnabled
    public static List <Contact> fetchContact(String searchKeyWord) {
        system.debug('## searchKeyWord ==>'+searchKeyWord);
        String searchKey = searchKeyWord + '%';
        List <Contact> returnList = new List <Contact> ();
        List <Contact> lstOfContact = [select id, Name from Contact where Name LIKE: searchKey ];
          system.debug('## lstOfContact ==>'+lstOfContact.size());
        for (Contact acc: lstOfContact) {
            returnList.add(acc);
        }
        return returnList;
    }
}