Salesforce Lightning Component using Bootstrap
Component Frameworks
Frameworks like Polymer, React, Flight, Brick and Lightning are Component based UI frameworks where components are nothing but self-contained and reusable units of an app that are simply composed of HTML, CSS, JavaScript, or any other web-enabled code and no alien substances. These modern framework are used for building single-page and dynamic applications where the component represent a re-usable section of the whole UI.
Why use Component Frameworks?
Similar to the notion of Classes in Java, Components are encapsulated such that their internal functioning (be it the client-side Javascript code interacting with the DOM or with the server-side code) remains private while the final rendered output (HTML DOM elements) is public. As a result of this insulation the author of the components can make changes to the internal implementation without worrying about breaking the consumers code since the components in an app are configured by setting the named attributes that are exposed in their definition by the author.
Also, Component frameworks follow event driven architecture where the components communicate to each other by publishing and subscribing to events thereby resulting in a better decoupling between components.
Lightning Component framework
The Lightning Component framework by Salesforce is one such component framework which is built on the open source Aura framework. The framework empowers the developers to work faster with the help of out-of-the-box component set that function seamlessly with different kind of devices viz. desktop, tablets, mobile devices etc. so that the developer no longer need to worry about optimizing the app for various devices.
Lightning Component using Bootstrap
We will now create a simple lightning component that will have a multi-select picklist. Since the usual default multi-select picklist looks ugly we will use the bootstrap multi-select that comes with lot of customization. The final output looks as follows spiced up with the Lightning Design System:
Ugly Multiselect
Bootstrap Multiselect
To create a component:
- Go to Developer Console
- Click File then New and then Lightning Component
- Give a Name to your component and optionally enter the Description
MyContactList.cmp
The below code is what goes into the Component file:
<aura:component controller="MyContactListController">
<ltng:require styles=""
scripts=""
afterScriptsLoaded="{!c.scriptsLoaded}"/>
<aura:handler name="init" action="{!c.myAction}" value="{!this}" />
<aura:attribute name="contacts" type="Contact[]" />
<aura:attribute name="compname" type="String" />
<div class="slds">
<div class="slds-form-element">
<label class="slds-form-element__label" for="multiSelectSpan">{!v.compname}</label>
<div class="slds-form-element__control">
<div class="slds-select_container">
<span id="{!'multiSelectSpan' + v.compname}">
<select multiple="true" >
<aura:iteration items="{!v.contacts}" var="contact">
<option text="{!contact.Name}" label="{!contact.Name}"/>
</aura:iteration>
</select>
</span>
</div>
</div>
</div>
<div class="slds-form-element">
<div class="slds-form-element__control" id="{!v.compname}">
<!--input boxes for Phone will be dynamically added here -->
</div>
</div>
<hr></hr>
</div>
</aura:component>
Quick look at the code
-
Notice the
aura:
namespace for the<aura:component>
tag inherited from the Aura framework. -
The
Controller
attribute defines the associated Javascript Controller (similar to the controller in Visualforce pages) that handles both client-side and server-side methods. To trigger the server side Apex code the component has to do it via JS Controller. So in case of Components there will be two controllers: -
Server side i.e Apex Class : MyContactListController
public class MyContactListController { @AuraEnabled public static List<Contact> getContacts() { return [Select Id, Name, Email, Title, Phone From Contact LIMIT 5]; } }
-
Client Side : MyContactListController.js. This we will see in the next section.
-
The
<aura:handler>
attribute is used to define the action/method to be called when a certain event (defined by thename
attribute) is triggered. -
Scripts and Styles are included using the
scripts
andstyles
attributes respectively on<ltng:require>
tag. Multiple Scripts and Styles are included by comma separated paths. -
afterScriptsLoaded
attribute is used to trigger a javascript (client-side) function (scriptsLoaded
) where we will initialize and configure the Bootstrap multiselect. -
<aura:attribute>
tags are used to define variables in Component that can be accessed within the component and the JS Controller usingv.<variablename>
-
I have used
compname
variable to name the component and set unique id's in the DOM so that when we re-use the same component in the application they do not conflict with each other. This will be evident while we further see the Controller and application code. -
Tags with
<ui:
namespace are standard Lightning components and<aura:iteration
is likeforeach
loop. Rest of the markup is of Lightning Design System.
MyContactListController.js
To create the controller code simply click on the CONTROLLER option in the right corner or press CTRL+SHIFT+2
and copy the below given code.
The myAction
function here is triggered when the component is initialized (init event fired) as defined in <aura:handler name="init" action="{!c.myAction}" value="{!this}" />
. And the scriptsLoaded
attribute as discussed earlier initializes and configures the bootstrap multi-select as per the docs. Note the use of comp.get("v.compname")
function in the JQuery selector where we append the input
element; this ensures that when the same component is re-used in an application the input
elements goes only to the block corresponding to that particular component : <span id="{!'multiSelectSpan' + v.compname}">
.
({
myAction : function(component, event, helper) {
var action = component.get("c.getContacts");
var isSelectLoaded = false;
action.setCallback(this, function(data) {
component.set("v.contacts", data.getReturnValue());
isSelectLoaded = true;
});
$A.enqueueAction(action)
},
scriptsLoaded : function(comp,event,helper){
var selector = "#multiSelectSpan" + comp.get("v.compname");
console.log(selector);
console.log('done');
setInterval(function() {
console.log('inside set interval')
if (true) {
var selector = "#multiSelectSpan" + comp.get("v.compname");
$( selector + " > select").multiselect({
onChange: function(option, checked) {
console.log(comp.get("v.compname"));
console.log($(option).val()+":"+(checked));
var s = $(option).val();
if(checked)
$("#"+comp.get("v.compname")).append(jQuery("<input placeholder='Enter Phone for "+s+"' id='"+s.replace(" ",'-')+"-"+comp.get("v.compname")+"' style='height: 35px;font-size: 14px;width: 25%;margin: 5px;display:block' class='inputonly slds-input' type='text'/>"));
else
$('#'+s.replace(" ",'-')+"-"+comp.get("v.compname")).remove();
}
})
}
}, 500);
},
})
MyContactListApp.app
Now to create an application, Go to File then New and click on Lightning Application. Give a Name, Description and then Submit. Enter this simple code using the component. I have re-used the component twice and given them unique names using the compname
attribute.
<aura:application >
<c:MyContactList compname="Component-1"/>
<c:MyContactList compname="Component-2"/>
</aura:application>
To preview the app click Preview in the right corner.
You can provide additional styling to the component by entering the CSS code in the components STYLE file.
MyContactList.css
.THIS .slds-select_container {
margin:5px;
width: 0px;
}
.THIS input::-webkit-input-placeholder { font-size:12px }
.THIS input::-moz-placeholder { font-size:12px } /* firefox 19+ */
.THIS input:-ms-input-placeholder { font-size:12px } /* ie */
.THIS input:-moz-placeholder { font-size:12px }
.THIS label.slds-form-element__label {
margin: 10px;
font-size:12px;
}
This obviously isn't an exhaustive description and all about Lightning Components and there is much much more to this. I found the below article by Jeff Douglas a great start to understand the core concepts by building a simple but real-world Lightning Component.
TUTORIAL - BUILD YOUR FIRST LIGHTNING COMPONENT