Tuesday, November 20, 2018

Lightning Base component Input text validation example in Lightning Component.

Lightning Base component <lightning:input type="text" /> Input text validation example


Lightning Base component <lightning:input type="text" /> Input text validation example

Capturing component markup UI values in component JS controller.
Doing some validation on input text entered and displaying error message.


Application markup

InputCompValidation.app

<aura:application extends="force:slds">
    <c:InputValidation />
</aura:application>

Component Markup

InputValidation.cmp

<aura:component implements="flexipage:availableForAllPageTypes" access="global" >
 
    <aura:attribute name="firstName" type="String" />
    <aura:attribute name="lastName" type="String" />
    <aura:attribute name="midName" type="String" />
 
    <br/>
    <br/>
    <lightning:input aura:id="inputFirstName" type="text" label="First Name" value="{!v.firstName}"  />
    <br/>
    <lightning:input aura:id="inputMidName" type="text" label="Middle Name" value="{!v.midName}"  />
    <br/>
    <lightning:input aura:id="inputLastName" type="text" label="Last Name" value = "{!v.lastName}" />
 
    <br/>
    <br/>
 
    <lightning:button aura:id="buttonApply" label="Apply"  variant="brand" onclick="{!c.check}"/>
 
</aura:component>

Client side JS Controller

InputValidationController.js

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

        var inputFieldFirstName = component.find("inputFirstName");
        if(inputFieldFirstName != null) {
            var fname = inputFieldFirstName.get("v.value");
            console.log('Value of First Name is ' + fname);
        } else {
            console.log('inputField for first name is null');
        }
     
        var inputFieldMidName = component.find("inputMidName");
        if(inputFieldMidName != null) {
            var mname = inputFieldMidName.get("v.value");
            console.log('Value of Middle Name is ' + mname);
        } else {
            console.log('inputField for mid name is null');
        }
     
        var inputFieldLastName = component.find("inputLastName");
        if(inputFieldLastName != null) {
            var lname = inputFieldLastName.get("v.value");
            console.log('Value of Last Name is ' + lname);
        } else {
            console.log('inputField for last name is null');
        }
     
        console.log(inputFieldFirstName.get('v.validity').valid);
     
        if($A.util.isEmpty(fname)) {
            inputFieldFirstName.setCustomValidity("You must enter a value for First Name.");
            inputFieldFirstName.reportValidity();
        } else {
            inputFieldFirstName.setCustomValidity("");
            inputFieldFirstName.reportValidity();
            console.log(inputFieldFirstName.get('v.validity').valid);
        }
     
        console.log(inputFieldLastName.get('v.validity').valid);
     
        if ($A.util.isEmpty(lname)) {
            inputFieldLastName.setCustomValidity("You must enter a value for Last Name.");
            inputFieldLastName.reportValidity();
        } else {
            inputFieldLastName.setCustomValidity("");
            inputFieldLastName.reportValidity();
            console.log(inputFieldLastName.get('v.validity').valid);
        }
    }
})

Wednesday, July 18, 2018

Lightning component with configurable attributes

Lightning component with configurable attributes

Component

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,
                            force:hasSObjectName" access="global">

    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="sObjectName" type="String" default="Account" />
    <aura:attribute name="numberOfColumns" type="String" default="2" />
    <aura:attribute name="fieldsArray" type="String" />
    <aura:attribute name="layoutType" type="String" default="Compact" />

    <lightning:card iconName="custom:custom19" title="lightning:recordForm in Spring'18">

        <div class="slds-p-left_large slds-p-right_medium">
       
            <lightning:recordForm aura:id="recordViewForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="{!v.sObjectName}"
                                  fields="{!v.fieldsArray}"
                                  layoutType="{!v.layoutType}"
                                  columns="{!v.numberOfColumns}"
                                  onsuccess="{!c.raiseTheToastMessage}" />
        </div>
   
    </lightning:card>
</aura:component>

Design file

<design:component>
    <design:attribute name="sObjectName" label="Object" datasource = "Account, Contact, Opportunity" description="object on whose detail page component should be available" />
    <design:attribute name="numberOfColumns" label="Columns" datasource="1,2,3,4" description="Number of columns component should have" />
    <design:attribute name="fieldsArray" label="Field List" description="comma separated list of fields" /> 
    <design:attribute name="layoutType" label="Layout" datasource = "Custom, Full, Compact" description="type of layout to be used in component" /> 
</design:component>


JS Controller


({
    raiseTheToastMessage : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Success!",
            "message": "The record has been updated successfully.",
            "type": "success"
        });
        toastEvent.fire();
    }
})

Tuesday, July 10, 2018

Lightning Component using lightning:recordForm


Lightning component which can be used on Record detail page to provide a user a quick view on important fields. This uses component <lightning:recordForm> which is displayed inside a <lightning:card>. <aura:attribute> are used to pass values to attributes of <lightning:recordForm> component.

Component Code :

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,
                            force:hasSObjectName" access="global">

    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="sObjectName" type="String" default="Account" />
    <aura:attribute name="layoutType" type="String" default="Compact" />
    <aura:attribute name="numberOfColumns" type="String" default="2" />
    <aura:attribute name="compMode" type="String" default="Edit" />
    <aura:attribute name="fieldsArray" type="String[]" default="['AccountNumber','Name','AccountSource','Description',
                                                'NumberOfEmployees','Industry','Phone','Type','Rating']" />

    <lightning:card iconName="custom:custom19" title="lightning:recordForm in Spring'18">
 
        <div class="slds-p-left_large slds-p-right_medium">
         
            <lightning:recordForm aura:id="recordViewForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="{!v.sObjectName}"
                                  fields="{!v.fieldsArray}"
                                  columns="{!v.numberOfColumns}"
                                  layoutType="{!v.layoutType}"
                                  mode="{!v.compMode}"
                                  onsuccess="{!c.raiseTheToastMessage}"
                                  onload="{!c.onLoad}"
                                  onerror="{!c.onError}" />
        </div>
     
    </lightning:card>
