Salesforce1 Lightning

Visualforce vs Lightning

Posted on Updated on

Hi

There are lots of questions in the mind of Salesforce developers regarding Lightning but the question which comes in every Salesforce developer’s mind is, will Lightning replace Visualforce?

You will be able to answer this question after exploring the Lightning Experience and VisualForce.

vfvslightning

Lightning Experience is not finished yet. There is plenty of work for developers to do just  building out the basic Salesforce application. Many things are working great, some things are working well in “Beta”. As it is in “beta” version  there are a number of things we just haven’t gotten to yet.

We are living in a multi device world where users are expecting highly interactive and immersive experiences literally at their fingertips. Companies like Google, Facebook are making user experience highly interactive using isolated components. Online forms now come with immediate error feedback when users enter invalid data. This interactivity is no longer a novelty, it’s the norm.

So what does this mean for us?

The Visualforce framework provides a robust set of tags that are resolved at the server-side and that work alongside standard or custom controllers to make database and other operations simple to implement. This is a page-centric web application model. It’s great for basic functionality, but it’s challenging to deliver the new, more dynamic experience that users expect. Fundamentally, this is because it relies on the server to generate a new page every time you interact with the application.

Lightning components are part of the new Salesforce user interface framework for developing dynamic web applications for desktop and mobile devices. They use JavaScript at the client-side and Apex at the server-side to provide the data and business logic. To deliver a more interactive experience, you need help from JavaScript on the client-side. In this new app-centric model, JavaScript is used to create, modify, transform, and animate the user interface rather than completely replacing it a page at a time. This model is exciting, interactive, and fluid.

Both the page-centric and app-centric models have their own advantages and both are here to stay. Combining the models lets applications deliver the right type of experience for the right use case.

Let’s explore the differences between Lightning and Visualforce.

Visualforce

UI Generation

  • Server-Side

Workflow

  1. User requests a page
  2. The server executes the page’s underlying code and sends the resulting HTML to the browser
  3. The browser displays the HTML
  4. When the user interacts with the page, return to step one.

 Advantages

  1. Tried and true model
  2. Easy to implement for greater productivity
  3. Naturally splits large applications into small, manageable pages
  4. Has built-in metadata integration

 Disadvantages

  1. Limited interactivity (aside from added JavaScript functionality)
  2. Higher latency

 Lightning

 UI Generation

  •  Client-Side

 Workflow

  1. The user requests an application or a component
  2. The application or component bundle is returned to the client
  3. The browser loads the bundle
  4. The JavaScript application generates the UI
  5. When the user interacts with the page, the JavaScript application modifies the user interface as needed (return to previous step)

Advantages

  1. Enables highly interactive and immersive user experiences
  2. Aligns with Salesforce user interface strategy
  3. Built on metadata from the foundation, providing an integrated developer experience
  4. The Developer Console supports Lightning components, so there’s an integrated developer experience

Disadvantages

  1. Higher learning curve compared to Visualforce
  2. Higher complexity than Visualforce—you’re building an application, not a page
  3. Since Lightning components are new, there are still some features that aren’t supported
  4. There are a limited number of out-of-the-box components

You have gone through pros and cons of Lightning and Visualforce now you have to decide which tool you should use.

Here are some guidelines to help you decide-which tool you should use and when.

When you should use Lightning

  • If you are developing for Salesforce1 Mobile Application you should use Lightning as visualforce characteristics, especially the page-centric orientation, can be a poor match for mobile apps with limited, high-latency network connections and limited compute resources. Lightning components, by contrast, was designed specifically to handle this context.
  • If you are building an interactive experience with JavaScript to meet user experience requirements you should use Lightning.
  • If you are enabling non-developers to build apps by assembling standard or custom components you should use Lightning App Builder and Lightning components for custom components. Use Visualforce if the required components aren’t yet available.
  • If you are adding user interface element for example, say you want to add a tab to a record home. This task is a simple drag-and-drop in Lightning App Builder.
  • If you are building a Community for Customers you should use Community Builder to create a Lightning-based community site leveraging Lightning components.
  • If you are committed to invest in latest technology you should start using Lightning Components.
  • If you are starting a brand new project you should use Lightning Components. If you’re not familiar with them, there’s no better time than now to learn!

