Saturday, December 22, 2018

Notifications Library powers to create Toast and Notices

We have been using window.alert, window.confirm, window.prompt for various reasons, all these screens runs in synchronous mode and pauses your execution logic until clicks on a button.

Below are the offerings of the Lightning frame work in the for of Notifications Library which runs in asynchronous mode

Messages can be displayed in notices and toasts. Notices alert users to system-related issues and updates. Toasts enable you to provide feedback and serve as a confirmation mechanism after the user takes an action.
Include one <lightning:notificationsLibrary aura:id="notifLib"/> tag in the component that triggers the notifications, where aura:id is a unique local ID. Only one tag is needed for multiple notifications.

Notices

Notices interrupt the user's workflow and block everything else on the page. Notices must be acknowledged before a user regains control over the app again. As such, use notices sparingly. They are not suitable for confirming a user’s action, such as before deleting a record. To dismiss the notice, only the OK button is currently supported.
Notices inherit styling from prompts in the Lightning Design System.
Here’s an example that contains a button. When clicked, the button displays a notice with the error variant.
==================================================================================
<aura:component implements="flexipage:availableForAllPageTypes" access="global" >
  <lightning:notificationsLibrary aura:id="notifLib"/>
    <lightning:button name="notice" label="Show Notice" onclick="{!c.handleShowNotice}"/>
    
    <lightning:button name="toast" label="Show Toast" onclick="{!c.handleShowToast}"/>
</aura:component>
===================================================================================

({    
    handleShowNotice : function(component, event, helper) {
        component.find('notifLib').showNotice({
            "variant": "error",
            "header": "Something has gone wrong!",
            "message": "Unfortunately, there was a problem updating the record.",
            closeCallback: function() {
                alert('You closed the show notice!');
            }
        });
    },
      handleShowToast : function(component, event, helper) {
        component.find('notifLib').showToast({
            "title": "Notif library Success!",
            "message": "The record has been updated successfully.",
            "variant": "success"
        });
    }
})
===============================================================================
Show toast Example:



Show Modal Example:






Tuesday, October 16, 2018

Another advanced way of Parent to child component communication

We have been using below two techniques to communicate from parent to child. In addition to the below techniques, introducing advance way of communication with the component body technique.




Component Body

The root-level tag of every component is <aura:component>Every component inherits the body attribute from <aura:component>. We dont need to create a separate attribute to handle the v.body.
 Any free markup that is not enclosed in one of the tags allowed in a component is assumed to be part of the body and is set in the body attribute.
The body attribute has type Aura.Component[]. It can be an array of one component, or an empty array, but it's always an array.
In a component, use “v” to access the collection of attributes. For example, {!v.body} outputs the body of the component.

Below is the perfect example for body communication technique. Follow the step by step process to see the end result. Its gonna be very advanced level of communication technique.

===========
Step 1:  Markup : Coldata   (below component just acts like a programmatic abstraction, it wont display any data). Sole purpose of the below component is to pass the data to the Childcmp.
=========
<aura:component >
     <aura:attribute name="Firstname" type="string" />
     <aura:attribute name="LastName" type="string" />
     <aura:attribute name="age" type="Integer" />
</aura:component>

==========
Step 2:  Markup :Coldata2 (Again below component also just acts like a programmatic abstraction, it wont display any data). Sole purpose of the below component is to pass the data to the Childcmp.
=========

<aura:component >
     <aura:attribute name="att1" type="string" />
     <aura:attribute name="att2" type="string" />
</aura:component>

=========
Step 3:  Markup :Childcmp 
=========

<aura:component >
    <aura:attribute name="subtagsdata" type="object[]" />
     <aura:attribute name="subtagsdata2" type="object[]" />
    <aura:handler name="init" value="{!this}"  action="{!c.doinit}" />
    
    {!v.body}  <!---without this attribute you would not be able to access the body placed in the below parent component(see step 5) -->
    <table border="1">
        <tr>
        <th>FirstName</th>
             <th>LastName</th>
             <th>Age</th>
        </tr>
     <aura:iteration items="{!v.subtagsdata}" var="item">
          <tr>
        <td> {!item.Fname} </td>
         <td>  {!item.Lname}  </td>
         <td>  {!item.age} </td>
                </tr>
    </aura:iteration>
    </table>
</aura:component>

========
Step 4:  JavaScript controller:Childcmp 
========

