Tuesday, July 17, 2018

Salesforce Lightning Tutorial - Part 1 | Fetch and display data from server



This is the first post in the Lightning Tutorial Series. In this post, you'll learn how you can you fetch data from an apex controller and display it in the lightning component. Mainly the read operation in CRUD (Create, Read, Update and Delete). If you want to learn about the very basics of lightning like:- what is lightning ? What are the pre requisites ? etc. then you can refer to my previous post Salesforce Lightning Basics.

Now, we are going to code a lightning component that will display all the contacts related to an account and then we'll replace it with the standard related list of contacts under the account detail page in lightning.

1. Create an Apex Controller

// Apex Controller for Contact List Lightning Component
public class ContactListController {
        
    @AuraEnabled
    public static List<Contact> getContactList(List<Id> accountIds) {
        // Getting the list of contacts from where Id is in accountIds
                List<Contact> contactList = [SELECT Id, Name, Email, Phone, AccountId FROM Contact WHERE AccountId in :accountIds];
                // Returning the contact list
        return contactList;
    }
}
As you can see in the above code that I have created a very simple apex controller which takes a single argument i.e. a list of account ids and return a list of contacts related to all the accounts whose ids are passed as a parameter. The above method is static as the non- static @AuraEnabled methods cannot have parameters. The @AuraEnabled annotation is used to specify that this method will be called from lightning component.

2. Create a Lightning Component

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" controller="ContactListController" access="global" >
    <!-- Handler to call function when page is loaded initially -->
    <aura:handler name="init" action="{!c.getContactsList}" value="{!this}" />
    <!-- List of contacts stored in attribute -->
    <aura:attribute name="contactList" type="List" />
    <!-- Lightning card to show contacts -->
        <lightning:card title="Contacts">
        <!-- Body of lightning card starts here -->
        <p class="slds-p-horizontal_small">
            <!-- Aura iteration to iterate list, similar to apex:repeat -->
            <aura:iteration items="{!v.contactList}" var="contact">
                <!-- recordViewForm to view the record -->
                <lightning:recordViewForm recordId="{!contact.Id}" objectApiName="Contact">
                    <div class="slds-box slds-theme_default">
                        <!-- outputfield used to output the record field data inside recordViewForm -->
                        <lightning:outputField fieldName="Name" />
                        <lightning:outputField fieldName="Email" />
                        <lightning:outputField fieldName="Phone" />
                    </div>
                </lightning:recordViewForm>
                <!-- Line break between two records -->
                <br />
            </aura:iteration>
        </p>
        <!-- Lightning card actions -->
        <aura:set attribute="actions">
            <!-- New button added -->
            <lightning:button label="New" onclick="{!c.newContact}" />
        </aura:set>
    </lightning:card>
</aura:component>
If you remember, I have told in my previous post that Lightning Component tags are like html tags. In the above code, the lightning component implements flexipage:availableForRecordHome ( as we have to embed our component in a standard record detail page ) and force:hasRecordId ( this will help the component to get the record Id of the record which is being displayed on the page, here it will be the account id as we are going to embed this component in account detail page ). After this, I have used a aura:handler tag with attribute name - init and value - {!this} this name and value is fixed as we are going to specify a function in action which will be called automatically when the record is loaded initially. In the action, I have written c.getContactsList here c stands for controller but it's not the apex controller, it's the lightning controller in which I have defined the getContactsList function which I am calling on initial loading of the page.

So, till now we have made a lightning component in which getContactsList method is called which will mainly be used to fetch the list of contacts from apex controller we previously created. But wait...where are we going to store this list ? Correct..!! We need an apex attribute to store the list. So, I have used an apex attribute tag which is of type list as I have to store list in this attribute ( remember..we returned a list from apex controller method).