Continue using Visualforce

  • If you are building a page-centric experience with limited Client-Side logic use Visualforce.
  • If you are committed to Javascript Framework such as AngularJS or React continue using Visualforce.
  • If you are building an interactive experience with Javascript and you need third party Framework you should use Visualforce as a container for third party Framework.
  • If you are building a community for partners continue using Visualforce in Salesforce Classic. Explore using Lightning components with Lightning components for Visualforce.
  • If you are exposing a Public-Facing Unauthenticated Website continue using Visualforce. Lightning components don’t support an anonymous (unauthenticated) user context yet.
  • If you are rendering pages as PDF in your application use Visualforce. Lightning components don’t support rendering as PDF output yet.
  • If you are adding to an existing project with lots of Visualforce Pages continue to use Visualforce. Consider moving to Lightning components using Lightning components for Visualforce.

Now you are able to decide which tool to use. But, because web applications are taking more advantage of the app-centric model, I will encourage all Salesforce developers to learn at least the basics of Lightning components. You’ll want to use these components in your future development work.

Oauth Salesforce with Lightning Out

Posted on

Hi All,

In this article, I will explain the code which can be used for connecting and getting the records
from different or multiple salesforce organization using Apex and Lightning Out.

To start first you need to authorize URLs which can be accessed from salesforce environment.
Go to Setup > Administration Setup > Security Controls > Remote Site Settings.

Create one CONNECTED APP go to SETUP > BUILD > CREATE > APP > CONNECTED APP > NEW.

Create Custom Setting for Version,Client Id,Client Secret. Go to SETUP > BUILD > DEVELOP > CUSTOM Settings.

After completing all the steps let’s start coding.

CallBackURLController.apxc :

public with sharing class CallBackURLController{

    @AuraEnabled
    public Static List<Contact> getContacts(String Accesscode){
    
        version__c vrsn = [select name, ClientId__c, ClientSecret__c from version__c limit 1];
        Accesscode = Accesscode.replace('=','%3D').trim();
        String redireUri = 'https://skdomain-dev-ed--c.ap2.visual.force.com/apex/callbackurl';
        String loginUri = 'https://login.salesforce.com';
        String header = '';
        String endpoint = '';
                
        String reqbody = 'grant_type=authorization_code' + '&client_id=' + vrsn.ClientId__c +
            '&client_secret=' + vrsn.ClientSecret__c + '&code=' + Accesscode + '&redirect_uri=' + redireUri;
        
        endpoint = loginUri + '/services/oauth2/token?' + reqbody;
        
        Map<String, object> mapReqBody = CallBackURLController.getHTTPResponse(endpoint, header, 'POST');
        
        header = string.valueOf(mapReqBody.get('token_type')) + ' ' + string.valueOf(mapReqBody.get('access_token'));
        endpoint = loginUri + '/services/oauth2/userinfo';
        
        ///// User Info       
        Map<String, object> mapReqInfoBody = CallBackURLController.getHTTPResponse(endpoint, header, 'POST');
        
        ///// Query Request
        Map<String, object> mapURI = (Map<String, object>) mapReqInfoBody.get('urls');
        
        string queryUri = string.valueOf(mapURI.get('query')).replace('{version}',vrsn.name);
        endpoint = queryUri + '?q=select+id,Name,Phone,Email+from+contact+where+phone+!=null+limit+1000';
       
        Map<String, object> mapReqQryBody = CallBackURLController.getHTTPResponse(endpoint, header, 'GET');
        string strCons = JSON.serialize(mapReqQryBody.get('records'));
        list<contact> lstCon = (list<contact>) JSON.deserialize(strCons, List<contact>.class);
        return lstCon;
    }
    
    public static Map<String, object> getHTTPResponse(String endpoint, String header, String method){
        HttpRequest req = new HttpRequest();  
        req.setMethod(method);
        req.setEndpoint(endpoint);
        if(header != ''){
            req.setHeader('Content-Type', 'application/json');
            req.setHeader('Authorization', header);
        }
        Http httpReq = new Http();  
        HTTPResponse res = httpReq.send(req);
        return (Map<String, object>)JSON.deserializeUntyped(res.getBody());
    }
    
}

