+ Start a Discussion
Luciano RobertoLuciano Roberto 

Lightining component - Configure dynamic toast per alert object

Folks,


In the Salesforce Lightning Design System portal, show an example of a toast usage as per link below:

https://www.lightningdesignsystem.com/components/toast/


I used this example as the basis for setting it up in an environment.
The environment is configured as described below:

I have an object, called Alert, where the user can include as many alerts as he wants.
Each record of the object is an alert.

Fields of the Alert__c object:

- Name (Alert ID)
- Alert_Type__c (Example: Success, Info, Error, Warning) - User selects the type of alert you want to display
- Alert1__c (Alert message to be displayed)

 

-------------------------------------------------------------------------------

 

I created a component to display the alert on a certain page as per the code below:

 

Alert.cmp
-----------------


<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride,lightning:backgroundUtilityItem" access="GLOBAL" controller="AlertController">   

    
<aura:attribute name="html" type="List" />
    
    
<aura:attribute name="showToast" type="boolean" default="false"/>
    
<aura:attribute name="Alert" type="Alert__c" default="{'sobjectType': 'Alert__c',
                         'Tipo_de_Alerta__c': '',
                         'Name': '',
                         'Alerta1__c': ''
                          }"/>
    
    
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    
    
<aura:if isTrue="{!v.showToast}">
    
           <aura:iteration items="{!v.html}" var="lista">        
					<div class="demo-only" style="height: 4rem;">
		
   							 <div class="slds-notify_container slds-is-relative">    
				
        							<div aura:id="alerta" role="status"> 
                                 
                                 <!--  <div id="{!Lista.Name}" role="status">   -->
													<div  class="slds-notify__content">
                            
                                                                <h2 class="slds-text-heading_small ">                
                                                                     <aura:unescapedHtml value="{!lista.Alerta1__c}" />  
                                                                </h2>
                            
                                                    <lightning:buttonIcon iconName="utility:close" variant="bare" alternativeText="Close"
                                                     iconClass="{!v.type == 'warning' ? 'light' : 'dark'}" size="small"
                                                     class="slds-button slds-button_icon slds-notify__close slds-button_icon-inverse"
                                                     onclick="{!c.close}"/>      
    
													</div>
									</div>
							</div>
					</div>
			</aura:iteration>
    
    
    
    
   

</aura:if>
    
    
    
</aura:component>

AlertController.js
-----------------------





({


   doInit : function(component, event, helper)
    {

  var action = component.get( "c.getMsgs" );

         action.setCallback(this, function(response) 
                           {                               
                             
                               var state = response.getState();

                               if(state == 'SUCCESS')
                               {                                   
                                   var alertMsgList = response.getReturnValue();
                                   var lista = [ ];                                  
                                   
                                   
                                   if(alertMsgList.length > 0)
                                   {                                       
                                       component.set("v.showToast", true);                             
                                   }
                                 
                                   
                                   
                                   for(var i = 0; i < alertMsgList.length; i ++) 
                                   {                                       
                                     
                                       /*
                                       var alerta = alertMsgList[ i ].Alerta1__c;
                                       var tipo = alertMsgList[ i ].Tipo_de_Alerta__c;
                                       var titulo = alertMsgList[ i ].Name;                                       
                                       */
                                       
                                      lista.push(alertMsgList[i]);

      						       }
                                   
                                   
                                   component.set("v.html",lista);
                                 
                                   var tipoAlerta = component.find( "alerta" );
                                   
                                   
                              //     var tipoAlerta = document.getElementById("!v.Alert.Name");
                              
                                                                      
                                              $A.util.addClass( tipoAlerta, "slds-notify" );
                                              $A.util.addClass( tipoAlerta, "slds-notify_toast" );  
                                              $A.util.addClass( tipoAlerta, "slds-theme_success" );  
   
                                   
     }
                               
               
                          else {
                                   console.log("Failed with state: " + state);
                               }
                           }); 
        
        
        $A.enqueueAction(action);
        
  
        
    },

   
    
   close: function(cmp, event, helper) 
    {
   $A.util.addClass(cmp.find('alerta'), "slds-hide");
    //  $A.util.addClass(document.getElementById('{!v.lista.Name}'), "slds-hide");
    },
   
   
       
    
})

AlertController.apxc
-------------------------------------




public class AlertController {
    
    
       
    
 @AuraEnabled
    public static List<Alert__c> getMsgs() {
        
        List<Alert__c> lst = new List<Alert__c>();
        lst = [select Tipo_de_Alerta__c, Name, Alert_Style__c,  Alerta1__c from Alert__c where Data_inicial__c <= :system.now() and Data_final__c >= :system.now()];
        return lst;
    }
    

    
}

