Sunday, 21 October 2018

Aura Method in Lightning Component | aura:method | Communicate Between Components


In our last post we talk about Lightning Component Event for Component communication. In this post we will talk about how to do component communication with the help of <aura:method > . Aura:Method enables you to directly call a method in a component’s client-side controller instead of firing / handling a component event. With the help of  <aura:method > we can call child component method from parent component.

Syntax :-

How to call method :- Simply call the function and pass parameter value in parent component

component.sampleMethod(arg1);
 
How to declare method :- Declare the aura:method with attribute

<aura:method name="sampleMethod" action="{!c.callAction}" description="Sample"> 
    <aura:attribute name="param1" type="String" default="param1"/> 
</aura:method>


Aura Method Action :- get the Aura:Attribute value with event.getParam('arguments');
({
    callAction: function(cmp, event) {
        var params = event.getParam('arguments');
        if (params) {
            var p1 = params.param1;
            // add your code here
        }
    }
})


Get Message from Child Component to parent Component.

Step 1) Create Child component with Aura:Method.

ChildCmp.cmp
<!--ChildCmp.cmp-->
<aura:component >
    <aura:method name="GetMessageFromChildMethod" action="{!c.getMessage}"
                 access="public">
        <aura:attribute name="Name" type="String" default="Amit"/>
    </aura:method>
</aura:component>

Step 2) Create Child Class Controller to Get argument "event.getParam('arguments');" and return the message.

ChildCmpController.js
({
    getMessage : function(component, event) {
        var params = event.getParam('arguments');
        if (params) {
            var param1 = params.Name;
            return "##### Hello "+param1+" From Child Component #####";
        }
        return "";
    }
})

Step 3) Create a parent Component and a button to call Aura method.

ParentCmp.cmp
<!--ParentCmp.cmp-->
<aura:component >
    <aura:attribute name="message" type="String"
                    default="------ Hello From Parent -----"/>
    <c:ChildCmp aura:id="childComponent"/>
  
    <div class="slds-m-around_xx-large">
        <lightning:button variant="brand" label="Call Aura Method"
                          onclick="{!c.callAuraMethod}" />
        <BR></BR> <BR></BR>
        <p>{!v.message}</p>
    </div>
</aura:component>

Step 4) Create Parent Component Controller to Call Aura Method "childCmp.GetMessageFromChildMethod('Amit');".

ParentCmpController.js
({
     callAuraMethod : function(component, event, helper) {
            var childCmp = component.find("childComponent");
            var retnMsg = childCmp.GetMessageFromChildMethod('Amit');
            component.set("v.message", retnMsg);
     }
})

DemoApp.app
<aura:application extends="force:slds">
    <c:ParentCmp/>  
</aura:application>

Output :-





Reference
1) https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cmp_methods.htm


Please join our YouTube Channel. Please check below related post

1Component Event in Lightning Component | aura:event  
2) Invoke Apex from Lightning Component
3) Design Resource In Lightning Component Bundle
4) Create and Destroy Modal Dialog Component



Please provide your comment and feedback.


Thanks,
Amit Chaudhary

Capture.JPG  @amit_sfdc    @ApexHours
  Salesforce Apex Hours 
    #SalesforceApexHours  

Monday, 8 October 2018

Inheritance In Lightning Component


 Lightning framework Support inheritance same like Apex or Java. If you mark any component as extensible=”true” means component can be inherited by any component. Inheritance allows us use JavaScript functions and attributes of extensible component in child components.

We need to Follow below point
  1. Create a Base Component and set extensible=”true”.
  2. Create a controller or helper for base component.
  3. In Child Component set extend base component. Like extends=”C:BaseComponent”
  4. You can also use the Base Component attribute in Child Component like {!v.AttributeName }
  5. You can call Base component helper/controller method from child component like  helper.baseComponentHelperMethodName(params);
Use Case :- Some time we have many components which call apex controller method from helper function. So instead of writing getDataFromServer method in all components helper function , we  can create a component and mark it as extensible=”true” component and write getDataFromServer function in helper function once. Now in other components, we need to extends that component and we just need to call getDataFromServer function.

Here is Sample Code for you

Step 1) Create a Base Component and set extensible=”true”.

BaseComponent.cmp
<aura:component extensible="true" controller="AccountUtil" > 
    <aura:attribute name="message" type="String" default="Value from Parent"/>
    {!v.body}
</aura:component>

Step 2) Create a controller or helper for base component.

BaseComponentHelper.js
({
    getDataFromServer : function(component, method, callback, params )
    {
        var action = component.get(method);
        if (params) {
            action.setParams(params);
        }
        action.setCallback(this,function(response)
        {
            var state = response.getState();
            if (state === "SUCCESS") {
                callback.call(this,response.getReturnValue());  
            } else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    alert('errors'+errors);   
                }
            }
        });
        $A.enqueueAction(action);
    },
})

Step 3) In Child Component set extend base component. Like extends=”c:BaseComponent”