This class is making a callout to other Salesforce Org and fetching Contacts of that Salesforce Org.

LightningOutApp.app :

<aura:application access="GLOBAL" extends="ltng:outApp">
    <aura:dependency resource="c:LightningOutCmp" />
</aura:application>

LightningOutCmp.cmp :

<aura:component controller="CallBackURLController" implements="force:appHostable">
    <aura:attribute name="code" type="String" default=""/>
    <aura:attribute name="contacts" type="Contact[]" />
    <aura:if isTrue="{!v.code==''}">
    	<ui:button label="login into Other Org" press="{!c.redirect}"/>
        <aura:set attribute="else">
        	<ui:button label="Get Contacts" press="{!c.getCons}"/>
        </aura:set>
  	</aura:if> 
    
    <div id="tblDiv" style="display:none">
        <table>
            <tr>
                <th>Name</th>
                <th>Phone</th>
                <th>Email</th>
            </tr>
            <aura:iteration items="{!v.contacts}" var="con">
               <tr>
                   <td>{!con.Name}</td>
                   <td>{!con.Phone}</td>
                   <td>{!con.Email}</td>
                </tr>
            </aura:iteration>        
        </table>
    </div>
</aura:component>

This component will be used in Visualforce Page.

LightningOutCmpController.js :

({
	redirect : function(component, event, helper) {
        window.location.href = 'https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=[YOUR CLIENT ID]&redirect_uri=[REDIRECT URL]&prompt=login&display=popup';        
    },
    getCons : function(component, event, helper) {
        document.getElementById("tblDiv").style.display = "block";
        var code = component.get("v.code");        
    	helper.getContacts(component, code);
    },
}

Redirect() function will redirct to the login page for Salesforce Login. getCons() function will get Contact from logged in Salesforce Org.

LightningOutCmpHelper.js :

({
    getContacts: function(component, code) {        
        var action = component.get("c.getContacts");
        action.setParams({
            "Accesscode": code
        });
        var self = this;
        action.setCallback(this, function(actionResult) {
            component.set("v.contacts", actionResult.getReturnValue());       
        });        
        $A.enqueueAction(action);
    },
})

CallBackUrlPage.page

<apex:page showHeader="false" sidebar="false" standardStylesheets="false">
 <!-- Lightning Resources-->
    <apex:includeScript value="/lightning/lightning.out.js" /> 
    <!-- JavaScript to make Remote Objects calls -->
    <script>
        var code="{!$CurrentPage.parameters.code}";
        
        $Lightning.use("c:LightningOutApp", function() {
            $Lightning.createComponent("c:LightningOutCmp",
                  { "code" : code },
                  "lightningComponent",
                  function(cmp) {
                    // any further setup goes here
            });
        });
    </script>
     
    <!-- Lightning Component -->
    <div id="lightningComponent"/>
</apex:page>

When completed it will look like this.

12204800_921217127916108_1436226568_n 12204574_921217134582774_409109935_n 12207968_921217131249441_1515473630_n 12208016_921217124582775_1057121612_n

 

When you click on “Login into Other Org” it will prompt you to login to salesforce. After logging in it will redirect you to Component Page and when you click on “Get Contacts” button it will fetch records from other Salesforce Org.

 

Lightning Design System with Lightning Component

Posted on Updated on

Hi All,

Salesforce just made a major announcement ahead of Dreamforce by introducing Lightning Design System.With the Design System you can build custom applications with a look and feel that is consistent with Salesforce core features — without reverse engineering your styles.

After browsing the docs I decided to have a try with a SLDS.In this article I am just telling a basic example of SLDS and how you can use it with Lightning Component? If you haven’t looked at the SLDS yet, the best place to start is by getting your Trailhead badge for the Lightning Design System module.

I just updated my previous post with SLDS you can find the orignal post here, you can use Apex class from this post.

img1

Application :

<aura:application controller="bklightning.WClassController">
	<!-- REQUIRED SLDS CSS -->
	<ltng:require styles="/resource/SLDS080/assets/styles/salesforce-lightning-design-system-vf.css"/>
	
	<aura:attribute name="accounts" type="bklightning.WrapperClass"/>
	<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
	
	<!-- REQUIRED SLDS WRAPPER -->
	<div class="slds">
		<!-- Page Header -->
		<div class="slds-page-header">
			<div class="slds-grid">
				<div class="slds-col slds-has-flexi-truncate">
				  <h1 class="slds-text-heading--medium slds-truncate" title="Account Information">Account Information</h1>
				</div>
			</div>
		</div>
		<!-- TABLE - BADGE COMPONENT -->
		<table class="slds-table slds-table--bordered">
		  <thead>
			<tr class="slds-text-heading--label">
			  <th scope="col">
				<span class="slds-truncate">Name</span>
			  </th>
			  <th scope="col">
				<span class="slds-truncate">Contact</span>
			  </th>
			  <th scope="col">
				<span class="slds-truncate">Active</span>
			  </th>
			</tr>
		  </thead>
		  <tbody>
			<aura:iteration items="{!v.accounts}" var="account">
				<tr class="slds-hint-parent">
				  <td data-label="activity">
					<span class="slds-truncate">{!account.acc.Name}</span>
				  </td>
				  <td data-label="stage">
					<span class="slds-truncate">{!account.count}</span>
				  </td>
				  <td data-label="confidence">
					<span class="slds-truncate">{!account.acc.bklightning__Active__c}</span>
				  </td>
				</tr>
			</aura:iteration>
		  </tbody>
		</table><!-- TABLE - BADGE COMPONENT -->
		
	</div><!-- REQUIRED SLDS WRAPPER -->
	
</aura:application>

The markup is wrapped in a div with the class ‘slds’ as the LDS is namespaced – so any styles that I use need to be inside an ancestor with this class or they will revert back to very ordinary looking HTML.Lightning Design System works like Bootstrap.The only draw back of LDS is it only provides you CSS(Designs) not functionality.Means if you want to fire an event onclick of button you have to write JAVACRIPT/JQUERY/CSS or use external jquery/css.

So That’s It.

Stock Market Updates Lightning Component

Posted on Updated on

Hi All,

In this article, I will be showing you how to build a stock quote Lightning Component with HighChartTable chart and Yahoo’s YQL(Yahoo Query Language) web service.You can use this component to see Stock Market Updates of any Company and of any StockExchange provided by Yahoo API.Sometimes this API may not work like other APIs but do not worry it will start working.

YQL is like SOQL language that allows you to query, filter and combine data from multiple sources across both the Yahoo! network and other open data sources.Yahoo made things easy on us by providing a very intuitive console for accessing data via the API.You can read complete documentation about YQL.HighChartTable charts are used to represent your data as Charts and Graphs.HighChartTable chart can not be used for commercial purpose.

Screenshot_2015-08-12-19-40-00 Screenshot_2015-08-12-19-39-39

Send me an email on balkishan.kachawa@gmail.com for StockUpdates component package.

Installation Instructions

Follow the steps below to install the Stock Update component and create the application in your own Developer Org.

Step 1: Install the Component

  1. Enable Lightning Components in your new Developer Org:
    In Setup, click Develop > Lightning Components, check the Enable Lightning Components checkbox, and click Save.

Step 2: Enter Sample Data

  1. Click the StockSymbols tab and enter your favourite Company’s records with their Symbol and Stock Exchange Name.
    For example, enter the following values:

Salesforce :
Company : Salesforce,
Symbol : CRM
StockExchange : NYSE

Apple
Company : Apple,
Symbol : AAPL
StockExchange : NASDAQ

Google
Company : Google,
Symbol : GOOG
StockExchange : NASDAQ

Step 3: Add the StockUpdates Component to the Salesforce1 Menu

  1. In Setup, select Administer > Mobile Administration > Mobile Navigation
  2. Select StockUpdates in the Available list
  3. Click the Add button to add the StockUpdates tab to the Selected list
  4. Click the Up button to move the StockUpdates tab closer to the top of the menu and Click Save

Step 4: Test the Component in the Salesforce1 Application

  1. In Salesforce, remove the part of the URL that comes immediately after salesforce.com and append /one/one.app to the URL immediately after salesforce.com
  2. This starts the Salesforce1 Application simulator
  3. Click the menu button in the upper left corner
  4. Select Stock Updates in the menu
  5. Select any company from drop down list

Final result will look like this :

So That’s It Simple 🙂

Share Content on WhatsApp Using Lightning

Posted on Updated on

Hi All,

Whats-app is one of the most popular messaging apps in the world.One third of world’s population is using Whats-app on their smartphones.That is why I thought to implement a functionality by which user can share content on Whats-app. I implemented this with Salesforce1 Lightning.

I got this idea from here.
If you need complete code you can send me an email on balkishan.kachawa@gmail.com

In this demo I am showing you user’s feeds with WhatsApp Share button. When you click on this button it will ask you to share your specific feed with any contact in your mobile device. When complete it will look like this:
IMG-20150702-WA0002

Here is the complete code let’s walk through it :

FeedItemController.apxc
public class FeedItemController{
    @AuraEnabled
    public static List&lt;FeedItem&gt; getFeedItems(){
        return [SELECT Body FROM FeedItem WHERE InsertedById =: UserInfo.getUserId() ORDER BY CreatedDate DESC LIMIT 10 ];
    }
}

In this controller I have created a method getFeedItems() to return feeds of current logged in user.

WhatsAppLightningComponent.cmp
<aura:component controller="bklightning.FeedItemController" implements="force:appHostable">
	
    <ltng:require styles="/resource/whatsappfiles/whatsappfiles/bootstrap,
				/resource/whatsappfiles/whatsappfiles/whatsappbutton.css"
                  scripts="/resource/whatsappfiles/whatsappfiles/jquerymin.js" 
                  afterScriptsLoaded="{!c.afterLoaded}"></ltng:require>
    
    <aura:attribute name="feeds" type="FeedItem[]" />
    
    <div class="page-header page-header-anchor">
    	<h1>Share Your Feeds</h1>
    </div>
    <div id="msg" style="display:none;color:red">
    	Please share this article in mobile device
    </div>   
    <aura:iteration items="{!v.feeds}" var="feed">
        <div class="card">
          	<div class="card-heading">
            	{!feed.Body}
          	</div>
          	<div class="card-detail">
            	<a data-text="{!feed.Body}" class="whatsapp w3_whatsapp_btn w3_whatsapp_btn_large">Share</a>
        	</div>
        </div>
    </aura:iteration>
</aura:component>

Resources for this Lightning Component could be found here jQuery , Bootstrap.

WhatsAppLightningComponentHelper.js
({
	loadFeeds : function(component) {
		var action = component.get("c.getFeedItems");
        action.setCallback(this, function(a) {
            component.set("v.feeds", a.getReturnValue());
        });
        $A.enqueueAction(action);
	},
    
    whatsAppJS : function(component){
        var isMobile = {
            Android: function() {
                return navigator.userAgent.match(/Android/i);
            },
            BlackBerry: function() {
                return navigator.userAgent.match(/BlackBerry/i);
            },
            iOS: function() {
                return navigator.userAgent.match(/iPhone|iPad|iPod/i);
            },
            Opera: function() {
                return navigator.userAgent.match(/Opera Mini/i);
            },
            Windows: function() {
                return navigator.userAgent.match(/IEMobile/i);
            },
            any: function() {
                return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
            }
        };
    	
        jQuery('.whatsapp').click(function(){
            if( isMobile.any() ) {
 				var text = jQuery(this).attr("data-text");
                var message = encodeURIComponent(text);
                var whatsapp_url = "whatsapp://send?text=" + message;
                window.location.href = whatsapp_url;
            } else {
                jQuery('#msg').show();
            }
        })
    }
})

In WhatsAppLightningComponentHelper.js whatsAppJs() method is used to share content on Your WhatsApp.It can support any mobile device but we know that Lightning app is not supporting Android and other devices so it will not work for them.
I did not change code because I hope Lightning will support other Mobile Devices in future.

Please change Namespace to your Namespace before running this code.

Thanks 🙂

Leaflet.js,Map with Custom Images and Lightning Component

Posted on Updated on

Hi All,

In this post I am sharing with you a Lightning Map Component built with Leaflet.
Leaflet is an open source javascript library which you can find here.

pic1  pic2

Requirements :
1) Download latest version of Leaflet here.
2) “bklightning” namespace to “YourNamespace”.

