Tuesday, March 14, 2017

Localizing Content in Salesforce Lightning

Localizing plays important role when you enable multiple languages, currency and uses different date formats in salesforce.

Below are different options which you can use to localize your contents in Lightning.
  • Using Custom Label which can be translated into multiple languages.
  • Format number and date using <lightning:formattedDateTime> and <lightning:formattedNumber> components.
  • Using $Locale environment variable along with lightning localization service to format number and date formats in string expressions.


Using Custom Labels


As we know that custom labels can be translated in any language supported by salesforce. Custom label helps in displaying message to users in different languages. Remember, labels can contain only 1000 characters.

In order to use custom labels for multiple languages, you have to enable translation workbench. After this you can different translation text for labels.

Using labels in markup

You can access labels in lightning mark up by using below syntax:
{!$Label.namespace.labelName}

You can use "c" as namespace if your org uses default namespace.

Using labels in javascript function

You can use labels in controller/helper function by using the $A.get() function as mentioned below:

$A.get("$Label.namespace.labelName");

Formating Date, Time and Numbers


Localizing Dates in Markup

In <ui:outputDateTime>, you can specify the langLocale attribute and format to display datatime in required format. Below is an example:

<ui:outputDateTime value="2017-02-10T00:17:10:10.00Z" langLocale="us" format="M-d-y"/>

This will return "2-10-2017"

<ui:outputDateTime value="2017-02-10T00:17:10:10.00Z" langLocale="us" />

This will return "Feb 10, 2017 5:10:10 PM"

Using javascript to localize the dates

you can use localization service to format datetime values. Below is sample code:

var localDateFormat = $A.get("$Locale.dateFormat");
var userLocalLang = $A.get("Locale.langLocale");
var actualDtae = $A.localizationService.formatDateTime(new date(),localDateFormat);
//Now format datetime value
var requiredformat = "MMMM d, yyyy";
var formattedDate = $A.localizationService.formatDate(
actualDtae, 
requiredformat,
userLocalLang
);  
//Now you use formattedDate to set value in controller

Localizing Numbers in Markup

<ui:outputNumber> automatically reads user's SFDC locale setting on user detail page and formats number automatically.


For example:
<ui:outputNumber value="100002"/>

Output (if locale in user details page is English(United States))= 100,002
Output (if locale in user details page is German(Germany))= 100.002

You can also use format attribute to format numbers. Below is example:

<ui:outputNumber value="100002" format="0,000.00"/>
output will be = 100.002,00

Using javascript to localize the numbers

You can use different functions of localizationService to format numbers. Below are few exmaples:

$A.localizationSerevice.formatCurrency(100.10);
//dispaly output as $100.10

$A.localizationSerevice.formatNumber(1000.10,'0,000.00');
//dispaly output as 1,000.10

$A.localizationSerevice.formatPercent(.56);
//dispaly output as 56%



Using Locale Global Variable


$Locale global variable return information about user's locale. Below are few example:

{!locale.language}   
//returns language  code like "en', "fr" etc

{!locale.timezone}
//return time zone Id like America/New_York

{!locale.langLocale}
//return users locale id like "en_US", "en_GB" etc

In javascript, you can access this global variable by using $A.get() methods. Below is example to get user language:

var localelang= $A.get("$Locale.language");
//this will return language code like "en', "fr" etc

Hope this will help!!


More Blogs>>: 
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE    

Friday, March 10, 2017

Generating random number between two numbers and finding string value from list of values randomly

As we know in apex, math.random() function gives random number greater than or equal to zero and less than 1. This function can be used to generate random number in apex.

I have created a apex class which can be used to find a random between 2 numbers and this can be extended later to find random string from list of strings values or to select random picklist value for picklist field while creating test data in test class.

Below is apex class code:


In order to find random picklist value, use apex describe to store all picklist values in List and then pass that list to "findRandomStringFromList" method in RandomUtility apex class.


Hope this will help!!!


More Blogs>>: 
DYNAMIC APEX IN SALESFORCE
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IN SALESFORCE
SOQL INJECTION IN SOQL
CUSTOM METADATA AND CUSTOM SETTINGS IMPLEMENTATION TRICKS
SMART TABLE USING ANGULARJS IN VISUALFORCE PAGE
VISUALFORCE COMPONENT FOR RECORD STATUS BAR

Monday, March 6, 2017

Why to use design resource in Lightning bundle and how to add dynamic Options in datasource for Design Component

In Lightning Bundle, design resource helps in displaying components attributes in lightning app builder so that user can select attribute values and component behaves accordingly.

When to use design resource in lightning?