Next steps are pretty simple and straight forward:-

  1. I used a lightning card tag to show my contacts wrapped in a card and gave the title Contacts
  2. Lightning Card body consists of a paragraph tag with an slds class so defined the same. You can have a detailed look at lightning card tag here.
  3. In the body I have to display the contacts list, so I have used aura iteration tag and in the items, I have given {!v.contactList} as I have to iterate through the contactList to show the contacts and each contact is represented using a var which is given the value contact. It is very similar to apex:repeat if you have worked on visualforce pages before.
  4. After that, I have used lightning:recordViewForm tag which is mainly used to display a record. You just have to pass the recordId and the objectApiName as the attributes which I have given as {!contact.Id} and Contact respectively.
  5. In the lightning recordViewForm, I have used lightning:outputField tag in which we just have to pass the field name and I have done so. You can have a detailed look at lightning recordViewForm tag here.
  6. Before closing the lightning card tag, I have used aura:set tag in which I have given the attribute as actions as I am going to add action buttons in this.
  7. Finally, I have added a lightning button with label New and given a controller function in the onclick attribute which will be called when the button is clicked.

3. Creating a Lightning Controller

({
    // Function called on initial page loading to get contact list from server
        getContactsList : function(component, event, helper) {
        // Helper function - fetchContacts called for interaction with server
                helper.fetchContacts(component, event, helper);
        },

    // Function used to create a new Contact
    newContact: function(component, event, helper) {
        // Global event force:createRecord is used
        var createContact = $A.get("e.force:createRecord");
        // Parameters like apiName and defaultValues are set
        createContact.setParams({
            "entityApiName": "Contact",
            "defaultFieldValues": {
                "AccountId": component.get("v.recordId")
            }
        });
        // Event fired and new contact dialog open
        createContact.fire();
    }
})

This is very simple. In lightning controller, we mainly keep the functions that are called from the page. It consists of 3 parameters component, event and helper which are used to interact with the component, event and helper respectively. If you want to pass another parameter, you can add after these. I personally prefer to keep all the client side actions in the controller itself and use helper for the server calls. In the above code, I have created two functions, getContactsList and newContact. If you remember I called the getContactsList from the init handler to fetch the data, so this require a server call. Therefore, I simply called the fetchContacts function from the helper which will be doing everything so we'll discuss it later. For now, let's concentrate on newContact function which will fire an event to create a new contact. In this function, $A is used to reference global event e.force:createRecord. We assigned this event to createContact variable. Then we set the parameters entityApiName as Contact and in the defaultFieldValues I have specified the AccountId only as I want this to be filled by default and I have given recordId in this which is the id of account under which we are creating a contact. Then, we fire the event. Remember the create record dialog which we get when we create a new record...?? This will do exactly the same thing. The global event can run only in one.app container. In other words, new button will work only when our component is embedded somewhere in a detail page ( having one.app - salesforce org url ).

4. Creating a Lightning Helper

({
    // Function to fetch data from server called in initial loading of page
        fetchContacts : function(component, event, helper) {
        // Assign server method to action variable
        var action = component.get("c.getContactList");
        // Getting the account id from page
        var accountId = component.get("v.recordId");
        // Setting parameters for server method
        action.setParams({
            accountIds: accountId
        });
        // Callback function to get the response
        action.setCallback(this, function(response) {
            // Getting the response state
            var state = response.getState();
            // Check if response state is success
            if(state === 'SUCCESS') {
                // Getting the list of contacts from response and storing in js variable
                var contactList = response.getReturnValue();
                // Set the list attribute in component with the value returned by function
                component.set("v.contactList",contactList);
            }
            else {
                // Show an alert if the state is incomplete or error
                alert('Error in getting data');
            }
        });
        // Adding the action variable to the global action queue
        $A.enqueueAction(action);
        }    })