Here is complete code let’s walk through it:

LightningMapComponent.cmp
<aura:component implements="force:appHostable">
	<ltng:require styles="/resource/leaflet/leaflet/leaflet.css" 
                  scripts="/resource/leaflet/leaflet/leaflet.js"
                  afterScriptsLoaded="{!c.afterJsLoaded}"/>
    
    <div id="map" style="width:100%; height: 100%"></div>
    
</aura:component>

In LightningMapComponent.cmp you can see I have used latest version of Leaflet Library. When all scripts loaded I am calling afterJsLoaded() function of LightningMapComponentController.js.

LightningMapComponentController.js
({
	afterJsLoaded : function(component, event, helper) {
        var map = L.map('map').setView([26.46, 74.64], 13);
        
        L.tileLayer('https://a.tiles.mapbox.com/v4/{YOUR MAP ID}/{z}/{x}/{y}.png?access_token=[YOUR ACCESS TOKEN]', {
            attribution: 'Balkishan @kachawaa'
        }).addTo(map);
        
        var LeafIcon = L.Icon.extend({
            options: {
                shadowUrl: '/resource/leaflet/leaflet/leaf-shadow.png',
                iconSize:     [38, 95],
                shadowSize:   [50, 64],
                iconAnchor:   [22, 94],
                shadowAnchor: [4, 62],
                popupAnchor:  [-3, -76]
            }
        });
        
        var greenIcon = new LeafIcon({iconUrl: '/resource/leaflet/leaflet/leaf-green.png'}),
            redIcon = new LeafIcon({iconUrl: '/resource/leaflet/leaflet/leaf-red.png'}),
            orangeIcon = new LeafIcon({iconUrl: '/resource/leaflet/leaflet/leaf-orange.png'});
        
        L.marker([26.46,74.64], {icon: greenIcon}).bindPopup("Ajmer Junction,Ajmer").addTo(map);
        L.marker([26.456221, 74.628175], {icon: redIcon}).bindPopup("Ajmer Sharif,Ajmer").addTo(map);
        L.marker([26.441522, 74.616850], {icon: orangeIcon}).bindPopup("Prithviraj Smarak,Ajmer").addTo(map);
    }
})