If you create a component which will be used in standalone lightning app, then you can pass attributes values for component and component will work accordingly but what if you component will be used in Lightning app builder while creating a lightning page. In this case how you will pass attributes values apart from default values.
So design resource helps you to specify some values to attributes which can be selected by Admin in lightning app builder. Below are 2 scenarios in which you should specify attributes in design resource otherwise they will not appear for users in Lightning App Builder.
  1. Required attributes which have default values
  2. Attributes which are not marked as required in component definition.
Let me explain this with an example.

I have created a component which display records from different objects. As of now for, I am going to display only record Id and name fields in table.

GenericListView.cmp

<aura:component controller="GenericListViewController"  implements="flexipage:availableForAllPageTypes" access="global" >
<aura:attribute name="objectName" type="String" default="Contact" required="true"/>
    <aura:attribute name="recList" type="List" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    
    <aura:if isTrue="{!v.recList.length > 0}">
        <table class="slds-table slds-table--bordered slds-table--cell-buffer">
        <thead>
            <tr class="slds-text-title--caps">
            <th scope="col">RecordId</th>
            <th scope="col">Name</th>
            </tr>
        </thead>
        <aura:iteration items="{!v.recList}" var="item">
        <tr>
        <td> {!item.Id}</td>
            <td> {!item.Name}</td>
        </tr>
        </aura:iteration>
    </table>
    </aura:if>
</aura:component>

GenericListViewController.js

({
doInit : function(component, event, helper){
        var objname=component.get("v.objectName");
        //alert('objname:'+objname);
        var params ={}
        helper.callServer(
            component,
            "c.findRecords",
            function(response){
                //alert('Response from controller for opportunities:'+JSON.stringify(response));
                component.set("v.recList",response);
            },
            {objectName: objname}
        );
    }
})

GenericListViewHelper.js

({
callServer : function(component, method, callback, params) {
        //alert('Calling helper callServer function');
var action = component.get(method);
        if(params){
            action.setParams(params);
        }
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                callback.call(this,response.getReturnValue());
            }else if(state === "ERROR"){
                alert('Problem with connection. Please try again.');
            }
        });
$A.enqueueAction(action);
    }
})

GenericListViewController apex class

Global class GenericListViewController{
@auraEnabled
    public static List<sobject> findRecords(string objectName){
        string queryString ='';
        List<sobject> returnList=new List<sobject>();
        if(objectName !=null ){
    queryString='select Id, name from '+ objectName + '  Order by lastmodifiedDate DESC Limit 10';
        }else{
            queryString='select Id, name from Contact   Order by lastmodifiedDate DESC Limit 10';  
        }
        system.debug('**queryString:'+queryString);
        returnList=database.query(queryString);
    return returnList;
    }
}

Now if you use this component in Lightning app builder, then you will not get any option to specify "ObjectName" attribute value and component will take default value which is "Contact" as specified in component definition.

Now if you want that admin will get option to select ObjectName so that component will display records from that object, then add attribute in design resource. Below is sample code:

GenericListView.design

<design:component >
<design:attribute name="objectName" datasource="Contact,Account,Opportunity" />
</design:component>

After saving this file you will get option to select object name in app builder.

Note:
  1. What ever you specify in datasource seperated by comma will appear as dropdown in Lightning app builder.
  2. Design resource supports only text, boolean and int.

How to add dynamic options to datasource in design components?


You have to follow below steps to implement this:
  • Create a Apex class which will be used to provide dynamic values. Apex class must extend the VisualEditor.DynamicPickList abstract class.
  • Specify datasource as this apex class while creating attribute in design resorce.

GenericListViewController apex class

Global class GenericListViewController extends VisualEditor.DynamicPickList{
@auraEnabled
    public static List<sobject> findRecords(string objectName){
        string queryString ='';
        List<sobject> returnList=new List<sobject>();
        if(objectName !=null ){
    queryString='select Id, name from '+ objectName + '  Order by lastmodifiedDate DESC Limit 10';
        }else{
            queryString='select Id, name from Contact   Order by lastmodifiedDate DESC Limit 10';  
        }
        system.debug('**queryString:'+queryString);
        returnList=database.query(queryString);
    return returnList;
    }
    global override VisualEditor.DataRow getDefaultValue(){
        VisualEditor.DataRow defaultValue = new VisualEditor.DataRow('contact', 'Contact');
        return defaultValue;
    }
    global override VisualEditor.DynamicPickListRows getValues() {
        Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        VisualEditor.DynamicPickListRows  myValues = new VisualEditor.DynamicPickListRows();
        VisualEditor.DataRow value1 = new VisualEditor.DataRow('Contact', 'Contact');
        myValues.addRow(value1);
        VisualEditor.DataRow value2 = new VisualEditor.DataRow('Account', 'Account');
        myValues.addRow(value2);
        VisualEditor.DataRow value3 = new VisualEditor.DataRow('Lead', 'Lead');
        myValues.addRow(value3);
        //Or you use object describe ti find all object details
        /*for(String ss1: schemaMap.keyset()){
            Schema.SObjectType objToken=schemaMap.get(ss1);
            Schema.DescribeSObjectResult objDescribe=objToken.getdescribe();
            VisualEditor.DataRow value11 = new VisualEditor.DataRow(objDescribe.getLabel(), objDescribe.getName());
            myValues.addRow(value11);
        }
*/
        return myValues;
    }
}

