Validation Rule Requiring Lead Fields Prior to Conversion

In this post I am writing a validation rule that requires all of these fields prior to Lead conversion.

Need is a checkbox, Languages and propsepct role are picklists, Notes and SDR are text…

Below is the successful Formula that works for the above criteria:

Also, If the  Notes__c a Rich Text area field, then you need to use this:

 

If the above don’t work either, then check the following:
This Lead Settings should be checked in order for the Validation Rule to Fire.
Hope this information helps you!
– Chandra V [01/12/2019]

 

EINSTEIN ANALYTICS

In this Post, I would like to get the most important points on the Einstein Analytics to this Blog, through which one can understand it’s significance in improving the Business.

  1. Work with a platform you can trust
  2. Save on expenses
  3. Get set up quickly
  4. Cut out the fluff
  5. Customize your solution
  6. Enjoy built-in support
  7. Integrate your data
  8. Integrate with the entire Salesforce ecosystem
  9. Easily explore customer data from every source
  10. Bring your people together
  11. Unify your goals
  12. Collaborate from the dashboard
  13. Generate presentation-worthy visuals
  14. Be a part of the conversation
  15. Put it all into context
  16. Never be out of reach
  17. See team performance
  18. Access relevant KPIs
  19. Track call-center efficiency
  20. Chart changes
  21. Become a better coach
  22. Empower your teams to analyze themselves
  23. Eliminate the holes in your campaigns
  24. See the big picture
  25. Eliminate borders
  26. Find the devil in the details
  27. Predict the future
  28. Reduce churn
  29. Focus on the right leads
  30. Evaluate your lead sources
  31. Recognize your biggest wins
  32. Optimize the customer experience
  33. Dive deeper
  34. Present the right message
  35. Be your own data analyst
  36. Take instant action
  37. Make B2B marketing your speciality
  38. Understand the brand experience
  39. Set your priorities
  40. Evaluate your accounts
  41. Connect with your agents
  42. Review your service backlog
  43. Integrate with third-party applications
  44. Go mobile
  45. Optimize your pipelines
  46. Automate your analysis efforts
  47. Enjoy the highest level of data security
  48. Push the limits
  49. Gain deeper visibility into your business
  50. Keep up the pace                                                                                                                                                                                         – Sumanth A[01/04/19]

Custom Data Table With Pagination And Checkbox Functionality In Salesforce Lightning

In this post I am  going to show how we can create custom lightning data table with client side JavaScript pagination buttons and row level checkbox functionality using salesforce lightning component. In this component we’ll also persist checkbox checked state on pagination.

 
Apex Controller : dataTableCtrl
public class dataTableCtrl{
    @AuraEnabled
    public static List<accountListWrapper> fetchAccountWrapper(){     
        List<accountListWrapper> lstaccountListWrapper = new List<accountListWrapper>();
        // query account records and create 'accountListWrapper' class instance for each record. 
        for(Account acc : [Select id,Name,Type,Phone
                           From Account
                           Limit 1000]){
                               // by default checkbox should be false 
                               lstaccountListWrapper.add(new accountListWrapper(false,acc));
                           }
        // return the 'lstaccountListWrapper' list 
        return lstaccountListWrapper;
    }
    
    /* wrapper class */  
    public class accountListWrapper {
        @AuraEnabled public boolean isChecked {get;set;}
        @AuraEnabled public  account objAccount{get;set;}
        public accountListWrapper(boolean isChecked, account objAccount){
            this.isChecked = isChecked;
            this.objAccount = objAccount;
        }
    }
}
 