To use this Map Library you have to first register for your MAP ID and ACCESS TOKEN here.

LightningMap.app
<aura:application >
	<bklightning:LightningMapComponent />
</aura:application>

So that’s it.

WrapperClass in Lightning

Posted on Updated on

Hi All,

In my series of Salesforce1 Lightning posts today you will know, how to use Wrapper Class in Lightning?
There is a little difference when using Wrapper Class in Salesforce.com and Lightning.

When complete it will look like this :

pic1

Change “bklightning” namespace to “YourNamespace”.

If you need complete code you can download from github.

Let’s walk through code:

WClassController.apxc
public class WClassController{
    
    @AuraEnabled
    public static List<WrapperClass> getAccounts() {
        List<WrapperClass> wcList = new List<WrapperClass>();
        List<Account> accList = [SELECT Name,Active__c, (SELECT Name FROM contacts) FROM Account];
        
        if(accList.size() > 0){
            for(Account acct : accList){
                if(acct.contacts.size() > 0){
                    WrapperClass wc = new WrapperClass();
                    wc.count = acct.contacts.size();
                    wc.acc = acct;
                    wcList.add(wc);
                }
            }
        }
        
        return wcList;
    }
    
}

First off all you will notice that each method has an @AuraEnabled keyword.
Any method that you want to be visible to the Aura view components will need this keyword.

