Salesforce Cookies #11 ( Salesforce Admin Special )

Is there a way to mass-check Checkboxes when updating a Profile’s Object’s Field-Level Security?

Of course, there is. You can do it through your browser’s console. You just need the following Javascript code snippet which will do the job for you.

For the Edit Permission
var checkboxes = document.querySelectorAll(".displayedCol input");
for (var i = 0; i < checkboxes.length; i++) {
   checkboxes[i].checked=true;
   handleEditClick(checkboxes[i]);
}
For the Read Permission Only
var checkboxes = document.querySelectorAll(".readonlyCol input");
for (var i = 0; i < checkboxes.length; i++) {
   checkboxes[i].checked=true;
   handleEditClick(checkboxes[i]);
}

Running JS code snippet in the Google Chrome for updating the field-level permissions

  1. First, navigate to the Field-Level security page for profile and click on Edit button so you can perform the check and uncheck
  2. Now from the Chrome menu > More Tools > Select ‘Developer Tools’ and Click on the Console tab / Press Ctrl+Shift+J.
  3. Copy and Past the above JS code in the console editor and hit the return key.
  4. Save the changes

20180328-122619_capture

Salesforce Cookies #10

Creating a dynamic SOQL which includes all the fields

I have seen this question several times on developer forums and I thought it could be another addition to Salesforce cookies. If you are wondering how can you query all the fields of an object then you can use the following code snippet.

The above code snippet using describe calls to get all the fields and then created a dynamic SOQL query to get all the field values.

This is quite similar to SQL query which uses wildcard characters – SELECT * FROM Table.

Salesforce Cookies #9

Populating merge fields in Salesforce Email Template without sending the email / Preview Email Template

Recently, I faced a challenge while working on a small project in which I had to send email through apex using email templates. I am calling it a challenge because of the problem I faced and I am sharing the solution/workaround I found for this.

Problem – The Email template was using custom fields of the Campaign Member object and whenever I was sending email to Campaign Member ( Lead ), those custom fields were not populating. I tried to set the WhatId to CampaignMember record Id but were getting an error in Messaging.sendEmail method. Unfortunately, I couldn’t use workflow/process builder as email’s from address had to be dynamically set based on some criteria.

Solution –  Used the renderEmailTemplate method of Messaging class and then set the merged body of the result as HtmlBody of the SingleEmailMessage object. Here didn’t get any error when I passed the campaign member record id as whatId.

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String htmlBody = '';
EmailTemplate et = [SELECT Id, Subject, HtmlValue FROM EmailTemplate Where DeveloperName = 'Sample_Email_Template'];
email = Messaging.renderStoredEmailTemplate(et.Id, cm.LeadId, cm.Id);
mail.setTargetObjectId( cm.LeadId );
mail.setOrgWideEmailAddressId( orgWideEmailAddressId );
mail.setSaveAsActivity(false);

The above-mentioned approach can be used in many scenarios like

  1. If you want to preview Email Template content after populating all the merge field values.
  2. Where you can’t set the WhatId of the record directly for SingleEmailMessage object to render merge fields which are used in the email template.
  3. You want to send email to the user and can’t set the TargetObjectId field of the SingleEmailMessage object along with WhatId.
  4. Messaging.renderStoredEmailTemplate method takes 3 parameters, email template Id is the required one.

There are other variants of this method in Messaging class which you can found useful in your use case. You can get the rendered merge field with the help of GetHtmlBody() method of the SingleEmailMessage class from the returned object.

Resource –

Messaging Class

 

Salesforce Cookies #8

How to use namespace in managed lightning components

If you are working on a lightning component and it’s going to be a part of a managed package then you need to take care of namespace in client side JS code if you are accessing any custom field. This can be handled in various ways but I found one very quick way to handle this. Using wrapper could be a best way but it’s time consuming so you can use the following way.

Get the namesapce from server side controller and use that in the lightning components.

NamespaceDemoComp.cmp

NamespaceDemoCompController.cls

NamespaceDemoCompController.js

NamespaceDemoCompHelper.js

So, you can see in the above example that using namespace in JS code can save lot of time as compared to wrapper classes. Expense__c is a custom object and this code will take care of the namespace automatically based on the running environment. If there is a namespace then it will be added as suffix with field’s API names in JS code.

Happy coding 🙂