({
doinit : function(component, event, helper) {
        var body=component.get("v.body");
        var coldata=[];
         var coldata2=[];
        
        for(var i=0; i<body.length;i++){
            /* below code differentiates two different components instances */
            if(body[i].isInstanceOf("c:Coldata")){
            coldata.push(
                {
                 Fname:body[i].get('v.Firstname'),
                 Lname:body[i].get('v.LastName'),
                 age:body[i].get('v.age')
                
                }
            
            );} else{
                
                 coldata2.push(
                {
                 att1:body[i].get('v.att1'),
                 att2:body[i].get('v.att2')
                
                }
           
            );
            }
        }
        
        component.set('v.subtagsdata',coldata);
         component.set('v.subtagsdata2',coldata2);
        console.log('%%%%Col data 1%%%%'+JSON.stringify(component.get('v.subtagsdata')));
         console.log('%%%%Col data 2%%%%'+JSON.stringify(component.get('v.subtagsdata2')));
}
})
=============
Step 5:  Markup : Parentcmp 
=============
<aura:component >
    <aura:attribute name="fn" type="string" default="Oliva trainings"/>
    <c:Childcmp >
        <c:Coldata Firstname="Dave" LastName="Oliva" age="28" />
        
          <c:Coldata Firstname="Dave1" LastName="Oliva1" age="29" />
        
          <c:Coldata Firstname="Dave2" LastName="Oliva2" age="30" />
        
          <c:Coldata Firstname="Dave3" LastName="Oliva3" age="31" />
        
        <c:Coldata2 att1="col2dataatt1" att2="col2dataatt2" />
        
          <c:Coldata2 att1="col2dataatt1" att2="col2dataatt2" />
               
    </c:Childcmp>  
</aura:component>

=========
Step 6:  Markup :Bodycommunication 
=========

<aura:application >
    <c:Parentcmp />
</aura:application>

Final output looks as below.


Thursday, September 13, 2018

Best way of using lightning helper method and Switch statements

JavaScript Controllers and Helpers play a key role in Lightning Components Framework. One of the first things people new to the framework wonder is: What exactly is the difference between JavaScript Controllers and JavaScript Helpers. 

 To understand it better, here I'm taking simple example to determine what would get from Helper and why we need to delegate logic to the helper from controller. Though this code incorporated with basic logic like add, sub, mul and div. It has lot of take away's in terms of frame work concepts.  Out put looks as below.







Earlier I have provided similar kind of code to demonstrate getters, setters, hide and seek mechanism, and many more with very basic example to keep the things simple. If you want to check it, please hit this link Simple calci for the same. 

================

Step 1: create a component with the name "NoHelpercmp" and  copy the below mark up code in the new component

Mark up: c:NoHelpercmp 

================
<aura:component implements="flexipage:availableForAllPageTypes" access="global" >

    

    <aura:attribute name="num1" type="integer" />

    <aura:attribute name="num2" type="integer" />    

    <aura:attribute name="num3" type="integer" />

    <aura:attribute name="str" type="String" default="None of them selected"/>
    <lightning:card variant="Narrow" title="My Caluclations" >

        <lightning:input name="input1" label="Enter first number" type="number" value="{!v.num1}" aura:id="abc" id="ccc"/>

        <lightning:input name="input2" label="Enter second number" type="number" value="{!v.num2}" aura:id="xyz"/>

        {!v.str}     <ui:outputNumber value="{!v.num3}"/>

        <aura:set attribute="actions">

            <lightning:buttonGroup >

                <lightning:button label="Div" variant="brand" onclick="{!c.Div}" title="Div Method"  />

                <lightning:button label="Add" variant="success" onclick="{!c.Add}" title="Add Method"  />

                <lightning:button label="Sub" variant="brand" onclick="{!c.Sub}"  />

                <lightning:button label="Mul" variant="destructive"  onclick="{!c.Mul}"  class=""/>

            </lightning:buttonGroup>

        </aura:set>
    </lightning:card>

</aura:component>

==============

Step 2: copy the below code and paste it in the NoHelpercmp Controller

=================

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

     var n1=parseInt(component.find("abc").get("v.value"));  //repeated code

         var n2=parseInt(component.find("xyz").get("v.value"));  //repeated code

         var c=n1-n2; 

         component.set("v.str","sub of 2 number");

          component.set("v.num3",c);

},

    Mul : function(component, event, helper) {

         var n1=parseInt(component.find("abc").get("v.value"));  //repeated code
         var n2=parseInt(component.find("xyz").get("v.value"));  //repeated code

         var c=n1*n2; 

          component.set("v.str","Mul of 2 number");

      component.set("v.num3",c);

},
Add : function(component, event, helper) {

     var n1=parseInt(component.find("abc").get("v.value"));  //repeated code

         var n2=parseInt(component.find("xyz").get("v.value"));  //repeated code

         var c=n1+n2; 

         component.set("v.str","sub of 2 number");

          component.set("v.num3",c);

},

    Div : function(component, event, helper) {

         var n1=parseInt(component.find("abc").get("v.value"));  //repeated code

         var n2=parseInt(component.find("xyz").get("v.value"));  //repeated code

         var c=n1%n2; 

          component.set("v.str","Mul of 2 number");

      component.set("v.num3",c);

}

})



============

Test the above component by using below application container, It still works but its not a best practice to handle the logic in the controller. Your Js controller methods were not desinged for re-usability  purpose.