In WClassController.apxc controller getAccounts() method contains a WrapperClass List but you can not see WrapperClass in WClassController.apxc class.
Actually I have created a separate class for WrapperClass with the name WrapperClass.apxc.
Why I did so?
1)Because Apex Controller/Class Types cannot be marked as AuraEnabled.
2)If you create an inner class you can not access this class in Lightning components.
3)If you want to access members of Apex Controller through Object you need to marked them with @AuraEnabled keyword.

There is no difference when accessing the members of WrapperClass.

WrapperClass.apxc
public class WrapperClass{
    @AuraEnabled
    public Integer count;
    
    @AuraEnabled
    public Account acc;
    
}

In WrapperClass.apxc class you can see that I have marked each member of this class with @AuraEnabled keyword.
If you do not mark them @AuraEnabled,you will not be able to access them in Lightning Component.

WrapperClassComponent.cmp
<aura:component controller="bklightning.WClassController">
	<aura:attribute name="accounts" type="bklightning.WrapperClass[]"/>
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
    <div>
        <table class="table table-bordered">
            <thead>
            	<tr>
                	<th><b>Name</b></th>
                    <th><b>Contact</b></th>
                    <th><b>Active</b></th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.accounts}" var="account">
                    <tr>
                        <td>{!account.acc.Name}</td>
                        <td>{!account.count}</td>
                        <td>{!account.acc.bklightning__Active__c}</td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>
    </div>
