Lightning Component for Dropbox

Hi All,

Today i will be showing you DropBox Lightning Component created by me and my colleague Balkishan Kachawa.

Dropbox is a file hosting service operated by Dropbox, Inc., headquartered in San Francisco, California,
that offers cloud storage, file synchronization, personal cloud, and client software. There are limits in storage of files in Salesforce. If you need a secure and free storage space for your files, you can use DropBox Lightning Component to store files directly in your DropBox app from Salesforce.

Features of this Lightning Component are :

  1. You can use this component on any sObject.
  2. You can store files for a specific record.
  3. You can upload multiple files.
  4. You can delete files directly in DropBox.
  5. You can view you files.

Click here to install Manage Package in your org.

After installing package register for My Domain.

Make sure you have DropBox Account. If you don’t have you can sign up and create DropBox App as below.

Sign up Dropbox account from DropBox website.

After the Sign up login into your dropbox account and then create a Dropbox App using following steps:

Go to on dropbox developer edition i.e. https://www.dropbox.com/developer
Click on My Apps > Create App.
Then fill all information about app and then click on create. See below screen shot.

dropbox

Manage Dropbox Key from Custom setting

Insert a record in custom setting using following steps:

  1. Navigate to Setup > Develop > Custom Settings, click on Manage of “Dropbox Key”.
  2. Click on New, than insert following value:

App Key : from DropBox App

App Secret : from DropBox App

Redirect URI : from salesforce <your domain>/apex/DropBoxOAuth or copy url from preview of DropBoxOAuth page.

isAuthentication : false

Click on Save.

Add Redirect URI in Dropbox App

To add Redirect URI, Open your Dropbox App and you must set auth2 Redirect URIs same as above Redirect URL.

That’s It.

Your final result will look like this:

Advertisements

EMI Calculator Component using Lightning

Hi All,

In this post I will tell you how to create EMI Calculator using Lightning Component.

How to Use EMI Calculator?

Our EMI Calculator is easy to use, intuitive to understand and is quick to perform. You can calculate EMI for home loan, car loan, personal loan, education loan or any other fully amortizing loan using this calculator.

Enter the following information in the EMI Calculator:

  • Principal loan amount you wish to avail (rupees)
  • Loan term (months or years)
  • Rate of interest (percentage)
  • EMI in advance OR EMI in arrears (for car loan only)

Let’s walk through code.

EMICalculator.cmp :