Lightning Component
 
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction"
access="global"
controller="dataTableCtrl">
<!-- call doInit method on component load -->
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<!-- aura attributes to store data/values -->
<aura:attribute name="listOfAllAccounts" type="list"/>
<aura:attribute name="PaginationList" type="list"/>
<aura:attribute name="selectedCount" type="integer" default="0"
description="selected Records Count"/>
<aura:attribute name="startPage" type="Integer" />
<aura:attribute name="endPage" type="Integer"/>
<aura:attribute name="totalRecordsCount" type="Integer"/>
<aura:attribute name="pageSize" type="Integer" default="4"
description="number of records to be display on per page"/>
<aura:attribute name="currentPage" type="integer" default="1"/>
<aura:attribute name="totalPagesCount" type="integer"/>
<aura:attribute name="bNoRecordsFound" type="boolean"/>
<aura:if isTrue="{!v.bNoRecordsFound}">
<!--display error message if there is no records available -->
<div class="slds-notify slds-notify_alert slds-theme_alert-texture slds-theme_info" role="alert">
<span class="slds-assistive-text">error</span>
<h2>No record found.</h2>
</div>
<aura:set attribute="else">
<!-- lightning:button to get selected rows data -->
<div class="slds-clearfix slds-m-around_small">
<div class="slds-clearfix">
<div class="slds-float_right">
<lightning:button variant="destructive"
label="Get Selected Records"
onclick="{! c.getSelectedRecords }"
disabled="{!v.selectedCount == 0}"/>
</div>
</div>
</div>
<!-- display total record and selected record count -->
<p class="slds-m-around_small">
<span class="slds-badge slds-badge_lightest" style="display:inline-block">
Total Records : {!v.selectedCount > 0 ? v.selectedCount + '/' : ''} {!v.totalRecordsCount} 
</span>
</p>
 
<!-- data table start-->
<table class="slds-table slds-table_bordered slds-table_cell-buffer">
<thead>
<tr class="slds-text-title_caps">
<!--header checkbox for select all-->
<th style="width:3.25rem;" class="slds-text-align_right">
<div class="slds-form-element">
<div class="slds-form-element__control">
<label class="slds-checkbox">
<ui:inputCheckbox disabled="{!v.totalRecordsCount == 0}"
aura:id="selectAllId"
change="{!c.selectAllCheckbox}"/>
<span class="slds-checkbox_faux"></span>
<span class="slds-form-element__label"></span>
</label>
</div>
</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Name">Name</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Phone">Phone</div>
</th>
<th scope="col">
<div class="slds-truncate" title="Type">Type</div>
</th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.PaginationList}" var="obj">
<tr>
<th scope="row" class="slds-text-align_right" style="width:3.25rem;">
<div class="slds-form-element">
<div class="slds-form-element__control">
<label class="slds-checkbox">
<ui:inputCheckbox text="{!obj.objAccount.Id}"
value="{!obj.isChecked}"
change="{!c.checkboxSelect}"/>
<span class="slds-checkbox_faux"></span>
<span class="slds-form-element__label text"></span>
</label>
</div>
</div>
</th>
<th scope="row">
<div class="slds-truncate" title="{!obj.objAccount.Name}">
                                    {!obj.objAccount.Name}
</div>
</th>
<th scope="row">
<div class="slds-truncate" title="{!obj.objAccount.Phone}">
<lightning:formattedPhone value="{!obj.objAccount.Phone}"/>
</div>
</th>
<th scope="row">
<div class="slds-truncate" title="{!obj.objAccount.Type}">
                                    {!obj.objAccount.Type}
</div>
</th>
</tr>
</aura:iteration>
</tbody>
</table>
<!-- DataTable End -->
<br/>
<!--  Pagination Buttons Start -->
<div class="slds-align_absolute-center">
<lightning:button label="Previous"
disabled="{!v.startPage == 0}"
onclick="{!c.navigation}"
variant="brand"
iconName="utility:back"
name="previous"/>
<span class="slds-badge slds-badge_lightest"
style="margin-right: 10px;margin-left: 10px;">
                    Page {!v.currentPage} out of {!v.totalPagesCount}
</span>
<lightning:button label="Next"
disabled="{!(v.endPage + 1) >= v.totalRecordsCount}"
onclick="{!c.navigation}"
variant="brand"
iconName="utility:forward"
iconPosition="right"
name="next"/>
</div>
<!--  Pagination Buttons End -->
</aura:set>
</aura:if>
</aura:component>
 
Java Script Controller
 