In this class, I am specifying Contact, Account and Lead object. You can use object describe if you want to display all object name from your org or you can add any values.

Modify you GenericListView.design code as shown below:

<design:component >
<design:attribute name="objectName" datasource="apex://GenericListViewController"/>
</design:component>

Now if you use this component in Lightning app builder then, you will get Contact, Account and Lead as Object name attribute options;



In this way you can pass values from apex class to datasource in design attributes.

Hope this will help!!!

Looking forward for everyone feedback..


More Blogs>>: 
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
DYNAMIC APEX IN SALESFORCE    
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE    

Friday, March 3, 2017

Raising and Handling Custom Events in Salesforce Lightning

Events in Lightning plays very important role when we have to communicate between different components. Suppose a component is present inside another component and we want to change behavior of parent component based on actions on inner/child components.

I will try to explain this concept with real life example.

Suppose you are driving and suddenly you witness an accident and you need to notify the nearest hospital about this accident so that they can send ambulance for help.



In this scenario, car accident is an event which happened. You are notifier who witness this event (register this event). After witnessing this event, you are going to fire an event through which you will send some message to near by hospital (other component) so that it will perform some action by sending ambulance for help.

Now if we need to understand in Lightning terms, then we create different events which will be used by components to interact between them. Below are different steps for this event handling:
  • Create a Lightning event and create different attributes in it which can be used to pass information between components.
  • Component which want to fire an event needs to first register for an event by using <aura:registerEvent>. Then only it can fire an event and other component can receive it.
  • Component which wants to receive information will handle the event using <aura:handler> and type as Ligthning Event which we create.
Below image will help you to understand custom events using lightning code:



Below is complete code:


If you preview your app, then you will see below output:


Hope this will help you to understand the custom event handling...


More Blogs>>: 
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
BOX AND SALESFORCE INTEGRATION    
INTEGRATING BOX FILE PICKER WITH SALESFORCE    
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE    

Sunday, February 26, 2017

Dynamically Creating and Destroying Lightning Button(ui:button)

Sometimes it is required to create the lightning component at run time and destroy them. For example you can create a modalDialog box which display different messages to user. So while performing any operation like deleting records, you want to display message saying deleted successfully of not able to delete due to some error, then you can create the modalDialog box dynamically and destroy it.

In order to create any lightning component dynamically, you can use $A.createComponent() to instantiate a component. This function take 3 parameters mentioned below:

  1.  type (String) :Type of component to create like lightning:button, lightning:component etc.
  2. attributes : Map of all parameters required for new component.
  3. callback function: Once the component is created, this callback function will be invoked.This function can be used to append newly created component to target component. You can place the newly created component inside some div to display.
For Demo purpose, I will be creating a lightning component in which we will create lightning buttons and destroy them dynamically. Below is component, controller and app code for this:



Explanation:

Whenever user clicks on create button, controller will create new button dynamically and append it in <Div/> tag. Controller always checks for v.body which returns the body of component and will check the length of body and append label to new button.


How to Destroy any component dynamically

You can simply fetch the body of lightning component and set it to blank array.
In above example, in order to delete all buttons present in div tag, we find the div tag with aura:id and set the body as blank array.

component.find("newTag").set("v.body",[]);

In order to remove all content of any components, simple set the v.body to blank array.

var bdy = component.get("v.body");
bdy .set("v.body",[]);

How to specify the dependencies when you are creating a custom component dynamically

Suppose you have created a custom component like c:myCustomDialog and you want to create is dynamically and want to use in component say c:listComponent then you have to specify the c:myCustomDialog componet as a dependent component inside c:listComponent. This will ensure that the component and its dependencies are sent to client when its needed.

below is code snippet which we need to specify in c:listComponent component:

<aura:component>
                 <aura:dependency resource="markup://c:myCustomDialog"/>
</aura:component>

<aura:dependency> tag supports following attributes:

  • resource : specify the dependent component which you will create dynamically
  • type : type of resource component depends on. It can be COMPONENT, APPLICATION, EVENT. The default value is "COMPONENT".  You can specify type="*" to match all type of resources.