</aura:component>

In WrapperClassComponent.cmp component you can see I have used WrapperClass.apxc as “aura:attribute” Type.
To access an array/list of wrapper class you define “aura:attribute” Type like type=”bklightning.WrapperClass[]”.

So that’s it.Hope it will help you.

e-Signature App Using Lightning

Posted on Updated on

Hi All,
In my previous post I have shown you how we can convert currency of any country using lightning.
Today I will tell you how we can use HTML5 canvas to draw your signature and how we can attach this signature with your information in Salesforce lightning.

When complete it will look like this :

first

When you click on submit it will show you detail with your signature like this :

second

Changes :
1) Change “bklightning” namespace to “YourNamespace”.
2) Need to update browser as I am using HTML5, this App will work with Latest Version Browser.

If you need complete code you can drop me an email on this email id : balkishan.kachawa@gmail.com

Let’s walk through code:

ContactSignatureController.apxc
public with sharing class ContactSignatureController{
    
    @AuraEnabled
    public static void saveContact(ContactDetail__c con,String url) {
        String imgUrl = url.subStringAfter('base64,');
        
        insert con;
        
        Attachment attach = new Attachment();
        attach.contentType = 'image/png';
        attach.name = con.Firstname__c+' '+con.Lastname__c;
        attach.parentId = con.Id;
        attach.body = EncodingUtil.base64Decode(imgUrl);
        insert attach;
        
    }
    
    @AuraEnabled
    public static Attachment getAttachment(){
        return [Select Id,Name from Attachment order by CreatedDate DESC LIMIT 1];
    }
}

First off all you will notice that each method has an @AuraEnabled keyword.
Any method that you want to be visible to the Aura view components will need this keyword.

In ContactSignatureController.apxc controller saveContact() method is doing all work.
When you click on “Submit” button this method will be called.As you can see this method accepts two parameters:
First parameter is an object of ContactDetail which will have Contact Information.
Second parameter is an Encoded URL of image which we had drawn on canvas.We are using EncodingUtil.base64Decode() method to Decode URL.

ESignatureComponent.cmp
<aura:component controller="bklightning.ContactSignatureController" implements="force:appHostable">
    <aura:attribute name="att" type="Attachment"/>
    <aura:attribute name="newContact" type="bklightning.ContactDetail__c"
                                        default="{ 'sobjectType': 'bklightning__ContactDetail__c'}"/>
	
    <form>
    	<div class="form-group">
        	<label for="fname">First Name*</label>
          	<input type="text" class="form-control" id="fname" value="{!v.newContact.bklightning__Firstname__c}" autofocus="autofocus" onblur="{!c.doInit}" placeholder="First Name"/>
      	</div>
      	<div class="form-group">
        	<label for="lname">Last Name*</label>
          	<input type="text" class="form-control" id="lname" value="{!v.newContact.bklightning__Lastname__c}" placeholder="Last Name"/>
      	</div>
      	<div class="form-group">
        	<label for="phone">Phone*</label>
          	<input type="phone" class="form-control" id="phone" value="{!v.newContact.bklightning__Phone__c}" placeholder="Phone Number"/>
            <div id="pmsg" style="color:red"></div>
      	</div>
      	<div class="form-group">
        	<label for="signature">Your Signature*</label><br/>
          	<canvas id="signature" width="200" height="100" style="border:2px solid black"></canvas>
        </div>
        <div id="msg" style="color:red"></div>
      	<button type="button" class="btn btn-default" onclick="{!c.createContact}">Submit</button>&nbsp;&nbsp;
        <button type="button" class="btn btn-default" onclick="{!c.clearCanvas}">Clear Canvas</button>
    </form>    
    <div class="showDetail" style="display:none;">
        <b>Name &nbsp;&nbsp; : &nbsp;&nbsp;{!v.att.Name}</b><br/>
        <img src="{!'/servlet/servlet.FileDownload?file='+v.att.Id}"/>
    </div>
    
