Thursday, 17 June 2021

Salesforce Custom Metadata Type

In Salesforce Custom Metadata type is similar to creating custom object or custom setting. A custom metadata type's records are metadata, not data, in and of themselves. In contrast to Custom Settings, where only metadata is eligible for migration, Custom Metadata Type and its records can be migrated from one org to another during deployment. Custom Metadata is usually deployable, package-able, customizable, and upgradeable. The key benefit of using Custom Metadata is that it does not count against the SOQL query limit for each APEX transaction.

Custom metadata types can be used for


  • Mappings— Make connections between objects, such as a custom metadata type that allocates cities, states, or provinces to specific countries & regions. 
  • Business rules— Custom functionality can be combined with configuration records. To route payments to the correct destination, use custom information types and Apex code.
  • Master data— Assume your organization utilizes a basic accounting system. Create a special metadata type for custom charges such as customs and VAT rates. Subscriber orgs can refer to the master data if this type is included as part of an extension package. 
  • Whitelists— Keep track of lists like approved contributors and pre-approved vendors. 
  • Secrets— Protected custom metadata types within a package can be used to store information such as API keys. 

Field Manageability


Field manageability is used to manage custom fields when they are created under the Custom Metadata Type. Custom metadata type supports the following custom field types: 
  • Metadata Relationship 
  • Checkbox
  • Date
  • Date and Time 
  • Email
  • Number
  • Percent
  • Phone
  • Picklist
  • Text
  • Text Area 
  • URL

Access Custom Metadata Type Records


There are new ways to access Custom Metadata Types in the Salesforce Spring-21 pre-release orgs and similar to those for Custom Settings. It is no longer necessary to query them using SOQL, and the contribution to the Query Rows limit is reduced. To access information from custom metadata type records faster, use the Apex getAll(), getInstance(recordId), getInstance(qualifiedApiName), and getInstance(developerName) methods. These methods don't use the SOQL engine and return the sObject information from the call directly.

1.Access the Custom Metadata Type records before Spring 21.

2.Access the Custom Metadata Type records after Spring 21.

A. getAll() to get Custom Metadata Type Records.

The following example uses the getAll() method. The custom metadata type named Ticket has a field called TicketType 

B. getInstance() to get specific Custom Metadata Type Record.

What about if you don’t need to get all records and need to access only a single record? In that case, you can use the getInstance() method. 

Advantages of Custom Metadata:

  • It's possible to distribute metadata! There will be no more time-consuming post-deployment configuration, as there will be with custom settings. To create your default custom setting records, you don't need to develop Apex classes.
  • Change sets or the force.com migration tool can also be used to deploy custom metadata records with metadata type definitions (ANT). The records in custom settings are uploaded after the definition of the custom setting is deployed. 
  • ListViews, Page Layouts, and Validation Rules can be created on the Custom Metadata Types.
  • Metadata Relationships are a thing of beauty! Lookups between Custom Metadata objects are possible. You may also perform an Object Definition lookup.
  • With custom metadata types, you can issue unlimited Salesforce Object Query Language (SOQL) queries for each Apex transaction. 
  • Custom metadata type is visible in test class without using “SeeAllData”. 
  • Custom Settings has the same permissions to edit records and configure the system. The “Configure Application” permission allows you to do both. You can edit records with Custom Metadata's "Configure Application," but you'll need "Author Apex" to update the configuration.

Limitations


The following are the limitations of Custom Metadata Type:
  • Custom metadata records cannot exceed the size of 10MB.
  • It does not support formula field data type.
  • It cannot be updated through Apex. The only way to edit custom metadata types is by leveraging metadata API
  • 100 custom metadata types can be created per salesforce org. 
  • We can create only 100 fields per custom metadata type. 
  • Global picklists are not supported. 

Summary


By creating custom metadata, we can create a static set of data and reuse it in our applications, triggers, apex class, test class, Aura components, etc. Click here for more details. 

If you have any questions you can reach out our Salesforce Consulting team here.

Thursday, 10 June 2021

How to use apex:actionFunction in a Salesforce Visualforce Page?


SCENARIO


While working on one of the requirements for a banking sector project for a customer based in San Diego, California there was a requirement to update selected record in Visual Force Page.

 

Clicking on Update button, we need to pass the updated values from inputs of Visualforce page to apex class so that is that DML operations can be performed.

 

SOLUTION


To fulfil the requirement, we have used <apex:actionFuntion> tag of Visualforce page. By using this tag, we can call apex controller method from java script code using an AJAX request.  


To set field values directly from VF page, we have used <apex:param> with <apex:actionFunction> and added this keyword in the assignedTo attribute of <apex:param>. 

 

Below is a sample code for reference. Here we are updating Account Name using <apex:actionFunction>.

  1. On click of Update button, JS function will get the updated value of Account Name and pass it to the param of actionFunction. 
  2. The actionFunction first sets the value of the variable and then invokes the method of apex class to update the account record. 

ActionFunction.vfp 

<apex:page controller="actionFunctionExampleController" sidebar="false" showHeader="false">
    <div style="margin : 20px;">
        
        <apex:form id="accountForm">
            <apex:actionFunction action="{!updateAccount}" name="updateAccountAF" reRender="dataTable">
                <apex:param name="accountName" assignTo="{!this.account.Name}" value="" />
            </apex:actionFunction>
            
            <apex:outputpanel >
                <label>Name :</label>
                <apex:inputField id="accountName" value="{!account.Name}"/>
                <apex:commandButton value="Update" onclick="GetAccountName(); return false;" />
            </apex:outputpanel>
        </apex:form>
        
        <div style="margin:20px 0px;">
            <apex:dataTable value="{!account}" var="acc" id="dataTable" border="1" width="50%">
                <apex:column value="{!acc.Name}" headerValue="Name"/>
                <apex:column value="{!acc.Type}" headerValue="Type"/>
                <apex:column value="{!acc.AccountNumber}" headerValue="Account Number"/>            
                <apex:column value="{!acc.Industry}" headerValue="Industry"/>
            </apex:dataTable>
        </div>
    </div>
    
    <script type="text/javascript">
        function GetAccountName(){
            var accountName = document.getElementById("{!$Component.accountForm.accountName}").value;        
            updateAccountAF(accountName);
        }
    </script>
    
</apex:page>


ActionFunctionController.apxc 

public class actionFunctionExampleController {
    
    public Account account {get;set;}
        
    public actionFunctionExampleController(){
        Id accountId  = ApexPages.CurrentPage().getparameters().get('id');
        account = [select id, Name, AccountNumber, Type, Industry from Account where id =: accountId ];
    }
    
    public void updateAccount(){
        update account;
    }
}


NOTE: 


Also, we can get the values of <apex:param> by using the below code in apex class. For that, we don't need to write assignedTo attribute in VF page. 


Apexpages.currentPage().getParameters.get(paramName);



FACTS TO CONSIDER:

  • An <apex:actionFunction> component must be a child of an <apex:form> component.
  • Since the caller and <apex:actionFunction> are bound based on parameter order, make sure the caller's argument list matches the order of <apex:param>. 
  • For API version 23 or later, you cannot use <apex:actionFunction> inside an iteration component like, <apex:pageBlockTable>, <apex:repeat>, and so on. 

 

OUTPUT



If you have any questions you can reach out our Salesforce Consulting team here.