Lightning Component, JavaScript Remoting and Visualforce Page

Posted on Updated on

Hi All,

New Winter 16 feature allows Lighting Components to be embedded inside a Visualforce Page.We know Lightning Components are used as building blocks for faster development of mobile and web app. I thought to embed Lightning Component with some of the features of VisualForce Page which are optimized for use on mobile pages and on pages that use third-party JavaScript libraries. It enables dynamic, interactive pages that feel more responsive than traditional Visualforce pages. JavaScript Remoting is one the features which can be used to make mobile pages. This feature of Visualforce can be combine with Lighting Components to make more interactive pages that feel more responsive than traditional Visualforce pages. You can read more about JavaScript Remoting here.

Let’s walk through code

AccountRemoter.apxc :

global with sharing class AccountRemoter {

    public String accountName { get; set; }
    public static List<Account> accountList{ get; set; }
    
    //Remote Function
    @RemoteAction
    global static List<Account> getAccount(String accountName) {
    
        string tempName = '\'%' + accountName + '%\' ';
        String query = 'SELECT Id, Name, Phone, Active__c FROM Account WHERE Name like' + tempName;
        accountList = Database.Query(query);
        
        return accountList;
    }
}

In this class I have created a RemoteAction method which will return list of accounts. @RemoteAtion annotation is used to define a remote action method.

JSRemoteComp.cmp :

<aura:component>
    <!-- Attribute -->
	<aura:attribute name="accounts" type="Account[]"/>
    <!-- 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">Phone</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.Name}</span>
                        </td>
                        <td data-label="confidence">
                            <span class="slds-truncate">{!account.Phone}</span>
                        </td>
                        <td data-label="confidence">
                            <span class="slds-truncate">{!account.Active__c}</span>
                        </td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table><!-- TABLE - BADGE COMPONENT -->
    </div><!-- REQUIRED SLDS WRAPPER -->
</aura:component>

This Lighting Component will output Accounts searched from VisualForce Page.

In order to display a Lightning Component in a Visualforce page, you need to construct a simple Lightning Application that is used as the bridge between the two technologies. This needs to have a dependency on the Lightning Component that will display the content, I used JSRemote in this case.

JSRemote.app :

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

Once the app is in place, there is markup in the Visualforce page to tie things together – note that the Lightning Component is constructed dynamically via JavaScript, rather than being included in the page markup server side.

JSRemoteDemo.page :

<apex:page controller="AccountRemoter" standardStylesheets="false" sidebar="false" showHeader="false" >
    
    <!-- Lightning Resources-->
    <apex:includeScript value="/lightning/lightning.out.js" />
    <apex:stylesheet value="/resource/SLDS/assets/styles/salesforce-lightning-design-system-vf.css"/>
    
    <script type="text/javascript">
        function getRemoteAccount() {
            var accountName = document.getElementById('acctSearch').value;
            document.getElementById("lightningComponent").innerHTML = " ";
            document.getElementById("responseErrors").style.display = "none";
            
            //Remote Function
            Visualforce.remoting.Manager.invokeAction(
                '{!$RemoteAction.AccountRemoter.getAccount}',
                accountName, 
                function(result, event){
                    if (event.status) {
                        
                        if(result.length > 0){
                            //Adding Lightning Component Here
                            $Lightning.use("c:JSRemote", function() {
                                $Lightning.createComponent("c:JSRemoteComp",
                                      { "accounts" : result },
                                      "lightningComponent",
                                      function(cmp) {
                                        // any further setup goes here
                                });
                            });
                            
                        }else{
                            document.getElementById("responseErrors").style.display = "block";
                            document.getElementById("responseErrors").innerHTML = "No Records Found";
                        }
                        
                    } else if (event.type === 'exception') {
                        document.getElementById("responseErrors").style.display = "block";
                        document.getElementById("responseErrors").innerHTML = 
                            event.message + "
\n




<pre>" + event.where + "</pre>

";
                    } else {
                        document.getElementById("responseErrors").style.display = "block";
                        document.getElementById("responseErrors").innerHTML = event.message;
                    }
                },
                {escape: true}
            );
        }
    </script>
<div class="slds">
        <input id="acctSearch" class="slds-input" type="text" placeholder="Search Account"/>
        <button class="slds-button slds-button--neutral" onclick="getRemoteAccount()">Get Account</button>
        <!-- Error Message -->
<div id="responseErrors" style="display:none;" class="slds-notify slds-notify--alert slds-theme--error slds-theme--alert-texture" role="alert">
        </div>
</div>

    <!-- Lightning Component -->
<div id="lightningComponent"/>
</apex:page>

Output will look similar to this.

jsremoting

So That’s It.

Leave a comment