What happens is that for every alert found, it needs to display it according to its characteristics:
- Type of alert
- Identification of each alert (For each alert, your type configuration and the close button will be checked)
- Alert message: This setting is the only one that is working, need to interact for each alert by formatting your type to receive the appropriate CSS and the close button for it.

In the Controller.js I put the part that configures the CSS and the separate close button just to test its operation, so it works only for one record, I need to put it to work in each interaction and to each of the records that are found .
That's what I can not do, if anyone can help me, I'll be very grateful.
Thank you
Best Answer chosen by Luciano Roberto
Santosh Reddy MaddhuriSantosh Reddy Maddhuri
Hi Luciano,

Please Mark below as best answer if it helps! So others can benefit too.
Here is the modified code including logic for close button.

Component:
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride,lightning:backgroundUtilityItem,force:appHostable,flexipage:availableForAllPageTypes" access="GLOBAL" controller="AlertController"> 
    
    <aura:attribute name="html" type="List" />
    <aura:attribute name="showToast" type="boolean" default="false"/>

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    
     <lightning:card  title="Alerts">
    <div>
	
        <aura:if isTrue="{!v.showToast}">
         <aura:iteration items="{!v.html}" var="lista">
                <div class="slds-notify_container slds-is-relative" id="{! 'divtoHide-'+lista.Name}">
                    <div class="{! 'slds-notify'+ ' ' +'slds-notify_toast'+ ' ' + 'slds-theme_'+''+lista.Alert_Type__c}" role="status">
                     <lightning:icon iconName="{! 'utility:'+''+lista.Alert_Type__c}" alternativeText="Info!" variant="inverse" class="slds-m-right_small"/>   
                     <div class="slds-notify__content">
                        <h2 class="slds-text-heading_small">{!lista.Alert_Message__c}</h2>
                      </div>  
                      <div class="slds-notify__close">
                       <button id="{! lista.Name}" class="slds-button slds-button_icon slds-button_icon-inverse" title="Close" onclick="{!c.closeToast}">
                           <lightning:icon iconName="utility:close" alternativeText="Close" variant="inverse" />   
                       </button>
                      </div>  
                  </div>
	        	</div>
           </aura:iteration>  
        </aura:if>
            
        </div>
    </lightning:card>     
</aura:component>

Controller :
 
({
	doInit : function(component, event, helper) {
        console.log('function loaded...');
		 var action = component.get("c.getMsgs");
        action.setCallback(this, function(response){
            var state = response.getState();
            
         if(state == 'SUCCESS'){
                var alertMsgList = response.getReturnValue();
                var lista = [ ];
             
             if(alertMsgList.length > 0){
                component.set("v.showToast", true); 
             }

            for(var i = 0; i < alertMsgList.length; i ++){
                lista.push(alertMsgList[i]);
            }
         }else{
                
                 console.log("Failed with state: " + state);

            } 
            
                 component.set("v.html",lista);
          
        });
       $A.enqueueAction(action);  
	},
    
    closeToast : function(component, event, helper){
        var whichOne = 'divtoHide-'+event.currentTarget.id;
        var elements = document.getElementById(whichOne);
        $A.util.toggleClass(elements, "slds-hide");
    },

})


Regards,

Santosh​​​​​​​

 

All Answers

Santosh Reddy MaddhuriSantosh Reddy Maddhuri

Hi 
Luciano Roberto,

What you are trying to achieve here? you want to display notifications/alerts at one place.Meaning if you have 4 alert records of different types(info,success,warning,error) at one place or do they have to render as per any conditons. Meanwhile you can look for force:showToast documentation as that might be helpful to start with.

https://developer.salesforce.com/docs/component-library/bundle/force:showToast/documentation


Example  of showtoast

https://webkul.com/blog/forceshowtoast-in-lightning/

Hope this helps!

Regards,

Santosh.

Luciano RobertoLuciano Roberto

Hi Santosh Reddy Maddhuri,

Thanks, but this link you sent is not good for me.


Each alert must be rendered according to the conditions.



For example, the user creates a record through the alert object (which was created for this purpose) by informing the name of the alert, the message that will be displayed, and the type that it wants it to display.

After creating the record, the component I'm creating will check the amount of alerts that were created to store in a list, then read that list and display them as they were created.

 

For example

User created two alert logs:

Name: Alert1
Message: Hi, how are you?
Type: Success
------------------------------------
Name: Alert2
Message: Any error message
Type: error
------------------------------------

Two alerts need to be displayed on the screen, one for success and one for error.

In this snippet of code, it queries the database to see how many alerts there are and to display them (With some comments).

 