</aura:component>



Client side JS Controller code


({
    raiseTheToastMessage : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Success!",
            "message": "The record has been updated successfully.",
            "type": "success"
        });
        toastEvent.fire();
    },
    onLoad : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Loaded!",
            "message": "The record has been Loaded successfully ."
        });
        toastEvent.fire();
    },
    onError : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Error!",
            "message": "Error."
        });
        toastEvent.fire();
    }
})






Sunday, July 8, 2018

Lightning Component using lightning:recordForm

This component is intended to be used on Contact Object detail page.
This component uses lightning:recordForm component.
It takes contact record id and provides a little form where you choose the fields you want to display and allows you to view / edit those fields.

Component Code:

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:hasSObjectName" access="global">

    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="sObjectName" type="String" default="Contact" />
    <aura:attribute name="fieldsToDisplay" type="String" />
    <aura:attribute name="val" type="String" />
    <aura:attribute name="layoutType" type="String" default="Custom" />
    <aura:attribute name="numberOfColumns" type="String" default="1" />
    <aura:attribute name="fieldsArray" type="String[]" default="['Name','Email','Phone','AccountId']" />
    <aura:attribute name="targetFields" type="Contact" />

    <lightning:card iconName="custom:custom19" title="lightning:recordForm in Spring'18">
 
        <div class="slds-p-left_large slds-p-right_medium">
         
            <lightning:recordForm aura:id="recordViewForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="{!v.sObjectName}"
                                  fields="{!v.fieldsArray}"
                                  columns="1"
                                  onsuccess="{!c.happyDance}" />
        </div>
     
    </lightning:card>
</aura:component>

JS Controller Code:

({
    happyDance : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Success!",
            "message": "The record has been updated successfully.",
            "type": "success"
        });
        toastEvent.fire();
    }
})

Sunday, May 27, 2018

Apex Record Sharing

Apex Sharing


Individual records can be shared with Users or Groups by creating records in share object related to the object. These records can be inserted in share object from trigger or controller.

We will need to create records in share object when object's default OWD settings are restricted like Private, Public Read Only etc. This will open up record level access to new users / groups.

Fields to be set while using Apex sharing: ParentId, UserOrGroupId, AccessLevel, RowCause

These fields must be set when creating records in Share object :

  • ParentId
  • UserOrGroupId
  • AccessLevel
  • RowCause


ParentId The Id of the record being shared. This field cannot be updated.

UserOrGroupId The Id of the User to whom you are granting access. May also be a
Public Group Id. When sharing to a role, you cannot assign Role Id to UserOrGroupId field
directly. It should instead be a matching Group Id from Group table. This field cannot be
updated.

RowCause (aka Sharing Reasons) The reason why the user or group is being granted access.
The reason determines the type of sharing, which in turn controls who can alter the
sharing record. This field cannot be updated.

AccessLevel The level of access that the specified User or Group has been granted.
Valid values for Apex managed sharing are: Edit, Read.

This field must be set to an access level that is higher than the organizations default
access level for the parent object. For more information, see Access Levels.

AccessLevel is the only updateable field in Share object record.

Contact object has a custom field named Make_Public__c.

If a new contact record is either being created or updated and if this custom checkbox field is set to true, share the contact record with Group named Organization.

trigger ContactMakePublicTrigger on Contact (after insert, after update) {

  // get the id for the group for everyone in the org
  ID groupId = [select id from Group where Type = 'Organization'].id;
  // inserting new records
  if (Trigger.isInsert) {

    List<ContactShare> sharesToCreate = new List<ContactShare>();

    for (Contact contact : Trigger.new) {
      if (contact.Make_Public__c == true) {
        // create the new share for group
        ContactShare cs = new ContactShare();
        cs.ContactAccessLevel = 'Edit';
        cs.ContactId = contact.Id;
        cs.UserOrGroupId =  groupId;
        sharesToCreate.add(cs);
      }
    }

    // do the DML to create shares
    if (!sharesToCreate.isEmpty())
      insert sharesToCreate;

  // updating existing records
  } else if (Trigger.isUpdate) {

    List<ContactShare> sharesToCreate = new List<ContactShare>();
    List<ID> shareIdsToDelete = new List<ID>();

    for (Contact contact : Trigger.new) {

      // if the record was public but is now private -- delete the existing share
      if (Trigger.oldMap.get(contact.id).Make_Public__c == true &&
  contact.Make_Public__c == false) {
        shareIdsToDelete.add(contact.id);

      // if the record was private but now is public -- create the new share for the group
      } else if (Trigger.oldMap.get(contact.id).Make_Public__c == false &&
  contact.Make_Public__c == true) {

        // create the new share with read/write access
        ContactShare cs = new ContactShare();
        cs.ContactAccessLevel = 'Edit';
        cs.ContactId = contact.Id;
        cs.UserOrGroupId =  groupId;
        sharesToCreate.add(cs);
      }
    }

    // do the DML to delete shares
    if (!shareIdsToDelete.isEmpty())
      delete [select id from ContactShare where ContactId IN :shareIdsToDelete
and RowCause = 'Manual'];
    // do the DML to create shares
    if (!sharesToCreate.isEmpty())
      insert sharesToCreate;

  }

}

Salesforce Lightning components interview questions

Salesforce Lightning components interview questions 1 Lightning vs ui namespace for components ? It is recommended that you use t...