Salesforce Cookies #13

How to validate fields in lightning components ( Form Validation in Lightning Component )

Some lightning components come with inbuilt validation and you need to trigger the validation in your client-side controller. Following components provide inbuilt validation support.

  • lightning:input
  • lightning:select
  • lightning:textarea
  • ui:input*

lightning:input is more powerful when it comes to the validation as it honors the HTML5 validations too like setting the min and max limit on an element.

For the components which are part of the “ui” namespace like ui:input, you need to check it manually in the client-side code. These components have a property which is “errors” and you can set a list of errors to that property which will be displayed alongside the ui:input component.

How to add an error to ui:input

Adding an error to a ui:input is very simple. You just need to check whether it’s having the clean data or not and then add the error to the component.

var emailCmp = component.find("email");
var email = inputCmp.get("v.value");
var filter = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
// If it's blank
if ( email ) {
 // Set error
 emailCmp.set("v.errors", [{message:"Email is required"}]);
}
else if ( !filter.test( email ) ) {
    emailCmp.set("v.errors", [{message:"Email is not valid"}]);

 

I hope it explains a basic approach towards the validation. Please feel free to comment as it really important for the improvements.

 

 

Salesforce Cookies #12

How to remove the arrows from lightning:input[type=”number”]?

I think this is a generic question and Salesforce devs have looked for the ways to get rid of the spin buttons on the input field without changing it to text type for a purely numeric behaviour. You just need a few lines of CSS to solve your problem.

We need some CSS which work across the browsers. Any browser like Safari, Chrome and Firefox have a specific bahaviour for number type inputs.

Component.css

In the CSS component of the Lightning component bundle, we need to include the following styling.

/* For Firefox browser */
.THIS input[type='number'] {  
   -moz-appearance:textfield;
}
/* For webkit browsers like Chrome and Safari */
.THIS input[type=number]::-webkit-inner-spin-button,
.THIS input[type=number]::-webkit-outer-spin-button {
   -webkit-appearance: none;
   margin: 0;
}

So it will look like as shown here.

Screenshot_2     Screenshot_1

In case if you have any concern or queries then please feel free to comment on the post.

Have fun with the CSS!!

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!! 🙂