doInit : function(component, event, helper)
    {

  var action = component.get( "c.getMsgs" );

         action.setCallback(this, function(response) 
                           {                               
                             
                               var state = response.getState();

                               if(state == 'SUCCESS')
                               {                                   
                                   var alertMsgList = response.getReturnValue();
                                   var lista = [ ];   //       This list will store the queried records and then display them                         
                                   
                                   
                                   if(alertMsgList.length > 0)
                                   {                                       
                                       component.set("v.showToast", true);                             
                                   }
                                 
                                   
                                  
 
                                   for(var i = 0; i < alertMsgList.length; i ++) 
                                   {   

  lista.push(alertMsgList[i]);  //Stores records to display each of them

      			            }
                                   
                                   
                                   component.set("v.html",lista); // Sends each list alert to the view
                                 
                                                                      
                                       
   
                                   
     }
                               
               
                          else {
                                   console.log("Failed with state: " + state);
                               }
                           }); 
        
        
        $A.enqueueAction(action);
        
  
        
    },


I am able to display only the alert messages, there are still two settings that need to be formatted in the alert, its type and a close button.

For example, if the alert is of success type, you must receive the following configuration:

 var tipoAlerta = component.find( "alerta" );

​​​​​​​$A.util.addClass( tipoAlerta, "slds-notify" );
$A.util.addClass( tipoAlerta, "slds-notify_toast" );  
$A.util.addClass( tipoAlerta, "slds-theme_success" ); 

if is of warning

$A.util.addClass( tipoAlerta, "slds-notify" );
$A.util.addClass( tipoAlerta, "slds-notify_toast" );  
$A.util.addClass( tipoAlerta, "slds-theme_warning" ); 

if is of error

​​​​​​​$A.util.addClass( tipoAlerta, "slds-notify" );
$A.util.addClass( tipoAlerta, "slds-notify_toast" );  
$A.util.addClass( tipoAlerta, "slds-theme_error" ); 

...and so on..


I am using AURA ITERATION to display all the created alerts, but it is currently static with the <div aura:id="alerta" role="status"> , it needs to be dynamic in order to format each one, that's what I can not do.



<aura:if isTrue="{!v.showToast}">
    
           <aura:iteration items="{!v.html}" var="lista">        
					<div class="demo-only" style="height: 4rem;">
		
   							 <div class="slds-notify_container slds-is-relative">    
				
<div aura:id="alerta" role="status">   <!-- This is the alert ID and it is static ("alert"), it needs to be dynamic. Each alert must have yours in order to pass the formatting of each one  -->
                                                                  
													<div  class="slds-notify__content">
                            
                                                                <h2 class="slds-text-heading_small ">                
                                                                     <aura:unescapedHtml value="{!lista.Alerta1__c}" />  
                                                                </h2>
                            
                                                    <lightning:buttonIcon iconName="utility:close" variant="bare" alternativeText="Close"
                                                     iconClass="{!v.type == 'warning' ? 'light' : 'dark'}" size="small"
                                                     class="slds-button slds-button_icon slds-notify__close slds-button_icon-inverse"
                                                     onclick="{!c.close}"/>      
    
													</div>
									</div>
							</div>
					</div>
			</aura:iteration>
</aura:if>
 

The alert is being displayed like this, with no formatting

User-added image

Santosh Reddy MaddhuriSantosh Reddy Maddhuri
Hi Luciano Roberto,

Here is the fixed code and screenshot of it.Hope this helps!

NOTE : 1. I have created object in my instance to replicate your object but with less fields
2.Alert Type : Change api names of picklist values from Uppercase start letter to all lower case : Example screenshot. This way values flow dynamically on to component.

User-added image

Sample Alert Records:

User-added image


Component :
 
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride,lightning:backgroundUtilityItem,
                            force:appHostable,flexipage:availableForAllPageTypes" access="GLOBAL" controller="AlertController"> 
    
    <aura:attribute name="html" type="List" />
    <aura:attribute name="showToast" type="boolean" default="false"/>

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    
     <lightning:card  title="Alerts">
    <div>
	
        <aura:if isTrue="{!v.showToast}">
         <aura:iteration items="{!v.html}" var="lista">
                <div class="slds-notify_container slds-is-relative">
                    <div class="{! 'slds-notify'+ ' ' +'slds-notify_toast'+ ' ' + 'slds-theme_'+''+Lowercase(lista.Alert_Type__c)}" role="status">
                     <lightning:icon iconName="{! 'utility:'+''+lista.Alert_Type__c}" alternativeText="Info!" variant="inverse" class="slds-m-right_small"/>   
                     <div class="slds-notify__content">
                        <h2 class="slds-text-heading_small">{!lista.Alert_Message__c}</h2>
                      </div>  
                      <div class="slds-notify__close">
                       <button class="slds-button slds-button_icon slds-button_icon-inverse" title="Close">
                           <lightning:icon iconName="utility:close" alternativeText="Close" variant="inverse" />   
                       </button>
                      </div>  
                  </div>
	        	</div>
           </aura:iteration>  
        </aura:if>
            
        </div>
    </lightning:card>     