Salesforce Cookies #7

Untitled

Calling a child lightning component method from the parent lightning component

When we have multiple nested components then we may run into a scenario in which our parent lightning component is supposed to call a method of its child component. This is a very common use case.


simplifies the code needed for a parent component to call a method on a child component that it contains

The lightning component framework has  which simplifies the code needed for a parent component to call a method on a child component that it contains. Following example states pretty everything you want to know about it.

Declare the method defination and it’s parameters in child component as explained below.

<aura:method name="handleShowHidePopupEvent" action="{!c.handleShowHidePopupEventAction}" description="Method to show or hide the popup from a button on the parent component">
    <aura:attribute name="showPopup" type="Boolean" default="true"/>
</aura:method>

Create a handler method in the client side controller of the same child component

({
   handleShowHidePopupEventAction : function(cmp, event) {
     var params = event.getParam('arguments');
     if (params) {
       var showPopup = params.showPopup;
       if(showPopup) {
         var cmpTarget = cmp.find('popupParentDiv');
         $A.util.removeClass(cmpTarget, 'slds-hide');
       } else {
         var cmpTarget = cmp.find('popupParentDiv');
         $A.util.addClass(cmpTarget, 'slds-hide');
       }
     }
   }
})

Above code snippet is toggling a parent div of the popup (model). You can also write any specific logic here which you just want to have in the child component only.

Calling method from the parent component – To close the popup after executing the save button logic or cancel button logic

<c:editRecordComponent aura:id="editRecordCmp"/>
<button class="slds-button" type="button" onclick="{!c.saveRecord}"> Save & Close </button>
<button class="slds-button" type="button" onclick="{!c.cancel}"> Cancel </button></pre>

Method in parent component controller

({
  cancel : function(cmp, helper, event){

    var editRecordCmp = component.find("editRecordCmp");
    editRecordCmp.handleShowHidePopupEvent( false );
  }
})

can also return a value once the execution has been completed.

To read more about, please check aura:method in Lightning Components Developer Guide.

Happy coding 🙂

Salesforce Cookies #6

Adding Loading Icon on the page for an AJAX Request ( ActionFunction, CommandButton)

It’s always good to add a loading icon on the page when you are processing something on the server side (calling an apex method ) so a user can understand that something is running in the background. Following code snippet can be used along with your apex:actionFunction or apex:commandButton.

In Classic

<apex:actionStatus id="actionStatus">
  <apex:facet name="start" >
    <img src="/img/loading.gif" />
  </apex:facet>
</apex:actionStatus>

In Lightning Experience

<apex:actionStatus id="actionStatus">
  <apex:facet name="start" >
    <div class="slds-spinner_container">
      <div class="slds-spinner--brand slds-spinner slds-spinner--small" aria-hidden="false" role="alert">
        <div class="slds-spinner__dot-a"></div>
        <div class="slds-spinner__dot-b"></div>
      </div>
    </div>
  </apex:facet>
</apex:actionStatus>

Using ActionStatus in CommandButton

<apex:commandButton value="Save" action="{!Save}" status="actionStatus"/>

Happy Coding 🙂

Salesforce Cookies#5

Uploading Attachment from Non-Salesforce Users ( Site or Guest Users) through Force.com sites

I came across a question on Trailblazers community where someone asked for a way to upload an attachment to a record and it should be accessible by non-salesforce users. I won’t go into much detail about that and will focus on providing the solution.

So, you just have to follow the below-mentioned steps to make it work for you.

  1. Setup a Force.com site if you haven’t already. You can get more details about this from this link.
  2. Create a VF page which lets an external user upload an attachment to Salesforce record.
  3. Add the page ( created in 2nd step) to the Site created in 1st step. Find more details here.

Visualforce page for Upload Attachment

You just need a VF page and here is the code gist which you can utilize and update as per your need.

Upload Attachment through Force.com sites

Happy coding 🙂

 

Salesforce Cookies #4

Never store record’s Id as a String (Variable type) if you are comparing Ids in your Apex code

If you are writing apex code then make sure that you are treating Ids’ carefully.  You should emphasize on declaring your variables of Id-type instead of String since storing record Id in a variable which type is Id will do the 15-character Id to 18-character Id conversion. Let’s take an example.