ChildComponent.cmp
<aura:component implements="flexipage:availableForAllPageTypes" extends="c:BaseComponent"  access="global" >
        <!-- This Example is for Inherit Component attribute-->
        <BR></BR>
            <div>
                <!--
                    Set Vaule if you want to override message value
                    <aura:set attribute="message" value="ChildComponent is inherited in BaseComponent"/>
                -->
                Inherited Component attribute Value =  {!v.message}
            </div>
        <BR></BR>
   
        <!-- This Example is for Inherit Helper method-->
        <aura:attribute name="ListAcc" type="List"/>
        <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
        <div class="slds-align--absolute-center">
            <table aura:id="accTable" class="slds-table slds-table--bordered slds-table--cell-buffer" cellspacing="0" width="100%">

                <thead>
                    <tr class="slds-text-title--caps">
                        <th scope="col">Account ID</th>
                        <th scope="col">Account name</th>
                        <th scope="col">Account Number</th>
                    </tr>
                </thead>   
                <tbody>
                    <aura:iteration items="{!v.ListAcc}" var="acc">
                        <tr>
                            <td>{!acc.Id}</td>
                            <td>{!acc.Name}</td>
                            <td>{!acc.AccountNumber}</td>
                        </tr>
                    </aura:iteration>
                </tbody>
            </table>
        </div>          
</aura:component>
 NOTE:- You can also use the Base Component attribute in Child Component like {!v.message }


ChildComponentController.js
({
    doInit : function(component, event, helper) {       
        helper.getAllAccounts(component, helper);
    },
})

Step 4) You can call Base component helper/controller method from child component like  helper.getDataFromServer(params);

ChildComponentHelper.js
({
    getAllAccounts : function(component, helper) {
        //Calling base component's helper method
        helper.getDataFromServer(component,
                                 "c.getAccounts",
                                 function(response){
                                     if(response){
                                         component.set("v.ListAcc", response);
                                     }
                                 }
                                );
    },
})


AccountUtil.apxc
public class AccountUtil {
   
    @AuraEnabled
    public static List<Account> getAccounts()
    {
        return [SELECT Id, Name, Phone, AccountNumber FROM Account  LIMIT 10];
    }
}


TestInheritance.app
<aura:application extends="force:slds">
    <c:ChildComponent />
</aura:application>


 Output:-


 
Please check our old post on Lightning :-
 
1) Invoke Apex from Lightning Component 

2) Design Resource In Lightning Component Bundle
3) Component Event in Lightning Component | aura:event
4) Modal/Popup in Lightning Component

5) Dynamically Creating Components Part 1:- createComponents

Feel free to post your feedback or question.


Thanks,
Amit Chaudhary

Capture.JPG  @amit_sfdc    @ApexHours
  Salesforce Apex Hours
    #SalesforceApexHours  

Monday, 1 October 2018

Dynamically Creating Components Part 2:- Create and Destroy Modal Dialog Component


In our last post we talk about modal/popup on button click. But in this post we will Dynamically Instantiate the lightning component and Destroy the lightning component on button click. If you want to learn about $A.createComponent() . Please check our old post.

Problem :- Hide and Show Modal on button click
Solution :- We can do the same with help of CSS ,JavaScript and Aura:If  but this time we will dynamically Instantiate the Lightning component on button Click and Destroy on button click with the help of $A.createComponent() .


Example 1) Show and Hide Modal Dialog Dynamically :-


Step 1) Create one Modal Component.

MyModalComponent.cmp
<aura:component >
    <div class="demo-only" style="height: 640px;">
        <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
            <div class="slds-modal__container">
                <header class="slds-modal__header">
                    <lightning:buttonIcon iconName="utility:close" variant="bare" onclick="{! c.RemoveMe }"
                                          alternativeText="Close" class="slds-modal__close" />
                    <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">
                        Modal Header
                    </h2>
                </header>
                <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                    <p>Salesforce Apex Hours</p>
                </div>
                <footer class="slds-modal__footer">
                    <button class="slds-button slds-button_neutral">Cancel</button>
                    <lightning:button variant="brand" label="Remove Me" title="Remove Me" onclick="{! c.RemoveMe }"/>
                </footer>
            </div>
        </section>
        <div class="slds-backdrop slds-backdrop_open"></div>
    </div>
</aura:component>

Create Modal Dialog Component with the help of SLDS.

MyModalComponentController.js

({
    RemoveMe : function(component, event, helper) {
         component.destroy();
    }
})

"component.destroy();" method is used to destroy the Lightning Component Dynamically.

Step 2) Now create one Component with button to create Component.

MainComponent.cmp
<aura:component >
     <div>
        <button class="slds-button slds-button--neutral" onclick="{!c.createModal}">Open Modal</button>  
        <!-- Modal will come here-->       
        <div aura:id="ModalDiv">
            {!v.body}
        </div>
    </div>