Hope this will help you all understand the basic of creating and destroying the components dynamically.

Looking forward for your comments and feedback!!!!



More Blogs>>: 
RAISING AND HANDLING CUSTOM EVENTS IN sALESFORCE lIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
FETCHING FILE FROM EXTERNAL/PUBLIC URL AND STORING IT IN SALESFORCE    

Saturday, February 25, 2017

Fetching file from external/public URL and storing it into Salesforce

If you have file URL for file stored outside the salesforce, then you can fetch file information from external URL by performing a call out to external system and store the file in salesforce.

For Demo purpose, I have uploaded a pdf file in Google drive and shared it with link with people. Now I will fetch this file and will store it as attachment in salesforce under account record.

File URL-  https://drive.google.com/file/d/0ByXILxflqQ2jWGpNVmI1WW9uYTQ/view?usp=sharing


Below is apex class which will help us to perform this activity:



Now you can run below code in developer console to test this:

//you can specify any record Id where you want to store file as attachment
String RecordId='0019000000ld4kN'; 
String fileContentType='pdf';
String extFileURL='https://drive.google.com/file/d/0ByXILxflqQ2jWGpNVmI1WW9uYTQ/view?usp=sharing';
blob fileBlob=FileDownLoadUtility.fetchFileFromExternalUrl(extFileURL);
Id attachmentId = FileDownLoadUtility.createAttachment(fileBlob, RecordId , fileContentType);
system.debug('*****attachmentId:'+attachmentId);

Note: 

  • If you are trying to fetch file from external source which is authenticated, then pass authorization parameters in HTTP Request headers
  • You should specify the file content type before creating attachment in order to properly view file.
  • You can add additional parameter as fileName in "createAttachment" method, if you you want specify the attachment name while creating attachment.

While trying above code you may get below error:

For this you need to add external URL in Remote Site Settings. For this example, I have added "https://drive.google.com/" in remote site settings.




More Blogs>>: BOX AND SALESFORCE INTEGRATION    
INTEGRATING BOX FILE PICKER WITH SALESFORCE
REST API TUTORIAL FOR SALESFORCE




Monday, February 20, 2017

Integrating Box File Picker with Salesforce

Box File Picker allows to view content present in box folders and to integrate it with other application. Suppose we want to display the box folder contents for user from salesforce UI, then we can use javascript code snippet provided for box file picker.

Box File Picker allow your users to share their Box content with your application — without using OAuth!

Now we are going to use below code sample to implement this in Salesforce. In order to use Box File Picker, you need Client Id or API Key.
Navigate to your box application and click on Edit Application button.

Suppose your URL is -https://app.box.com/developers/services/edit/133000

Then Client Id is 133000




Below is VF Page Code


Explanation about different attributes in Box file picker:
  • linkType : The type of link. Can be direct or shared
    • shared : Allow you to select folder as well as file inside folder. Shared also allow you to specify the access type of file or folder like people with link, people in your company or people with access to folders
    • direct : Allow you to select only files not folder.
  • multiselect : true or false.
    • true: will get checkboxes for multiple file selection
    • false: will get radio button for single file selection

Callback & Responses from Box File Picker

Below javascript functions helps in integrating Box file picker with your application:

// Register a success callback handler
boxSelect.success(function(response) {
    console.log(response);
});
// Register a cancel callback handler
boxSelect.cancel(function() {
    console.log("The user clicked cancel or closed the popup");
});

Details about callback functions:

  • Success function : Whenever user select files or folders, response is passed as JSON in sucess callback handler.
  • Cancel function : This function will be called whenever user click cancel or close the box file picker
Below is sample JSON response which we will get in success callback function for shared link type:


[
    {
        "url" : "https://app.box.com/s/jxi6hcwcvvbbccjka6k8ewhi3",
        "name" : "Happy Time",
        "access" : "collaborators",
        "type" : "folder",
        "id" : 100344004694
    },
    {
        "url" : "https://app.box.com/s/jdfaddssdc234232df123aad",
        "name" : "The Sunil Kumar.docx",
        "access" : "collaborators",
        "type" : "file",
        "id" : 1000000344
    }
]


How to fetch files from Box and store it into salesforce

You can pass the JSON to controller method using javascript remoting and parse JSON to find out file and folder information. JSON response return the file URL which can be used to get file details by doing callout and storing it as attachment in salesforce.

Please refer Fetching File from External/Public URL for more details on this.



BOX AND SALESFORCE INTEGRATION
ACCESS TOKEN USING OAUTH 2.0 IN SALESFORCE
REST API TUTORIAL FOR SALESFORCE