</aura:component>

In ESignatureComponent.cmp I am using HTML5 Canvas tag to draw signature.

When you click on “Submit” button it will call createContact() of ESignatureComponentController.js it then call saveContact() method of Apex Controller which will save Information and Signature.

So that’s it.

Currency Converter App Using Lightning

Posted on Updated on

The Salesforce Lightning Component Framework is the next-generation component based development framework for Salesforce.It is based on the Aura open source library and uses a mixture of JavaScript on the client and Apex on the Server. In this post I am using lightning to create a simple Currency Converter App.In this post I will not cover basics of lightning.To learn lightning basics you can download lightning pdf from here.

To convert currency i am using a free currency converter  Xignite API.You can also register for your free API here.

You can find complete code on github.

When complete it will look like this :

cc

Changes :
1) Change “bklightning” namespace to “YourNamespace”.
2) Register on Xignite to get you free API KEY.

Let’s walk through code:

CurrencyConverterControllerClass.apxc
public with sharing class CurrencyConverterControllerClass{
    
    @AuraEnabled
    public static List<CurrencyInformation__c> allCountries() {
        return [SELECT Id,Name,Code__c, Country__c FROM CurrencyInformation__c];
    }
    
    @AuraEnabled
    public static String getCurrency(String sourceCode,String targetCode) {
        String url = 'https://globalcurrencies.xignite.com/xGlobalCurrencies.json/GetRealTimeRate?Symbol=';
        url += sourceCode+targetCode+'&_token=YOURTOKEN';
        
        // Instantiate a new http object
        Http http = new Http();
        
        // Instantiate a new HTTP request, specify the method (GET) as well as the endpoint
        HttpRequest req = new HttpRequest();
        req.setEndpoint(url);
        req.setMethod('GET');
        
        HttpResponse res = new HttpResponse();
        
        // Send the request, and return a response
        if((sourceCode != null && sourceCode.trim().length() > 0) && (targetCode != null && targetCode.trim().length() > 0))
            res = http.send(req);
        else
            return null;
        
        Map<String, Object> response = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
        String text = (String)response.get('Text');
                
        return text;
    }
}

First off all you will notice that each method has an @AuraEnabled keyword.Any method that you want to be visible to the Aura view components will need this keyword. getCurrency() method calls out to the Xignite REST API with a GET request containing Source Country ,Target Country Code and API KEY.It will return response in JSON and the response JSON.deserialized into a Map and then into Text message.

CurrencyConverterComponentController.js
({
    doInit : function(component, event, helper) {
        helper.getCountries(component);
    },
    calculateCurrency : function(component, event, helper) {
        var srs = jQuery('#source option:selected').val();
    	var trg = jQuery('#target option:selected').val();
        helper.getResult(component, srs, trg); 	
    },
})

The CurrencyConverterComponentController.js implements the calculateCurrency() function called onclick of “Calculate” button in CurrencyConverterComponent.cmp and it calls the getResult() helper function.

CurrencyConverterComponentHelper.js
({
    getCountries : function(component) {
        var action = component.get("c.allCountries");
        action.setCallback(this, function(a) {
            component.set("v.countries", a.getReturnValue());
        });
        $A.enqueueAction(action);
        
	},
    getResult: function(component, srs, trg) {
        var action = component.get("c.getCurrency");
        action.setParams({
          "sourceCode": srs,
          "targetCode": trg
        });
      	action.setCallback(this, function(a) {
           	component.set("v.message", a.getReturnValue());
        });
        $A.enqueueAction(action);
    }
})

That getResult() helper function is defined in CurrencyConverterComponentHelper.js, and it calls the Apex getCurrency() function that actually does the REST API callout.It then takes the return value from that function, and populates the “message” attribute in the CurrencyConverterComponent.cmp component.

So that’s it. Simple! Coming soon with a new post on lightning.