({
doInit: function(component, event, helper) {
helper.doInitHelper(component, event);
},
 
/* javaScript function for pagination */
navigation: function(component, event, helper) {
var sObjectList = component.get("v.listOfAllAccounts");
var end = component.get("v.endPage");
var start = component.get("v.startPage");
var pageSize = component.get("v.pageSize");
var whichBtn = event.getSource().get("v.name");
// check if whichBtn value is 'next' then call 'next' helper method
if (whichBtn == 'next') {
component.set("v.currentPage", component.get("v.currentPage") + 1);
helper.next(component, event, sObjectList, end, start, pageSize);
}
// check if whichBtn value is 'previous' then call 'previous' helper method
else if (whichBtn == 'previous') {
component.set("v.currentPage", component.get("v.currentPage") - 1);
helper.previous(component, event, sObjectList, end, start, pageSize);
}
},
 
selectAllCheckbox: function(component, event, helper) {
var selectedHeaderCheck = event.getSource().get("v.value");
var updatedAllRecords = [];
var updatedPaginationList = [];
var listOfAllAccounts = component.get("v.listOfAllAccounts");
var PaginationList = component.get("v.PaginationList");
// play a for loop on all records list 
for (var i = 0; i < listOfAllAccounts.length; i++) {
// check if header checkbox is 'true' then update all checkbox with true and update selected records count
// else update all records with false and set selectedCount with 0  
if (selectedHeaderCheck == true) {
listOfAllAccounts[i].isChecked = true;
component.set("v.selectedCount", listOfAllAccounts.length);
} else {
listOfAllAccounts[i].isChecked = false;
component.set("v.selectedCount", 0);
}
updatedAllRecords.push(listOfAllAccounts[i]);
}
// update the checkbox for 'PaginationList' based on header checbox 
for (var i = 0; i < PaginationList.length; i++) {
if (selectedHeaderCheck == true) {
PaginationList[i].isChecked = true;
} else {
PaginationList[i].isChecked = false;
}
updatedPaginationList.push(PaginationList[i]);
}
component.set("v.listOfAllAccounts", updatedAllRecords);
component.set("v.PaginationList", updatedPaginationList);
},
 
checkboxSelect: function(component, event, helper) {
// on each checkbox selection update the selected record count 
var selectedRec = event.getSource().get("v.value");
var getSelectedNumber = component.get("v.selectedCount");
if (selectedRec == true) {
getSelectedNumber++;
} else {
getSelectedNumber--;
component.find("selectAllId").set("v.value", false);
}
component.set("v.selectedCount", getSelectedNumber);
// if all checkboxes are checked then set header checkbox with true   
if (getSelectedNumber == component.get("v.totalRecordsCount")) {
component.find("selectAllId").set("v.value", true);
}
},
 
getSelectedRecords: function(component, event, helper) {
var allRecords = component.get("v.listOfAllAccounts");
var selectedRecords = [];
for (var i = 0; i < allRecords.length; i++) {
if (allRecords[i].isChecked) {
selectedRecords.push(allRecords[i].objAccount);
}
}
alert(JSON.stringify(selectedRecords));
}
})
 
Java Script Helper
 