This is the last part of our lightning component in which, we'll hit the apex controller method, pass the account id, fetch all the contacts related to the account and finally push all the contacts in the contactList attribute. A helper method also consists of 3 parameters component, event and helper which are passed from the controller from where it is called. It is not compulsory to pass all 3 but recommended to do so and use a 4th parameter to pass anything else. I have used component.get()function in the first line that takes the apex controller method as a parameter and assigned it to actionvariable. So, I have passed c.getContactList in it where refers to apex controller and getContactList is the method we defined in our apex controller. I have used the same component.get() to get the account id from the page. The only difference is that while referencing the page I have used v instead of c as - v.recordId. I have set the parameters for action which is the parameters my apex controller method is using. In the accountIds of apex controller I have passed accountId which is my javascript variable. action.setCallback will hit the server method with parameters and we have a response in return. The response.getState() is used to check whether our call is successful or not and response.getReturnValue() gives us the list of contacts which were returned from the apex controller method. Finally, I have set the list fetched from apex controller method to my own aura attribute in component which is of type List and then I have added this action to the global action queue by using $A.enqueueAction() and passing the action as parameter in this function. All this functionality is performed during the initial loading of the page.

Congrats..!! you just made your first lightning component. It looks like this:-

And when you click on the new button, you'll have the standard dialog which is as follows:-

Salesforce Lightning Basics:




Salesforce Lightning includes the Lightning Component Framework and some exciting tools for developers. Lightning framework allows you to build responsive applications with a much better user interface that people love to interact with. Lightning components give you a client-server framework that makes development faster and is compatible for both web as well as Salesforce 1 Mobile application. You can read in detail from the official salesforce docs here.

So, In this post I am going to tell you that what are the basics of lightning and then we'll learn how you can make a lightning component that fetch and display data from the server. To work on lightning, it is recommended that you know a little bit of JavaScript but if you don't,  no worries I am going to explain you everything to the best of my knowledge.
A salesforce lightning component mainly consist of 5  most important parts:-

1. Component
2. Controller
3. Helper
4. Apex Controller
5 . Style

While the first three work on the client side, the last one work on the server side. Apart from these Lightning uses Salesforce Lightning Design System (SLDS) which can either be implemented by using ui tags or lightning tags. These tags are similar to the html tags that you have used somewhere before. We will mainly focus on using lightning tags instead of aura ui tags while we learn further because Salesforce recommend using lightning tags as they are optimized for common use cases and it is improving these day by day so that developers start using lightning tags that are optimmized for use by salesforce. You can have a look at the lightning tags in the original doc starting from here. Similarly, for the ui tags, you can have a look at them here.

So, now you have a brief overview that what is salesforce lightning and what are we going to learn in the upcoming posts, so let's have a look at the lightning design system website, the lightning and uitags so that you can get a crisp of all these stuff as we are going to use them from my next post. 

Thanks for reading and follow or subscribe my blog to stay in touch about my latest posts so that you don't miss anything. Let's start development in Salesforce Lightning right now from scratch.

Monday, July 9, 2018


Lightning Components Framework
Salesforce Lightning Architecture
We can use Lightning App builder to build lightning apps for every screen(Responsive design) by drag and drop of Lightning Components and Visualforce pages into a one canvas.
Lightning Components are small reusable applications which are the building blocks to a lightning application and there are three types of components:
  • Standard components - built by Salesforce.com
  • Custom components - built by developers
  • Apex exchange components - built by Salesforce.com partners
In this post we are going to discuss Custom Components.

Custom components

Developers can create their own custom components. So the Administrators can create lightning apps on demand, using these components. A component is a collection of files.

Structure of a Lightning Component

Structure of a Lightning Component
Table Lightning Custom Components

Let’s create a Custom Component

1.Enable my domain in your org

For security purposes, Lightning Components require you to define a custom Salesforce domain name for your organization.

2.Upload Bootstrap as a static resource

  • Download the salesforce.com optimized Bootstrap package.
  • Unzip that package and go to Setup > Build > Develop > Static Resources and click New.
  • Specify bootstrap as the Name, then click the Choose File button, and select the bootstrap.css in the dist/css directory of the unzipped bootstrap folder.
Static resource edit
  • Click Save.

3.Create a Namespace

  • Go to Packages from setup menu.
  • Click Edit.
  • Review the selections and then click Continue.
  • Enter the namespace prefix you want to register (eg: absi_dev).
  • Click Check Availability.
  • Click Review My Selections.
  • Click Save.
  • It’s a best practice to create a Namespace.