</aura:component>

Controller:
 
({
	doInit : function(component, event, helper) {
        console.log('function loaded...');
		 var action = component.get("c.getMsgs");
        action.setCallback(this, function(response){
            var state = response.getState();
            
         if(state == 'SUCCESS'){
                var alertMsgList = response.getReturnValue();
                var lista = [ ];
             
             if(alertMsgList.length > 0){
                component.set("v.showToast", true); 
             }

            for(var i = 0; i < alertMsgList.length; i ++){
                lista.push(alertMsgList[i]);
            }
         }else{
                
                 console.log("Failed with state: " + state);

            } 
            
                 component.set("v.html",lista);
          
        });
       $A.enqueueAction(action);  
	},
    

})

Apex Class :
 
public class AlertController {
    
    
       
    
 @AuraEnabled
    public static List<Alert__c> getMsgs() {
        
        List<Alert__c> lst = new List<Alert__c>();
        lst = [select Alert_Message__c, Name, Alert_Type__c from Alert__c ];
        return lst;
    }
    

    
}

Screenshot

User-added image

Please mark this as the best answer if it works, so others can benefit too.

Regards,
Santosh.​​​​​​​
Santosh Reddy MaddhuriSantosh Reddy Maddhuri
Change line 15 on component  to :

  <div class="{! 'slds-notify'+ ' ' +'slds-notify_toast'+ ' ' + 'slds-theme_'+''+lista.Alert_Type__c}" role="status">
Luciano RobertoLuciano Roberto

Thank you very much, Santosh Reddy Maddhuri. You do not know how much you helped me.
Just missing a detail to close with golden key, how to make the close button work ...

Santosh Reddy MaddhuriSantosh Reddy Maddhuri
Hi Luciano,

Please Mark below as best answer if it helps! So others can benefit too.
Here is the modified code including logic for close button.

Component:
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride,lightning:backgroundUtilityItem,force:appHostable,flexipage:availableForAllPageTypes" access="GLOBAL" controller="AlertController"> 
    
    <aura:attribute name="html" type="List" />
    <aura:attribute name="showToast" type="boolean" default="false"/>

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    
     <lightning:card  title="Alerts">
    <div>
	
        <aura:if isTrue="{!v.showToast}">
         <aura:iteration items="{!v.html}" var="lista">
                <div class="slds-notify_container slds-is-relative" id="{! 'divtoHide-'+lista.Name}">
                    <div class="{! 'slds-notify'+ ' ' +'slds-notify_toast'+ ' ' + 'slds-theme_'+''+lista.Alert_Type__c}" role="status">
                     <lightning:icon iconName="{! 'utility:'+''+lista.Alert_Type__c}" alternativeText="Info!" variant="inverse" class="slds-m-right_small"/>   
                     <div class="slds-notify__content">
                        <h2 class="slds-text-heading_small">{!lista.Alert_Message__c}</h2>
                      </div>  
                      <div class="slds-notify__close">
                       <button id="{! lista.Name}" class="slds-button slds-button_icon slds-button_icon-inverse" title="Close" onclick="{!c.closeToast}">
                           <lightning:icon iconName="utility:close" alternativeText="Close" variant="inverse" />   
                       </button>
                      </div>  
                  </div>
	        	</div>
           </aura:iteration>  
        </aura:if>
            
        </div>
    </lightning:card>     
</aura:component>

Controller :
 
({
	doInit : function(component, event, helper) {
        console.log('function loaded...');
		 var action = component.get("c.getMsgs");
        action.setCallback(this, function(response){
            var state = response.getState();
            
         if(state == 'SUCCESS'){
                var alertMsgList = response.getReturnValue();
                var lista = [ ];
             
             if(alertMsgList.length > 0){
                component.set("v.showToast", true); 
             }

            for(var i = 0; i < alertMsgList.length; i ++){
                lista.push(alertMsgList[i]);
            }
         }else{
                
                 console.log("Failed with state: " + state);

            } 
            
                 component.set("v.html",lista);
          
        });
       $A.enqueueAction(action);  
	},
    
    closeToast : function(component, event, helper){
        var whichOne = 'divtoHide-'+event.currentTarget.id;
        var elements = document.getElementById(whichOne);
        $A.util.toggleClass(elements, "slds-hide");
    },

})


Regards,

Santosh​​​​​​​

 

This was selected as the best answer
Luciano RobertoLuciano Roberto

Santosh,
​​​​​​​
You are the best !!!

Thank you very, very much.

Worked perfectly!