step 3 : create aura:application container and replace following code and preview it.

============

<aura:application extends="force:slds">

    <c:NoHelpercmp/>


</aura:application>

================

Mark up: c:Helpercmp 

Follow the similar kind of steps which you followed from step 1 to step 3 and then additionally use the step 4(helper function) which is mentioned below.

================

<aura:component implements="flexipage:availableForAllPageTypes" access="global" >

    

    <aura:attribute name="num1" type="integer" />

    <aura:attribute name="num2" type="integer" />    

    <aura:attribute name="num3" type="integer" />

    <aura:attribute name="str" type="String" default="None of them selected"/>

    
    <lightning:card variant="Narrow" title="My Caluclations" >

        <lightning:input name="input1" label="Enter first number" type="number" value="{!v.num1}" aura:id="abc" id="ccc"/>


        <lightning:input name="input2" label="Enter second number" type="number" value="{!v.num2}" aura:id="xyz"/>

        {!v.str}     <ui:outputNumber value="{!v.num3}"/>

        <aura:set attribute="actions">

            <lightning:buttonGroup >

                <lightning:button label="Div" variant="brand" onclick="{!c.Allcaluclations}" title="Div Method"  />

                <lightning:button label="Add" variant="success" onclick="{!c.Allcaluclations}" title="Add Method"  />

                <lightning:button label="Sub" variant="brand" onclick="{!c.Allcaluclations}"  />

                <lightning:button label="Mul" variant="destructive"  onclick="{!c.Allcaluclations}"  />

            </lightning:buttonGroup>

        </aura:set>

        

        

    </lightning:card>

</aura:component>



=================

Js controller code with delegates business logic to helper.

=================



({

Allcaluclations : function(component, event, helper) {

      helper.Mymethod(component, event, helper);

}

})


==============

Step 4: Helper to perform all the calculations with in the same function

==============

({

    Mymethod : function(component, event, helper) {

        var buttonlabel=event.getSource().get('v.label');

        this.Myswtich(component, event, helper,buttonlabel);


    },


     Myswtich : function(component, event, helper,buttonlabel) {

            var a=parseInt(component.get('v.num1'));

        var b=parseInt(component.get('v.num2'));

        switch (buttonlabel) {

            case 'Add':

                component.set("v.str","Addition of two numbers");       

                var c=a+b; 

                break;

            case 'Sub':

                component.set("v.str","Sub of two numbers");

                var c=a-b; 

                break;

            case 'Mul':

                component.set("v.str","Mul of two numbers");

                var c=a*b; 

                break; 

            case 'Div':

                component.set("v.str","Div of two numbers");

                var c=a%b; 

                break; 

        }

        
        component.set("v.num3",c);


     }

    

})



============

Test the above component by using below application container.

============



<aura:application extends="force:slds">

    
    <c:Helpercmp/>



</aura:application>

Saturday, August 4, 2018

Lightningout in W3 schools (Share Lightning Out Apps with Non-Authenticated Users)

Share Lightning Out Apps with Non-Authenticated Users


Paste the below code in the w3 schools which enables you to see the lightning component screen in the external site(w3school). As of my research this is the simple and best POC to show how the Lightning out works in the external sites.
====================================================================
<!DOCTYPE html>
<html>
<head>
<body>
<div id="lightning" />


<script src="https://oliva-developer-edition.ap5.force.com/dave/lightning/lightning.out.js"></script>

<script type="text/javascript">


window.onload= function(){

    $Lightning.use("c:CalciApp", function() {
          $Lightning.createComponent("c:Calci",
          {},
          "lightning",
          function(cmp) {
            // do some stuff
          });
        }, "https://oliva-developer-edition.ap5.force.com/dave");
     
}       
     
</script>
==================================================================

Add the ltng:allowGuestAccess interface to your Lightning Out dependency app to make it available to users without requiring them to authenticate with Salesforce. This interface lets you build your app with Lightning components, and deploy it anywhere and to anyone.
A Lightning Out dependency app with the ltng:allowGuestAccess interface can be used with Lightning Components for Visualforce and with Lightning Out.

The ltng:allowGuestAccess interface is only usable in orgs that have Communities enabled, and your Lightning Out app is associated with all community endpoints that you’ve defined in your org.

Note: When you make a Lightning app accessible to guest users by adding the ltng:allowGuestAccess interface, it’s available through every community in your org, whether that community is enabled for public access or not. You can’t prevent it from being accessible via community URLs, and you can’t make it available for some communities but not others.
IMP: this lightningout only works when you keep your community domain in the code. It wont work with your regular org domain.

For more details, please follow the below source.

Lightningout documentation

None of SSO users were able to login.

If SSO is down and you dont have option to login into the Salesforce org completely, don't worry there is a way system administrator can login into the org by hitting below URL 

<MyDomain URL>?login=1 


Replace My domain url with your companies domain name and try to login, you should be able to login.