4.Create an Apex class as the controller to write SOQL/Logic

  • Open Developer Console, click File > New > Apex Class. Name it as AccountController and click OK.
public with sharing class AccountController {
@AuraEnabled
public static List<Account> findAll() {
return [SELECT id, Name, AccountNumber, Fax,Industry,Type FROM Account LIMIT 10];
}
}
Code for AccountController class
  • Click File > Save to save the file.
  • The @AuraEnabled method annotation makes a method available to Lightning applications.

5. Creating the Lightning Application

  • In the Developer Console, click File > New > Lightning Application. Name it as MyAccounts and click Submit.
  • Click File > Save.
  • After Saving you can see this stack.
Preview

6. Creating a Component to get Data from AccountController

  • In the developer console click File > New > Lightning Component.
  • Name it as accountListComponent.
  • Click Submit.
<aura:component controller="absi_dev.AccountController" implements="flexipage:availableForAllPageTypes" >
<aura:attribute name="accounts" type="Account[]"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<div class="table table-bordered">
<table class="table table-striped">
<thead>
<tr>
<th>Account Name</th>
<th>Account Number</th>
<th>Fax</th>
<th>Industry</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.accounts}" var="account">
<tr>
<td>{!account.Name}</td>
<td>{!account.AccountNumber}</td>
<td>{!account.Fax}</td>
<td>{!account.Industry}</td>
<td>{!account.Type}</td>
</tr>
</aura:iteration>
</tbody>
</table>
</div>
</aura:component>
Code for accountListComponent Component
  • To appear components in lightning pages and the App Builder, a component must implement the flexipage:availableForAllPageTypes interface.
  • In a component, use “v (view)” to access the collection of attributes.

7. Create a Controller for accountListComponent

  • Click Controller from the file list.
Accountlist Component
({
doInit : function(component, event, helper) {
var action = component.get("c.findAll");
action.setCallback(this, function(a) {
component.set("v.accounts", a.getReturnValue());
});
$A.enqueueAction(action);
}
}
})
Code for accountListComponent’s Controller
  • doInit() function helps to load data to the component.
  • component.get("c.findAll") returns an instance of server side action.
  • action.setCallback() this function uses to set the retrieved account objects to components v.accounts attribute.
  • $A.enqueueAction() function adds the action to a queue and action calls are synchronous and run in batches.

8. Add accountListComponent to the Application UI

  • In developer console File > Open Lightning Resources.
  • MyAccounts > Application.
<aura:application >
<link href='/resource/bootstrap/' rel="stylesheet"/>
<div class="container">
<nav role="navigation" class="navbar navbar-inverse">
<div class="navbar-header">
<a href="#" class="navbar-brand">Accounts Details</a>
</div>
<div id="navbarCollapse" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Profile</a></li>
<li><a href="#">Messages</a></li>
</ul>
</div>
</nav>
</div>
<div class="container">
<div class="row">
<div class="col-sm-12">
<absi_dev:accountListComponent/>
</div>
</div>
</div>
</aura:application>
view rawApplication.app hosted with ❤ by GitHub
Code for the lightning application
  • File > Save All.
  • Click Preview or Update Preview.
Account details
Lightning Application

Conclusion

The objective of this blog is to show that how easy to create an attractive and functional component with bootstrap. The only external resource we have to use here is Bootstrap package. By using this kind of technology developers can fastly develop robust mobile and web applications on demand.

Thursday, June 28, 2018

Salesforce Extentions:
1)Salesforce Organizer
2)Salesforce advanced code searcher
3)Salesforce Api fieldnames
4)Salesforce apexclass liks
5)Salesforce Devtools
6)Salesforce DataExporter
7)Salesforce console data exporter
8)Viwizard
9)CRM Sceience - admin Assist
10)SOQL extractor and analyzer for salesforce
11)Record and Metadata Comparator for Salesforce
12)Salesforce.com Sandbox Favicon Extension
13)Salesforce inspector
14)Salesforce Admin Check All
15)Salesforce Navigator
16)Force.com Logins 
GITHUB Access
https://github.com/sfdc3154/venkat9916