<aura:component implements="force:appHostable,force:hasRecordId,force:hasSObjectName,flexipage:availableForAllPageTypes">
    <ltng:require styles="/resource/SLDS/assets/styles/salesforce-lightning-design-system-vf.css"/>
    
    <div class="slds">
        <div class="slds-page-header">
            <div class="slds-grid">
                <div class="slds-col slds-has-flexi-truncate">
                    <div class="slds-media">
                        <div class="slds-media__figure">
                            <c:svgIcon svgPath="/resource/SLDS/assets/icons/standard-sprite/svg/symbols.svg#process" category="standard" size="large" name="user" />
                        </div>
                        <div class="slds-media__body">
                            <p class="slds-text-heading--label">Calculator</p>
                            <div class="slds-grid">
                                <h1 class="slds-text-heading--medium slds-m-right--small slds-truncate slds-align-middle">Calculate Your EMI</h1>
                            </div>
                        </div>
                    </div>
                </div>
                <!-- /slds-col-->                        
            </div>   
            <!-- /slds-grid-->                 
        </div>
        <!-- /slds-page-header-->
        <div class="container">
            <div class="slds-grid slds-m-top--medium slds-wrap">
                <div class="slds-col--padded slds-size--1-of-1">
                    <div id="err" style="display:none;" class="slds-notify slds-notify--alert slds-theme--error slds-theme--alert-texture" role="alert">
                        <h2>Please fill all Information</h2>
                    </div>
                    
                    <div class="slds-form--stacked">
                        <div class="slds-form-element">
                            <label class="slds-form-element__label" >Loan Amount</label>
                            <div class="slds-form-element__control">
                                <input id="loanAmt" class="slds-input" type="text"  required="" />
                            </div>
                        </div>
                        <div class="slds-form-element">
                            <label class="slds-form-element__label" >Loan Tenure (Months)</label>
                            <div class="slds-form-element__control">
                                <input id="months" class="slds-input" type="text" required="" />
                            </div>
                        </div>
                        <div class="slds-form-element">
                            <label class="slds-form-element__label" >Interest Rate</label>
                            <div class="slds-form-element__control">
                                <input id="rate" class="slds-input" type="text" required="" />
                            </div>
                        </div>
                        <div class="slds-form-element slds-m-bottom--medium ">
                            <ui:button label="Submit" press="{!c.getEMIDetail}"/> &nbsp;
                            <ui:button label="Reset" press="{!c.reset}"/>   &nbsp;
                            <ui:button label="Monthly Detail" press="{!c.getEMIMonthly}"/><br/>                            
                        </div>                        
                    </div>
                </div>
                
                <div class="slds-col--padded slds-size--1-of-1 " >
                    <div id="emiDiv" style="display:none;">
                        <div class="slds-form-element">
                            <span class="slds-form-element__label">EMI</span>
                            <div class="slds-form-element__control">
                                <span class="slds-form-element__static"><div id="EMI"></div></span>
                            </div>
                        </div>
                        <div class="slds-form-element">
                            <span class="slds-form-element__label">Interest Payable</span>
                            <div class="slds-form-element__control">
                                <span  class="slds-form-element__static"><div id="interestP"></div></span>
                            </div>
                        </div>
                        <div class="slds-form-element">
                            <span class="slds-form-element__label">Total Payable</span>
                            <div class="slds-form-element__control">
                                <span  class="slds-form-element__static"><div id="totalP" ></div></span>
                            </div>
                        </div>
                    </div>
                    <div id="addchart" class="slds-scrollable--y" style="display:none; max-height: 280px;"></div>
                </div>                
            </div>
            
                        
        </div>        
    </div>    
</aura:component>

EMICalculatorController.js:

({
    getEMIDetail : function(component, event, helper) {
        helper.getEMI(component, "EMI");
    },
    getEMIMonthly : function(component, event, helper) {
        helper.getEMI(component, "Monthly");
    },
    reset : function(component, event, helper) {
        document.getElementById("emiDiv").style.display = "none";
        document.getElementById("addchart").style.display = "none";
        document.getElementById('loanAmt').value="";
        document.getElementById('months').value="";
        document.getElementById('rate').value="";
    },    

})

EMICalculatorHelper.js :

({
	getEMI : function(component, detail) {
        if(detail =="EMI"){
            document.getElementById("emiDiv").style.display = "block";
            document.getElementById("addchart").style.display = "none";
        }else if(detail =="Monthly"){
            document.getElementById("emiDiv").style.display = "none";
            document.getElementById("addchart").style.display = "block";
        }
		var loanAmt = document.getElementById('loanAmt').value;
        var months = document.getElementById('months').value;
        var rate = document.getElementById('rate').value;
        
        if (loanAmt == null || loanAmt.length == 0 || months == null || months.length == 0 || rate == null || rate.length == 0) {
            document.getElementById("err").style.display = "block";            
        } else {
            document.getElementById("err").style.display = "none";                           
            var rate1 = rate / 1200;
            var emi= loanAmt * rate1 / (1 - (Math.pow(1 / (1 + rate1), months)));//Math.round(loanAmt * rate1 / (1 - (Math.pow(1 / (1 + rate1), months))) * 100) / 100;
            document.getElementById('EMI').innerHTML = Math.round(emi);
            document.getElementById('interestP').innerHTML = Math.round(emi * months) ;//Math.round((emi * months)) ;
            document.getElementById('totalP').innerHTML = Math.round((document.getElementById('interestP').innerHTML) * 1 - loanAmt * 1);//Math.round(((document.getElementById('interestP').innerHTML) * 1 - loanAmt * 1) * 100) / 100;
            
            var tile='<ul class="slds-list--vertical slds-has-cards">';
            var balance=0;
            for(i=1; i<=months; i++){                    
                if(i==1){
                    balance = loanAmt;                       
                }                       
                var interest = balance* (rate/100.0)/12;//(Math.round((balance* (rate/100.0)/12)*100)/100).toFixed(2);
                var Principal = emi - interest;//(Math.round((emi - interest)*100)/100).toFixed(2);
                balance = balance - Principal;//(Math.round((balance - Principal)*100)/100).toFixed(2);
                
                tile += '<li class="slds-list__item">';
                tile += '<div class="slds-tile slds-tile--board">';
                tile += '<p class="slds-tile__title slds-truncate"><a href="#">Month - '+ i +' </a></p>';
                tile += '<div class="slds-tile__detail">';
                tile += '<p class="slds-text-heading--medium">Installment - '+ Math.round(emi) +'</p>';
                tile += '<p class="slds-truncate"><a href="#">Interest - '+ Math.round(interest) +'</a></p>';
                tile += '<p class="slds-truncate">Princple - '+ Math.round(Principal) +'</p>';
                tile += '<p class="slds-truncate">Balance - '+ Math.round(balance) +'</p>';
                tile += '</div>';
                tile += '</div>';
                tile += '</li>';
            }
            tile += '</ul>';
            document.getElementById("addchart").innerHTML = tile;            
        }	
	}
})

