Skip to main content

Favorite / Follow Lightning Component using Bootstrap in salesforce.com

As you know Lightning uses a java-script based aura framework. It makes it very easy to plugin with any other java-script libraries like React and Bootstrap. Also , you can use popular analytics and map libraries like Leaflet and D2 Charts.

In this example we will create a lightning component which will allow user to follow the records , this is different from salesforce's follow icon , as part of this component we will create a field (Follow) on Account Object , which will be checked if a user follows that record from Salesforce1 mobile app or web. We will use this bootstrap's "glyphicon"  icon.

glyphicon
In this example you can also get familiar with how to use Application events , embed bootstrap and 
JQuery in your lightning component.

We will fetch few accounts from system and use this icon to follow the records. Here is how it will appear in Salesforce1 mobile app.

Favorite or Follow Lightning Component using Bootstrap
Prerequisites :-

1. Download latest jQuery and add in static resource and
2. Download latest Bootstap and add in static resource

Lightning Code :-

Create a custom field "Follow" of type checkbox on Account object. Refer Screenshot below 

a.) FollowAccountApp.app (Create a Lightning Application and extend force:SLDC to include Lightning design system)

<aura:application extends="force:slds">
    <c:Follow/>
</aura:application>
b.) Follow.cmp (Master Component of the application)

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,force:lightningQuickAction"
                controller="FollowController" 
                access="global">
<ltng:require scripts="/resource/Scripts/js/jquery/jquery-2.2.4.min.js,
                           /resource/Scripts/util/js/bootstrap.min.js"
                  styles="/resource/Scripts/util/css/bootstrap.min.css"  
                  />
    
    <!-- Handle component initialization in a client-side controller -->
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="accounts" type="Account[]" />
    <aura:handler event="c:StarEvt" action="{!c.setStatus}"/>
    <aura:handler event="c:NoStarEvt" action="{!c.setStatus}"/>
    
    <div class="panel panel-default" >
             <aura:if isTrue="{!v.accounts.length > 0}"> 
                    <aura:iteration  var="act" items="{!v.accounts}">
                        <c:AccountTile account="{!act}"/>
                    </aura:iteration>
                </aura:if>
                <aura:if isTrue="{!v.accounts.length == 0}"> 
                    <lightning:layoutItem class="slds-align_absolute-center" flexibility="auto" padding="around-small">   
                    <ui:outputText value="No Accounts found" />
                </lightning:layoutItem>
                </aura:if>       
    </div>
</aura:component>
c.) FollowController.js

({
doInit : function(component, event, helper) {
        // Retrieve Accounts when component gets initialized             
        helper.getAccounts(component);       
},
    setStatus : function (component, event, helper){
        
var act = event.getParam("account");  
        var recordId = act.Id
        var action = component.get("c.followAccount"); 
       
        action.setParams({
      "acctId": recordId
    });
        action.setCallback(this, function(response){
           var state = response.getState();
           if (component.isValid() && state === "SUCCESS") {
              var res = response.getReturnValue(); 
           }                 
        });    
$A.enqueueAction(action);        
        
    },
    
})
d.) FollowHelper.js

({
getAccounts : function(component) {
       
        var action = component.get("c.getFewAccounts");       
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (component.isValid() && state === "SUCCESS") {                
                component.set("v.accounts", response.getReturnValue());                
            }            
        });        
       
$A.enqueueAction(action);
}
})
e.) AccountTile.cmp

<aura:component >
<aura:attribute name="account" type="Account" />
    <div class="panel-heading">{!v.account.Name}</div>
    <div class="panel-body">       
        <aura:if isTrue="{!v.account.Follow__c}">        
        <!-- content renders if true --> 
          <c:NoStar account="{!v.account}"/>
        <aura:set attribute="else">          
          <!-- content renders if false -->
            <c:Star account="{!v.account}"/>      
        </aura:set>
      </aura:if> 
    </div>   
</aura:component>
f.) FollowController.cls (Component Controller class)

public class FollowController {
@AuraEnabled
    public static List<Account> getFewAccounts(){       
        return [SELECT Id, Name, Follow__c
                    FROM Account limit 10 ];
    }
    
    @AuraEnabled
    public static Void followAccount(String acctId) {
        if(!String.isBlank(acctId)){
             List<Account> accounts = [Select id , name , Follow__c from Account 
                                                        where id = :acctId ];
            
            Boolean result = (accounts[0].Follow__c) ? false : true ; 
            accounts[0].Follow__c = result ;
            update accounts[0];
        }
    }
}
g.) StarEvt.evt (Application event which will fire one user click on the star icon)