({
/* doInitHelper funcation to fetch all records, and set attributes value on component load */
doInitHelper : function(component,event){
var action = component.get("c.fetchAccountWrapper");
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS"){
var oRes = response.getReturnValue();
if(oRes.length > 0){
component.set('v.listOfAllAccounts', oRes);
var pageSize = component.get("v.pageSize");
var totalRecordsList = oRes;
var totalLength = totalRecordsList.length ;
component.set("v.totalRecordsCount", totalLength);
component.set("v.startPage",0);
component.set("v.endPage",pageSize-1);
var PaginationLst = [];
for(var i=0; i < pageSize; i++){
if(component.get("v.listOfAllAccounts").length > i){
PaginationLst.push(oRes[i]);
}
}
component.set('v.PaginationList', PaginationLst);
component.set("v.selectedCount" , 0);
//use Math.ceil() to Round a number upward to its nearest integer
component.set("v.totalPagesCount", Math.ceil(totalLength / pageSize));
}else{
// if there is no records then display message
component.set("v.bNoRecordsFound" , true);
}
}
else{
alert('Error...');
}
});
$A.enqueueAction(action);
},
// navigate to next pagination record set   
next : function(component,event,sObjectList,end,start,pageSize){
var Paginationlist = [];
var counter = 0;
for(var i = end + 1; i < end + pageSize + 1; i++){
if(sObjectList.length > i){
if(component.find("selectAllId").get("v.value")){
Paginationlist.push(sObjectList[i]);
}else{
Paginationlist.push(sObjectList[i]);
}
}
counter ++ ;
}
start = start + counter;
end = end + counter;
component.set("v.startPage",start);
component.set("v.endPage",end);
component.set('v.PaginationList', Paginationlist);
},
// navigate to previous pagination record set   
previous : function(component,event,sObjectList,end,start,pageSize){
var Paginationlist = [];
var counter = 0;
for(var i= start-pageSize; i < start ; i++){
if(i > -1){
if(component.find("selectAllId").get("v.value")){
Paginationlist.push(sObjectList[i]);
}else{
Paginationlist.push(sObjectList[i]);
}
counter ++;
}else{
start++;
}
}
start = start - counter;
end = end - counter;
component.set("v.startPage",start);
component.set("v.endPage",end);
component.set('v.PaginationList', Paginationlist);
},
})

-Ranjith T [12/19/18]

Salesforce lead Queues

In Salesforce, Queues think about the board and relationship of records in Leads, Cases, and custom things. Lead Queues are particularly helpful in light of the fact that they license you to channel a social occasion Leads into a line reliant on a particular principles whereby customers in that line can ensure obligation regarding Leads. For example, you can make a Lead Queue to fitting as of late made Leads or those got from web by region/a territory (West Coast, North Pacific…etc) Today, I’ll be giving an associate on how with make a Leads Queue.

CREATION OF  TERRITORIES OR REGIONS:

First, we’re going to create a queue for each region.

To get started, go to Setup> Administration Setup> Manage Users> Queues and click New.

Name the Queue and on the other hand, you can assign an email address unequivocal for the line; customers in that line will get invigorates on exercises.

Next, pick the thing you have to make the line in.

Next, assign users to the queue. Alternatively, you can assign a Group of users to a queue. Then click Save.

ASSIGNING RULES FOR LEAD QUEUES

Now that you’ve built the queue, it’s time to create rules to automatically assign users to the appropriate region/territory queue. Go to Setup> Customize> Leads> Assigning Rules and click “New”. In Assignment Rules, you can prioritize the order of rules.Assigning Rules will run on an ascending order.

First, set the order of the rule.

Enter the criteria on which you want the Assignment Rule to apply
If you have multiple rules and depending on the logic, you can modify the logic of the rules right under the list.

Finally, enter the name of the queue you want the records with the above criteria to go to. click Save.

And now, users assigned to the queue can have a list view of all records in that queue where they can assign ownership accordingly. Only those users and users of higher hierarchy will have access to that list view.

Chandra V [11/26/2018]

Force Refresh on Lightning Component

To Force Refresh on a Lightning Component this code can be used:

refresh : function(component, event, helper) {
var action = cmp.get(‘c.myController’;);
action.setCallback(cmp,
function(response) {
var state = response.getState();
if (state === ‘SUCCESS’){
$A.get(‘e.force:refreshView’;).fire();
} else {
//do something
}
}
);
$A.enqueueAction(action);
}

Reloads the view.

To refresh a view, run $A.get(“e.force:refreshView”;).fire();, which reloads all data for the view.

This example refreshes the view after an action is successfully completed

Yeshas [11/10/18]

Field History Tracking on Custom Components

There is a limitation on the Field Tracking on the Quote Standard object in Salesforce.

This functionality is used when a custom application is built and want to track the history of the fields that are created
on the component.

In this scenario, I am tracking the Field History based on these criteria:

Date / Field / Original value / New Value / Type / Modified By

In the below scenario, Tracking the Custom Component Fields Based on two objects – Quote and Quote Line Item.

Lightning Component for Field History Tracking:

<aura:component controller=”QuoteAndQuoteLineItemHistory” implements=”force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction” access=”global” >
<!– HANDLERS –>
<aura:handler name=”init” action=”{!c.doInit}” value=”{!this}” />
<!– ATTRIBUTES –>
<aura:attribute name=”componentHistory” type=”List” />
<aura:attribute name=”componentHistoryFinalList” type=”List” />
<aura:attribute name=”searchText” type=”String”/>
<aura:attribute name=”headers” type=”List”/>
<aura:attribute type=”Boolean” name=”sortType” />

<aura:attribute name=”recordId” type=”Id” />
<aura:attribute name=”sortedBy” type=”String” default=”Name”/>
<aura:attribute name=”sortedDirection” type=”String” default=”asc”/>
<div class=”slds”>
<div class=”slds-grid slds-gutters”>
<div class=”slds-col slds-size_9-of-12″></div>
<div class=”slds-col slds-size_3-of-12″>
<lightning:input type=”text” name=”searchInput” onkeyup=”{!c.filterSelection}” value=”{!v.searchText}” aura:id=”searchInput” label=”Type here to search” />
<br/>
</div>
</div>

<lightning:datatable data=”{!v.componentHistory}”
columns=”{!v.headers}”
keyField=”Id”
hideCheckboxColumn=”true”
onsort=”{!c.updateColumnSorting}”
sortedBy=”{!v.sortedBy}”
sortedDirection=”{!v.sortedDirection}”/>
</div>
</aura:component>

This component also has the functionality of Sorting and Search feature.

Please comment and reach out for the Apex Class and related java scripts.

Chandra V [11/3/2018]

HTML textarea element that can be editable or read-only

Input Text Area

HTML textarea element that can be editable or read-only. Scroll bars may not appear on Chrome browsers in Android devices, but you can select focus in the textarea to activate scrolling.

Component

<aura:component>
<ui:inputTextArea aura:id=”comments” label=”Comments” value=”My comments” rows=”5″/>
<ui:button class=”btn” label=”Submit” press=”{!c.setOutput}”/>

<div aura:id=”msg” class=”hide”>
You entered: <ui:outputTextArea aura:id=”oTextarea” value=””/>
</div>
</aura:component>

Controller :

({
setOutput : function(component, event, helper) {
var cmpMsg = component.find(“msg”);
$A.util.removeClass(cmpMsg, ‘hide’);

var comments = component.find(“comments”).get(“v.value”);
var oTextarea = component.find(“oTextarea”);
oTextarea.set(“v.value”, comments);
}
})

CSS :

.THIS.hide {
display: none;
}

.THIS.btn {
margin-bottom: 10px;
}

.THIS label.uiLabel {
padding-right: 12px;
}

.THIS textarea {
border: 1px solid #dce4ec;
border-radius: 4px;
width: 200px;
}

– Yeshas [10/30/2018]

Adding RichText area field in a lightning component

How to add a RichText area field in a lightning component without getting FIELD INTEGRITY EXCEPTION
You can add a change handler event which basically does that, tracks changes on specified values:

Component

<aura:component implements=”forceCommunity:availableForAllPageTypes” access=”global” >
<aura:attribute name=”myVal” type=”String” />
<aura:handler name=”change” value=”{!v.myVal}” action=”{!c.handleValueChange}”/>

<lightning:inputRichText value=”{!v.myVal}” aura:id=”grr”/>
</aura:component>

controller.js

handleValueChange:function(cmp){
console.log(“value: ” + cmp.get(‘v.myVal’));
}

CSS :

.THIS .Resizable {
border: 2px solid;
padding: 20px;
width: 300px;
resize: both;
overflow: auto;
}

– Yeshas [10/30/2018]

How to use Named credentials for Callouts (Integrations)

In the call outs or Integrations that we do from Salesforce to External Systems, we should pass the Endpoint URL and Password in the Header to hit the External System.

Using the Named Credentials we can Put these Endpoint URL and Password in a Label and can expose that label in the code.

Below are the Steps for Navigating to Named credentials:

Setup -> Type Named Credentials -> Setup the Named Credentials with all the details

 

This is considered as one of the best practices (Not exposing the URL and Password in the code)

Sumanth A [10/25/18]