EMICalculator.css

.THIS .slds-list__item{
    width: 300px;
    float: left;
    margin: 4px!important;
}

Your final result will look like this.

Thanks

Breadcrumbs using Component Event in Lightning Component

Hi All,

In this post I will tell you how to use Breadcrumbs using Component Event.

A component event is fired from an instance of a component. A component event can be handled by the component that fired the event or by a component in the containment hierarchy that receives the bubbled event.

This can be useful when trying to breabcrumbs in component and We’ll see how to attribute is used for firing and handling events by using <aura:registerEvent>. Register Component Event is registers that it may fire an event by using in its markup.

When complete it will look like these screenshots:


Let’s walk through code.

BreadcrumbContainer.cmp :

<aura:component implements="force:appHostable">
    <aura:attribute name="FixedBreadcrumbs" type="String[]" default="Home,Bread,End"/>
    <aura:attribute name="Breadcrumbs" type="String[]" default="Home"/>
    <aura:attribute name="itemName" type="String" default="Home"/>
<div class="breadcrumb">
        <aura:iteration items="{!v.Breadcrumbs}" var="menu" indexVar="i">
            <c:BreadcrumbContent index="{!i}" menu="{!menu}" cmpEvent="{!c.setNavigationEvent}"/>
        </aura:iteration></div>
<div class="container">
<div>
        	This is <b>{!v.itemName}</b>  Breadcrumbs</div>
<aura:if isTrue="{!v.FixedBreadcrumbs.length > v.Breadcrumbs.length}">

<ui:Button label="Next" press="{!c.next}" />
        </aura:if></div>
</aura:component>

BreadcrumbContainerController.js

({
	setNavigationEvent : function(component, event, helper){

        var index = event.getParam("navIndexEvent");
        var navbNew = [];
        var navb = component.get("v.FixedBreadcrumbs");
        for(i=0; i<=index; i++){
            navbNew.push(navb[i]);
        }
        component.set("v.itemName",navb[index]);
        component.set("v.Breadcrumbs",navbNew);
	},
    next : function(component, event, helper){
        var navb = component.get("v.FixedBreadcrumbs");
        var navbNew = component.get("v.Breadcrumbs");
        var len = navbNew.length;
        navbNew.push(navb[len]);
        component.set("v.itemName",navb[len]);
        component.set("v.Breadcrumbs",navbNew);
    }
})

BreadcrumbContainer.css

.THIS.breadcrumb {
    padding: 20px;
    background-color: antiquewhite;
    margin: 13px;
    border-radius: 5px;
    font-size:20px;
}

.THIS.container {
    text-align: center;
    font-size: 22px;
    margin: 15px;
    padding: 20px;
    background-color: peru;
    border-radius: 5px;
}

BreadcrumbContainer is component parent component of BreadcrumbContent.

BreadcrumbContent.cmp

<aura:component >
	<aura:registerEvent name="cmpEvent" type="c:CmpEvent"/>
	<aura:attribute name="menu" type="String" />
    <aura:attribute name="index" type="integer" />
    <a onclick="{!c.setNavigation}">{!v.menu}</a> ❱