</aura:component>
In above code we create one Button and added action on button click to Instantiate the lightning componen. Also added one Div "<div aura:id="ModalDiv">" tag where modal will load.

MainComponentController.js
({
    createModal : function(component, event, helper) {
        $A.createComponent(
            "c:MyModalComponent",{},
            function(myModal){
                if (component.isValid()) {
                    var targetCmp = component.find('ModalDiv');
                    var body = targetCmp.get("v.body");
                    body.push(myModal);
                    targetCmp.set("v.body", body);           
                }
            }
        );
    },
})

Step 3) Create Application to Test Above Code.

<aura:application extends='force:slds'>
    <c:MainComponent />
</aura:application>



Example 2) Show and Hide Modal Dialog Dynamically with Component Communication


If you want to send some message in Modal and want to get some value back in main component from modal then we can do the same with the help of event. If you want to lean about about Event. Please check our old post.

Step 1) Create one event

MyModelEvent.evt
<aura:event type="COMPONENT" description="Event template" >
    <aura:attribute name="ModalMsg" type="String" />
</aura:event>
Create one event with one String Attribute.

Step 2) Update your modal Component.

MyModalComponent.cmp
<aura:component >
    <aura:attribute name="title" type="String" required="true"/>
    <aura:attribute name="msg" type="String" />
  
    <aura:registerEvent name="sendMsg" type="c:MyModelEvent"/>
  
    <div class="demo-only" style="height: 640px;">
        <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
            <div class="slds-modal__container">
                <header class="slds-modal__header">
                    <lightning:buttonIcon iconName="utility:close" variant="bare" onclick="{! c.RemoveMe }"
                                          alternativeText="Close" class="slds-modal__close" />
                    <h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">
                        {!v.title}
                    </h2>
                </header>
                <div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
                    <div class="row">
                        <lightning:input name="input1" value="{!v.msg}" label="Enter Message From Modal" />
                    </div>

                </div>
                <footer class="slds-modal__footer">
                    <button class="slds-button slds-button_neutral">Cancel</button>
                    <lightning:button variant="brand" label="Remove Me" title="Remove Me" onclick="{! c.RemoveMe }"/>
                </footer>
            </div>
        </section>
        <div class="slds-backdrop slds-backdrop_open"></div>
    </div>
</aura:component>
In above component we added two attribute. "title" to get value from other component. and "msg" to send value from Modal Component. And We also added "<aura:registerEvent" to register the Event.

 MyModalComponentController.js
({
    RemoveMe : function(component, event, helper) {
        var cmpEvent = component.getEvent("sendMsg");
        cmpEvent.setParams( { "ModalMsg" : component.get("v.msg") } );
        cmpEvent.fire();

        component.destroy();
    }
})
Add the above selected code to fire the event.

Step 3) Handle the Event in Parent Component

MainComponent.cmp
<aura:component >
    <aura:attribute name="myTitle" type="String" />
    <aura:attribute name="MessageFromModal" type="String" />
  
    <aura:handler name="sendMsg" event="c:MyModelEvent" action="{!c.handleComponentEvent}"/>
   
<div>
        <div class="row">
            <lightning:input name="input" value="{!v.myTitle}" label="Enter Title for Modal" />
            <button class="slds-button slds-button--neutral" onclick="{!c.createModal}">Open Modal</button>  
        </div>
        <!-- Modal will come here-->       
        <div aura:id="ModalDiv">
            {!v.body}
        </div>
        <div class="row">
          Msg will Come here :---  {!v.MessageFromModal}
        </div>

      
    </div>
</aura:component>
Created two attribute, One "myTitle" to get value and "MessageFromModal" to send value in parent component. Also added the "<aura:handler" to handle the event.


MainComponentController.js
({
    createModal : function(component, event, helper) {
        $A.createComponent(
            "c:MyModalComponent",{
                "title": component.get("v.myTitle"),            },
            function(myModal){
                if (component.isValid()) {
                    var targetCmp = component.find('ModalDiv');
                    var body = targetCmp.get("v.body");
                    body.push(myModal);
                    targetCmp.set("v.body", body);           
                }
            }
        );
    },
  
    handleComponentEvent : function(cmp, event) {
        var accRec = event.getParam("ModalMsg");
        cmp.set("v.MessageFromModal", accRec);
    }
  
})
If you want to send attribute in ModalComponent then set the attribute while creating component. We also added "handleComponentEvent " method to get value from Event.


Step 4) Test the changes in Application

<aura:application extends='force:slds'>
    <c:MainComponent />
</aura:application>


Please join our YouTube Channel. Please check below related post
1) Please check "<aura:dependency>" tag as well.
2) Component Event in Lightning Component | aura:event 
3) Invoke Apex from Lightning Component
4) Design Resource In Lightning Component Bundle


Please provide your comment and feedback.



Thanks,
Amit Chaudhary

Capture.JPG  @amit_sfdc    @ApexHours
  Salesforce Apex Hours
    #SalesforceApexHours