Code uses String type variable for holding record Ids
Map<String, Opportunity> mapOpportunities = new Map<String, Opportunity>();
mapOpportunities.put('006w000000tVvtt', Opp);
006w000000tVvtt - 15_Character_Opp_Id  

String oppRecordId = '006w000000tVvttAAG';
mapOpportunities.containsKey( oppRecordId ); // Will return False
006w000000tVvttAAG - 18_Character_Opp_Id

// Same as above 
String character_15_id = '006w000000tVvtt';
String character_18_id = '006w000000tVvttAAG';
character_15_id == character_18_id  // return false
Code uses Id type variable for holding record Ids
Map<Id, Opportunity> mapOpportunities = new Map<Id, Opportunity>();
mapOpportunities.put('006w000000tVvtt', Opp);
006w000000tVvtt - 15_Character_Opp_Id  
Id oppRecordId = '006w000000tVvttAAG';
// Performing containsKey operation will give you true 
// since declaring the map key as Id has done the required ID's conversion
mapOpportunities.containsKey( oppRecordId ); // Will return True
006w000000tVvttAAG - 18_Character_Opp_Id

// Same as above 
Id character_15_id = '006w000000tVvtt';
Id character_18_id = '006w000000tVvttAAG';
character_15_id == character_18_id // return true

Declaring such variables as Id will also help you to deal with invalid Ids. Happy coding!! 🙂

Are you looking for a way to open a lightning component in a new tab/window on detail page button click?

While working on a lightning component development, I found that there is no standard way to open a lighting component in a new tab. You can find the same problem being asked on developer forums.

So, to be honest there is no standard way to achieve this behavior. I used a workaround to get this done in a project. I thought it’s good to share it if someone is looking for a way. I will divide this into 3 simple steps.

1. Create a New Lightning Component Tab

In order to create a new Lightning Component Tab, please follow these steps.

  • Navigate to Setup and then Tabs.
  • Click on New button in Lightning Component Tab section.

pvzyfs0wteqpgztn1grmha

  • We will need the tab name for the URL which we are going to use for the button.
2. Create a New Button
  • Create a Detail Page button with “Display in new window” behaviour.
  • Button or Link URL
    /one/one.app#/n/tab_name
    
    After URL UPDATE Use the following 
    /lightning/n/tab_name
    

    tab_name is the Tab name which we created in the previous step. Additionally, you can add parameters to the URL. For example – Case record Id

    /one/one.app#/n/New_Case?id={!Case.Id}
    
    After URL UPDATE Use the following 
    /lightning/n/New_Case?id={!Case.Id}
  • Add this button to the page layout under Salesforce1 and Lightning Experience Actions from available Salesforce1 and Lightning Actions.
3. Get the passed Id in the URL

Now, here is the tricky part. Above 2 steps are enough if you don’t want to get the Id passed in the parameter. force:hasRecordId doesn’t work in this scenario. In order to get the passed Id or any other parameter, you will have to do some code in the lightning component which is being displayed in the new page. I did the following things to get the URL parameter.

  • Added an event handler which will be fired when the component gets loaded.
Component Code
<aura:attribute name="recordId"
                    type="String"
                    description="ID of the record."/>

<aura:handler name="init"
			  value="this"
			  action="{!c.doInit}"/>
Client-side controller code
doInit : function(component, event, helper) {

	var recordId = helper.getParamValue('New_Case', 'id');
	component.set('v.recordId', recordId);

}
Client-side helper JS code
({
	getParamValue : function( tabName, paramName ) {

		var url = window.location.href;
		var allParams = url.substr(url.indexOf(tabName) + tabName.length+1).split('&amp;amp;amp;');
		var paramValue = '';
		for(var i=0; i&amp;amp;lt;allParams.length; i++) {
			if(allParams[i].split('=')[0] == paramName)
				paramValue = allParams[i].split('=')[1];
		}
		console.log(paramValue);
		return paramValue;
	}
})

That’s all you need to achieve this functionality. Please comment your questions in case of any doubt/clarification.

UPDATE

If you have enabled the “NEW URL FORMAT” update in your org then you will have to update URL in the tab as per new format.

critical_update_screenshot_cptaqo

Difference

Old URL – /one/one.app#/n/tab_name

New URL –  /lightning/n/tab_name

 

Reference

Here’s What You Need To Know About The New URL Format For Lightning