</aura:component>

BreadcrumbContentController.js

({
	setNavigation : function(component, event, helper) {
        var cmpEvent = component.getEvent("cmpEvent");
        var index = component.get("v.index");

        cmpEvent.setParams({"navIndexEvent" : index});
        cmpEvent.fire();
    },
})

In this component i am using <aura:registerEvent>.

CmpEvent.evt

<aura:event type="COMPONENT" description="Event for set Index No." >
    <aura:attribute name="navIndexEvent" type="integer" default=""/>
</aura:event>

This is a Event with the type of COMPONENT.

Thanks

Lightning Component Bundle Concept

In my last post I showed how to use Nested Component in Lightning Component. In this post, I will be showing you some basic concept of Controller, Helper and Renderer oof Component Bundle.

bundle

Controller:

This is a client-side Controller. A client-side controller handles events within a component. It’s a JavaScript resource that defines the functions for all of the component’s actions.
Each action function takes in three parameters i.e. Component, Event, and Helper. A client-side controller is part of the component bundle.
It is auto-wired via the naming convention, <ComponentName>Controller.js like: DemoController.js here Demo is Component Name.

  • Component : component to which the controller belongs.
  •  Event : event that the action is handling.
  • Helper : helper if it’s used for calling helper method.

In the controller we can call function directly from action of component like: {!c.doSomething}. We can calls helper function from controller function with helper keyword.

Example :

Demo.cmp : This is Component of Demo Bundle

<aura:component >
    <ui:button label="Do Something" press="{!c.doSomething}"/>
</aura:component>

DemoController.js : This is Component Controller of Demo Component Bundle

({
    doSomething : function(component, event, helper) {
        alert("This is my Controller function");
    },
})

Note : we can’t call controller’s funtion or recursion funtion itself.

Helper:

Hepler is server-side Controller. It is usually use for firing server-side actions and process data or tasks. we can called Helper’s java-script function from a client-side controller or renderer. It is also part of the component bundle. A helper function can pass in any arguments required by the function, such as the component it belongs to, a callback, or any other objects.

It is auto-wired via the naming convention, <ComponentName>Helper.js like: DemoHelper.js here Demo is Component Name. The helper function calls an Apex controller method and queues the action. The Apex method is invoked and data is returned.
A JavaScript callback function is invoked when the Apex method completes. The JavaScript callback function evaluates logic and updates the component’s UI.

Example:
From above example we need to add some statement i.e.

DemoController.js : This is Component Controller of Demo Component Bundle

({
    doSomething : function(component, event, helper) {
        //Calling helper function
        helper.doSomethingHelper(component);
    },
})

DemoHepler.js : This is Component Helper of Demo Component Bundle

({
    doSomethingHelper : function(component, event, helper) {
        alert("This is my Helper function");
    },
})

If we want to reuse funtion in the component put it into helper. Hepler we can call helper’s funtion or recursion funtion itself.

Note : we cannot call Helper’s function directly from action of component like: {!c.doSomething}

Renderer :

Renderer is client-side Controller. It’s a JavaScript resource that defines the functions for all of the component’s actions.
Each action function takes in two parameters i.e. Component and Helper.It is auto-wired via the naming convention, ComponentName>Renderer.js like: DemoRenderer.js here Demo is Component Name.

The rendering lifecycle automatically handles rendering and rerendering of components whenever the underlying data changes. Here is an outline of the rendering lifecycle.

When an event is fired, it may trigger actions to change data and call rerender() on affected components. The rerender() function enables components to update themselves based on updates to other components since they were last rendered. This function doesn’t return a value. The framework automatically calls rerender() if you update data in a component. You only have to explicitly call rerender() if you haven’t updated the data but you still want to rerender the component. You generally want to extend default rerendering by calling superRerender() from your renderer() function before you add your custom rerendering code. Calling superRerender() chains the rerendering to the components in the body attribute.

Example:

DemoRenderer.js : This is Component Renderer of Demo Component Bundle

({
    render : function(component, helper) {
        var ret = this.superRender();
        //Calling Helper function
        helper.doSomethingHelper(component);
        return ret;
    },
})

Thanks!