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

Ugly Multiselect

Bootstrap Multiselect

Bootstrap Multiselect


To create a component:

  1. Go to Developer Console
  2. Click File then New and then Lightning Component

New Lightning Component

  1. Give a Name to your component and optionally enter the Description

Component details

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

  1. Notice the aura: namespace for the <aura:component>tag inherited from the Aura framework.

  2. 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:

  3. 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];
         }
        }
    
  4. Client Side : MyContactListController.js. This we will see in the next section.

  5. The <aura:handler> attribute is used to define the action/method to be called when a certain event (defined by the name attribute) is triggered.

  6. Scripts and Styles are included using the scripts and styles attributes respectively on <ltng:require> tag. Multiple Scripts and Styles are included by comma separated paths.

  7. afterScriptsLoaded attribute is used to trigger a javascript (client-side) function (scriptsLoaded) where we will initialize and configure the Bootstrap multiselect.

  8. <aura:attribute> tags are used to define variables in Component that can be accessed within the component and the JS Controller using v.<variablename>

  9. 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.

  10. Tags with <ui: namespace are standard Lightning components and <aura:iteration is like foreach 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.

Create Component Javascript Controller

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}">.

Reusing Components in same application

({
	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.

Preview the app

You can provide additional styling to the component by entering the CSS code in the components STYLE file.

Create Component 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


You’ve successfully subscribed to inteygrate
Welcome back! You’ve successfully signed in.
Great! You’ve successfully signed up.
Your link has expired
Success! Check your email for magic link to sign-in.