<aura:event type="APPLICATION" description="Event template">
    <aura:attribute name="account" type="Account"/>
</aura:event>
h.) Star.cmp

<aura:component >
<aura:attribute name="account" type="Account" />   
    <div class="class_star" onclick="{!c.setStar}">      
      <span class="glyphicon glyphicon-star-empty" ></span>           
    </div>
</aura:component>
i.) StarController.js

({
setStar : function(component, event, helper) {
       
        var target = jQuery(event.target);
        if(target.hasClass("glyphicon")){
            target.toggleClass("glyphicon-star-empty").toggleClass("glyphicon-star");
        } else if(target.hasClass("class_star")){
            target.find(".glyphicon").toggleClass("glyphicon-star-empty").toggleClass("glyphicon-star");
        }
       
        var act = component.get("v.account");
        var evt = $A.get("e.c:StarEvt");       
        evt.setParams({"account": act});
        evt.fire();
       
    },
})
j.) NoStarEvt.evt (Application event which will fire one user click on the star icon)

<aura:event type="APPLICATION" description="Event template">
    <aura:attribute name="account" type="Account"/>
</aura:event>
k.) NoStar.cmp

<aura:component >
<aura:attribute name="account" type="Account" />
    <div class="class_star" onclick="{!c.setNoStar}">
      <span class="glyphicon glyphicon-star" ></span>
    </div> 
</aura:component>
l.) NoStarController.js

({
setNoStar : function(component, event, helper) {      
        var target =  jQuery(event.target);
       
        if(target.hasClass("glyphicon")){
            target.toggleClass("glyphicon-star-empty").toggleClass("glyphicon-star");
        } else if(target.hasClass("class_star")){
            target.find(".glyphicon").toggleClass("glyphicon-star-empty").toggleClass("glyphicon-star");
        }
        
        var act = component.get("v.account");
        var evt = $A.get("e.c:NoStarEvt");
        evt.setParams({"account": act});
        evt.fire();
       
    },
})

Comments

Popular posts from this blog

Einstein Bot user authentication

Using Bot for data manipulation use case in your company requires need of implementing some extra security layer to make it spoof proof. One of exciting salesforce feature we have is the well known Einstein Bot which many companies have implemented. I am going to cover detail step-by-step implementation of User validation use case using encrypted token. STEP-1: Create a Site & Site User go to setup > Sites & Domains > Sites Create a Site and make your user as "Site Contact". This is a prerequisites for live agent or Embedded Service setup. STEP-2 : Create a Embedded Service(formerly snap-ins) go to Service setup > Embedded Service Create a new Embedded Service Deployment record and copy the embedded service code snipped generated in a notepad. STEP-3  : Create a Visualforce page to test the chatbot (it will simulate the actual web portal which is going to consume the embedded service snipped.) BotController.apxc public class BotControlle...

Dynamically populate lightning:combobox

In order to dynamically populate values in lightning:combobox using javascript we can create a list variable and push the values. We also require the values like ids associated to the particular option for back-end logic. For example  : If we want to show the list of contacts using lightning:combobox component where the option should display the contact name but the value should be the contact id which will be used for back-end logic For this we can create a temporary Map variable in our lightning component and set the value and label parameters of the lightning:combobox. Here is the code for this component Combo.app <aura:application extends="force:slds" access="global" description="Lightning Combo Demo"> <c:Combo_Cmpt/> </aura:application> Combo_Cmpt.cmp <aura:component implements="flexipage:availableForAllPageTypes" access="global" controller="ComboController"> <!-- ...

Use of wrapper class in lightning:datatable

As you guys know the wrapper class concept in visualforce pages , we generally use it to create a data-table which fetches data from different objects or if we want to redirect user to some other page on click of a link as one of the column of data-table.        For example we want a column "Account Name" on the data-table which is a link and once user clicks it should redirect respective account record. Or , suppose we want to display a column with some images or icons as a visual indicator Or what not. These requirements require us to use a wrapper on the lighting data-table (lightning:datatable) I am going to use my previous account search example ( Account Search Lightning Component ) and explain the use of wrapper. AccountSearchWrapper.app <aura:application extends="force:slds" access="global" >     <c:AccountSearchWrapper /> </aura:application> AccountSearchWrapper.cmp <aura:component controller="...