A blog about Salesforce CRM Configuration and development

Saturday, 5 October 2019

LWC Local Development Beta | Local Development Setup# and Installation


LWC ( Lightning Web Component) Local Development Beta is released by Salesforce.  This local development feature will help us to build, run and test the lightning web component on our local machine, we do not need to deploy the code on our salesforce org. Big Thanks to the LWC team.
This (Local Development) will reduce the time for LWC development and testing. This will definitely increase the productivity of the salesforce developer.


The Local Development Server is available through the Salesforce CLI plugin. It is configured and runs a Lightning Web Component enabled server on the local machine.

Setup# and Installation: 


Setup: 

Installation:
  • Open a terminal window (CMD run as administrator) run the following command to install the LWC local development server on your machine.
 sfdx plugins:install @salesforce/lwc-dev-server

  • Check for updates to the local development server.
 sfdx plugins:update





  • Open your VS Code IDE and add the.localdevserverfolder in your SFDX project to your.gitignorefile. Do not modify files inside of this folder.


  • Authorize a Developer Hub (Dev Hub) in the VS Code and through CMD.
sfdx force:auth:web:login --setdefaultdevhubusername
  • Log in using your Dev Hub credentials.



  • Start the server.
sfdx force:lightning:lwc:start

  • You can see all the LWC that you created in your org. Click on your favorite component to run.


  • c-hello-web-component: you can see this web component rendered in-browser without deploying to the org.
  • If you click on the button “View in VS Code” this will quickly open the component code in your VS Code IDE. When you can make any changes in the component code, those changes will refresh in the browser immediately.


Thanks
Arun Kumar



Share:

Tuesday, 10 September 2019

ChartJS Lightning Component | Draw Beautiful Report Chart Using Chart JS


In this blog post, I am going to share a lighting component which will display a chart based on the selected report and chart type. In this component, I have used the Chart.JS open-source javascript library to draw chart in lightning component. The user can select the report and chart type to draw/display the chart and the selection of report name and chart type will be remembered for the user.


Chart JS is a javascript library that allows us to design and draw the different kinds of charts using the HTML 5 canvas element. We can use this library to draw a simple, clean and animated chart. Below are some advantage of using this library for drawing chart.
  • It is open source.
  • We can use 8 chart type to display the chart.
  • HTML5 canvas (great rendring performance across all the modern browser)
  • It is responsive.

I have created a package which you can install in your salesforce instance.

RPTChart: Download/Install


Find the full code here.

References:



Share:

Saturday, 8 June 2019

Task Transfer Tool | Lightning Component | Mass Task Transfer

Task Transfer Tool.
Select multiple tasks to be transferred.
Select a user to which tasks will be assigned.
Task Re-Assigned successfully!
Search Tasks...

Task Transfer Tool - This is a tool which will transfer multiple task record from one user to another.

Sometimes we need to reassign large quantities of tasks, for example, when a staff/employee member is out and someone else will be working their tasks for that day. Editing the tasks one by one is not feasible and it is time-consuming. If we can transfer them in a single transfer it will save hours of time.


I have developed the lightning component which will do the mass task transfer:

Tool Features:
  • Mass task transfer ( Task re-assignment in a single click)
  • Search tasks which need to be transferred.
  • Easy to use, it can be used on the Home page, Lightning component tabs, etc.
  • It can be used on the Salesforce 1 mobile app.
OR




Share:

Sunday, 26 May 2019

OWD "Public Read Only" | Only record owner can edit their own records?

Scenario: There is a custom object, it's record should be visible to everyone (users) but only record owner can edit the record. When someone edits a picklist field, the record should be automatically assigned to the groups of the user to work on and they can edit the record and the previously assigned user should not edit the record.


Solution: Below is the steps to set up the things for the above requirement.
  • OWD: for this custom object will be "Public Read Only". (All user can see the record who has object access permission) 

  • OWD ( Organization Wide Sharing Default): It defines the default access level for an object’s records. The organization-wide sharing settings can be set to Private, Public Read Only, or Public Read/Write. 
  • Profile: The users who are going to see and work on the record should have 'Read','Edit' permission on the object.
  • Create queues for different users. (Setup -> Queue-> New)

  • Queue1 : Assigned User( User 1, User 2 )
    Queque 2: Assigned User ( User 3, User 4 )

  • Create a Process Builder: Assigned the record to the queue based on the selected picklist.
Setup -> Process Builder -> New
















Result: When the user changes the 'Level' picklist field value automatically record will be assigned to 'Queue' ( multiple users) with the help of Process Builder.

The record will be read-only to the users and only owner and the user who created the record will be able to edit the record.

Thanks.

Arun Kumar

Share:

Monday, 6 May 2019

Retrieve CustomField Metadata Information Using Tooling API

Sometimes Salesforce admin/user needs to know which custom fields created in a certain time frame like THIS Week/Month/Year, etc.

We can use Salesforce Tooling API to get the CustomField information. We can query the CustomField metadata information inside Salesforce developer console, you just need to check the "Use Tooling API" checkbox. Below is the screenshot showing the lists of custom fields created this year. 

Query: SELECT DeveloperName,CreatedDate,TableEnumOrId FROM CustomField where CreatedDate = THIS_YEAR



Q. How to export the data showing in dev console in CSV format?

Ans~ We can use the 'SDFC Dev Console Data Exporter' google chrome extension for that.

SFDC Dev Console Data Exporter (Screenshot)

Q. What is the Tooling API?

Ans~ Tooling API exposes metadata information of Org, we can access Metadata information using REST or SOAP. Tooling API retrieve the small piece of metadata, we can use this to develop an interactive application or tools for developers.

We can accomplish the following tasks using the Tooling API:
  • Retrieve metadata about an object’s field.
  • Retrieve metadata of custom and standard object properties.
  • Get metadata information about Apex Classes, Visualforce Pages, Apex Triggers.
  • Get Code coverage details of Apex classes and Trigger.
  • Retrieve metadata information about ValidationRule and WorkflowRules.
  • Query RecentItems used in your SFDC org.
  • Etc...
Share:

Sunday, 5 May 2019

Mailchimp Batch Operation | Salesforce - Mailchimp Integration | Mailchimp REST API










MailChimp Batch Operation: We can use this batch operation in the MailChimp API to complete more than one operation in just a single call. Let's take an example where you need to subscribe and unsubscribe the records. In the simple API call, you have to do separate call to make the single record to subscribe and unsubscribe in the MailChimp list this may exceed your API call out limit. The batch operation runs in the background on the MailChimp server and does the more than one action in just a single API call. After callout, we can check the batch status.



Scenario: There is a field on Contact records 'Email Opt Out', whenever user update the field to uncheck subscribe the record in the MailChimp list and vice versa.

MCSubscribeUnsubscribeTrg
MCSubscribeUnsubscribeHelper


Find the code on Github here

Happy Coding...

Reference:
https://developer.mailchimp.com/documentation/mailchimp/reference/batches/
https://developer.mailchimp.com/
Share:

Saturday, 4 May 2019

Edit Action On Account [Contacts] Related List In Lightning Experience



On the Account page, we have the 'Edit' action on the related Contact list in Salesforce classic user interface as shown in the screenshot below.


But if you see the same in the Lightning experience user interface, the user first needs to click on the 'down' button icon then they can see the 'Edit' action option and from there they can click on 'Edit' action.


In the Lightning user interface, the user needs to do an extra click to do the same as they were doing in a single click in Salesforce classic user interface.

I have solved the issue with a workaround (a field and URL hack) in one of my projects.

Create a formula field on Contact object with return type as Text.

Formula:

HYPERLINK(
"https://[custom domain].my.salesforce.com/" & Id & "/e?retURL=https://[custom domain].lightning.force.com/lightning/r/"
& AccountId & "/related/AccountContactRelations/view?0.source=alohaHeader" ,"Edit")


Add the created field in the Account (Contact Related list) page layout.


Result:




Share:

Wednesday, 1 May 2019

Copy To Clipboard | Lightning Component | Copy sObject Record Link


Hello Guys,

In this blog post, I am going to share the 'Copy To Clipboard' functionality in the lightning component using javascript. While working with the records in Salesforce sometimes user needs the record link to share in an email or need to use in the documentation or somewhere else.


This component will copy the record link in the clipboard in just a single click, the user does not need to copy the record link from browser URL. The component can be used for every standard and custom object, the user just needs to add the component on the object detail page and needs to click on the link button icon, the record link will be copied in the clipboard.

Find the full component code below.

copyToClipboardCmp
copyToClipboardCmpController copyToClipboardCmpHelper copyToClipboardCntrl

Full code on GITHUB.
Happy Coding...! 
Share:

Saturday, 23 March 2019

Material Designed DataTable In Visualforce Page.

Q. What is material design?

Ans:- Material design is a design technique/language. It uses a grid-based layout, responsive animation, and transition, padding, depth effects show as lightning and shadow. It is designed to optimize user experience with natural motions, 3D effects, and realistic lighting.

DataTable: It is a plug-in for the jQuery Javascript library. It will add features like fast search in the table, paginations, column sorting, etc with the minimum code.



In this example code, I have used DataTable (Jquery plug-in javascript library) in the visualforce page. Find the full code below.

 <apex:page controller="DatatableCntrl" sidebar="false">  
 <head>  
   <apex:includescript value="https://code.jquery.com/jquery-3.3.1.js"/>  
   <apex:includescript value="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"/>  
   <apex:includescript value="https://cdn.datatables.net/1.10.19/js/dataTables.material.min.js"/>  
   <apex:stylesheet value="https://cdnjs.cloudflare.com/ajax/libs/material-design-lite/1.1.0/material.min.css"/>  
   <apex:stylesheet value="https://cdn.datatables.net/1.10.19/css/dataTables.material.min.css"/>  
   <script>  
   j$ = jQuery.noConflict();  
   j$(document).ready( function () {  
     var accTable = j$('[id$="accTable"]').DataTable({  //datatable 
        columnDefs: [  
     {  
       targets: [ 0, 1, 2 ],  
       className: 'mdl-data-table__cell--non-numeric'  
     }  
   ]  
     });  
   });  
   </script>  
   <style>  
     div.dataTables_wrapper div.dataTables_filter {  
     text-align: right;  
     margin-right: 2%;  
     /* border-radius: 2px; */  
     /* height: 51px; */  
   }  
   </style>  
 </head>  
 <body>  
   <table id="accTable" class="mdl-data-table" style="width:100%">  
     <thead>  
       <tr>  
         <th>Name</th>  
         <th>Billing State</th>  
         <th>Website</th>  
       </tr>  
     </thead>  
     <tbody>  
       <apex:repeat value="{!accList}" var="acc">  
         <tr>  
           <td>{!acc.Name}</td>  
           <td>{!acc.BillingState}</td>  
           <td>{!acc.Website }</td>  
         </tr>  
       </apex:repeat>  
     </tbody>  
   </table>  
 </body>  
 </apex:page>  

 public class DatatableCntrl{  
   public List<Account> accList {get; set;}  
   public DatatableCntrl(){  
     accList = [SELECT Name, BillingState,Website FROM Account where BillingState!='' and Website !='' order by name ];  
   }  
 }  


References:

Share:

Make only one record active at a time of same record type.


Scenario: Make only one contact record active at a time of the same record type on Account.

Solution: Using Apex Trigger: Create a trigger on the contact object for insert and update event. Find the code below.

 /* Name: deactivateContact  
  * Description: Make only one record active at a time of same record type.  
  * Created By: 23/03/2019  
  * Last ModifiedDate: 23/03/2019  
  * Created By: Arun Kumar  
 */  
 trigger deactivateContact on Contact (before update, before insert) {  
   if(Trigger.isBefore){  
     if(Trigger.isUpdate || Trigger.isInsert){  
        if(deactivateContactHelper.isFirstTime){ // check for recursive call  
         deactivateContactHelper.isFirstTime = false;  
         deactivateContactHelper.updateContact(Trigger.new);   
        }  
     }  
   }  
 }  

 /* Name:deactivateContactHelper  
  * Description: Update isActive field on contact( Only one contact record will be active at a time of same record type).  
  * Created Date: 23/03/2019  
  * Last ModifiedDate: 23/03/2019  
  * Created By: Arun Kumar  
 */  
 public class deactivateContactHelper {  
   public static boolean isFirstTime= true; // for recursive call check  
   // update isActive field ( Only one contact record will be active at a time of same record type).  
   public static void updateContact(List<Contact> contactList){   
     set<id> parentId = new set<id>();  
     set<id> recordId = new set<id>();  
     set<id> recordTypeIdSet = new set<Id>();  
     for(Contact c: contactList){  
       if(c.isActive__c){  
         parentId.add(c.AccountId); // accountid  
         recordId.add(c.id); // record id  
         recordTypeIdSet.add(c.recordTypeId); // recordtype id  
       }  
     }  
     List<contact> ContactForUpdate = new List<contact>(); // contact list for update  
     for(Contact con:[select id,isActive__c from contact where accountid IN: parentId and Id NOT IN: recordId and recordTypeId IN:recordTypeIdSet]){  
       con.isActive__c = false;// isActive__c = FALSE  
       ContactForUpdate.add(con);   
     }  
     if(ContactForUpdate.size()>0){  
       try{  
         update ContactForUpdate;// Update rest contact list  
       }  
       catch(Exception e){  
         system.debug('Exception has occred! ' +e.getMessage());  
       }  
     }   
   }  
 }  
Share:

Friday, 22 March 2019

Count number of Active contact on Account


Count # Number of active contact on Account record.

Scenario: Calculate #NoOfActiveContact for Account record.

Solution: Create an Apex Trigger on Contact object and calculate for all case (insert, update, delete, undelete) 

 trigger CountActiveContact on Contact (after insert,after update,after delete,after undelete) {  
   Set<id> parentId = new Set<Id>(); // AccountId Set  
   if(Trigger.isAfter){  
     if(Trigger.isUpdate || Trigger.isInsert || Trigger.isUndelete){  
       for(Contact con: Trigger.new){  // return list of new sObject record
         if(con.accountId !=null){  //check if accountid is not null
           parentId.add(con.accountId);  //add accountid in set
           if(Trigger.isUpdate){ // check for update   
             if(Trigger.oldMap.get(con.id).AccountId != con.AccountId){ // check old accountid with new  
               parentId.add(Trigger.oldMap.get(con.id).AccountId);//accountid set  
             }  
           }  
         }  
       }  
     }  
     if(Trigger.isDelete){// delete  
       for(Contact con: Trigger.old){  // return list of deleted sObject record
         parentId.add(con.accountId);  
       }  
     }  
     List<Account> accListForUpdate = new List<Account>();  //account list for update
     for(Account acc: [select id,ARI__No_Of_Contact__c,(select id from contacts where isActive__c=true) from Account where id IN: parentId]){  
       acc.ARI__No_Of_Contact__c = acc.contacts.size(); // get size of contact list on account 
       accListForUpdate.add(acc);  //add acc object in list
     }  
     if(accListForUpdate.size()>0){  //check for list size
       try{  
         update accListForUpdate;  // update account list
       }  
       catch(Exception e){  
         system.debug('Exception has occured! '+e.getMessage());  
       }  
     }  
   }  
 }  

Share:

Wednesday, 20 March 2019

Sort wrapper class list in Apex

Sort wrapper list based on selected records.


Visualforce page:
 <apex:page showHeader="false" controller="WrapperListSortCntrl" >  
 <html>  
   <head>  
     <apex:slds />  
   </head>  
   <body>  
     <apex:form >  
       <div class="slds-page-header">  
          My Product  
       </div>  
       <table class="slds-table slds-table--bordered">  
         <thead>  
           <tr>  
             <th> Select</th>  
             <th> Name </th>  
             <th> Product Family </th>  
             <th> Description</th>  
             <th> Active</th>  
           </tr>  
         </thead>  
         <tbody>  
           <apex:repeat value="{!ProductList}" var="p">  
             <tr>  
               <td><apex:inputcheckbox value="{!p.selectcheck }" styleClass="slds-checkbox"/></td>  
               <td>{!p.prd.Name}</td>  
               <td>{!p.prd.Family}</td>  
               <td>{!p.prd.Description}</td>  
               <td>{!p.prd.IsActive}</td>  
             </tr>  
           </apex:repeat>  
         </tbody>  
       </table>  
     </apex:form>   
   </body>  
 </html>    
 </apex:page>  
Apex Class:
 /* Name: WrapperListSortCntrl  
   Description: Wrapper List Sort  
   Created Date: 20/03/2019  
   LastModified Date: 20/03/2019  
   Created By: Arun Kumar  
 */  
 public class WrapperListSortCntrl{  
   public List<WrapperCls> ProductList{get;set;}  
   public WrapperListSortCntrl(){  
     ProductList = new List<WrapperCls>();  
     system.debug('Insider');  
     fetchProducts();  
   }  
   public void fetchProducts(){  
     for(Product2 p:[select id,Name,Family,Description,IsActive from Product2]){  
       Boolean check = false;  
       if(p.isActive){  
         check = true;  
       }  
       ProductList.add( new WrapperCls(check, p));   
     }  
     system.debug('ProductList: '+ProductList);  
     ProductList.sort(); // this Wrapper list will be sort according to checkbox selected (isActive =true)  
   }  
   //Wrapper cls implements Comparable Interface  
   public class WrapperCls implements Comparable { //Adds sorting support for Lists that contain non-primitive types, that is, Lists of user-defined types.  
     public Boolean selectcheck {get;set;}    
     public Product2 prd{get;set;}    
     public WrapperCls(Boolean selectcheck, Product2 prd){  
       this.selectcheck = selectcheck ;  
       this.prd = prd;  
     }  
     public Integer compareTo(Object ObjectToCompare) { //Returns an Integer value that is the result of the comparison.  
       WrapperCls compareToWrapperCls = (WrapperCls)ObjectToCompare;  
       if (compareToWrapperCls.selectcheck )   
         return 1;  
       else  
         return 0;  
       }  
     }  
 }  

Reference:

Comparable Interface:https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_comparable.htm
Share:

Sunday, 17 March 2019

Show the uploaded image on the detail page.





Hello,

I have recently worked on the interesting/good requirement and just want to share this with you:

Requirement: There should be a detail page button on object record and the user can upload the image file to that record. The uploaded image file should show on the record details page.

Solution: Created a visualforce page through which the user can upload the image in the content file system in Salesforce. Now the main thing is to show the uploaded image file on the record detail page. For that, I had created a rich text field and inserted file downloadable URL in the <image> tag.

Q. Where we can find the 'ContentDownloadUrl ' after file upload? 

Ans- The ContentDistribution object: (Represents information about sharing a document externally). We need to insert the ContentDistribution object record after ContentVersion insertionAfter CD (ContentDistribution) record insertion, you will get the 'ContentDownloadUrl' for that file. Find more information on ContentDistribution in Salesforce doc here.

Create a detail page button on the Account object like the screenshot below:














Visulforce page:
 <!-- Name: UploadImages  
    Decription: Upload images in files object and show them on richtex field on record.  
    Created Date: 17/03/2019  
    LastModified Date: 17/03/2019  
    Created By: Arun Kumar  
 -->  
 <apex:page controller="uploadImageCntrl" sidebar="false">  
  <html>  
    <head>  
      <apex:slds />  
      <style>  
        .slds-scope .slds-page-header {  
         padding: 1rem 1rem;  
         /* border-bottom: 1px solid rgb(221, 219, 218); */  
         /* border-radius: .25rem; */  
         background: rgb(243, 242, 242);  
         background-clip: padding-box;  
         /* box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.10); */  
         border: 1px solid rgb(221, 219, 218);  
       }  
       #bodyPart{  
         border: 1px solid rgb(221, 219, 218);  
         padding:1rem 1rem;  
       }  
      </style>  
    </head>  
    <body>  
      <apex:form >  
      <div class="slds">  
        <div class="slds-grid">  
          <div class="slds-col slds-size--12-of-12">  
            <div class="slds-page-header">  
              Upload Image  
            </div>  
          </div>  
        </div>  
        <div id="bodyPart">  
          <apex:inputFile value="{!imageFile}" styleClass="" />  
          <apex:actionRegion >  
             <apex:commandButton value="Upload" action="{!uploadImg}" Styleclass="slds-button slds-button--brand" />  
          </apex:actionRegion>  
        </div>  
      </div>  
      </apex:form>  
    </body>  
  </html>  
 </apex:page>  
Apex controller
 /* Name: uploadImageCntrl   
   Description: Upload files and show image in richtext field on object record page.  
   Created Date: 17/03/2019  
   LastModified Date: 17/03/2019  
   Created By: Arun Kumar  
 */  
 public with sharing class uploadImageCntrl {  
   public transient Blob imageFile{get;set;}  
   public string parentRecId ='';  
   public void uploadImageCntrl(){  
   }  
    public PageReference uploadImg() {  
     parentRecId = ApexPages.currentPage().getParameters().get('id');  
     system.debug('record id: ' +parentRecId );  
     //ContentVersion  
     ContentVersion conVer = new ContentVersion();  
     conVer.ContentLocation = 'S'; // S specify this document is in SF, use E for external files  
     conVer.Title = 'Test File';   
     conVer.PathOnClient = 'Test File';  
     conVer.VersionData = imageFile; //   
     insert conVer;  
     ContentVersion cv = [select id,ContentDocumentId from ContentVersion where id =: conVer.id];  
     //Create ContentDocumentLink  
     ContentDocumentLink cDe = new ContentDocumentLink();  
     cDe.ContentDocumentId = cv.contentDocumentId;  
     cDe.LinkedEntityId = parentRecId; // you can use objectId,GroupId etc  
     cDe.ShareType = 'V'; // Inferred permission, checkout description of ContentDocumentLink object for more details  
     //Insert content document link  
     insert cDe ;  
     //ContentDistribution: Represents information about sharing a document externally  
     ContentDistribution cd = new ContentDistribution();  
     cd.Name = 'Test File';  
     cd.ContentVersionId = conVer.Id;  
     //insert   
     insert cd;  
     ContentDistribution distribution = [select Name,ContentDownloadUrl from ContentDistribution where id=: cd.id];  
     Account acc = [select id,ARI__Images__c from Account where id=: parentRecId]; //ARI__Images__c (ARI__ is Namspace. it will be different in your case)   
     if(acc.ARI__Images__c == null){  
       acc.ARI__Images__c ='';  
     }  
     acc.ARI__Images__c += '<img src="'+distribution.ContentDownloadUrl+'" width="478" height="247">'+'</img><br/>';   
     update acc;  
     return null;  
   }  
 }  
Output:










Reference: https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_contentdistribution.htm

Hope this blog post helps many.

Happy Coding... :)
Share:

Wednesday, 16 January 2019

Super fast records searching in the lightning component.

Lightning component client-side searching/filter.
Hello Everyone,

We generally make the server call to search the records in the table on the lighting component/VF page. As we know that the concept of Lightning Component development is based on reducing the server calls, so I have demonstrated client-side record filter/search in this lightning component. 


Component
 <aura:component controller="ListComponentCntrl" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >  
   <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>  
   <aura:attribute name="data" type="Contact[]" />  
   <aura:attribute name="UnfilteredData" type="Contact[]" />  
   <aura:attribute name="filter" type="String" />  
   <aura:handler name="change" value="{!v.filter}" action="{!c.doFilter}" />  
   <div class="slds-page-header">My Contacts</div>  
   <lightning:input name="x" value="{!v.filter}" label="Filter" placeholder="Search Contact by "/>  
   <table class="slds-table slds-table--bordered">  
     <thead>  
       <tr>  
         <th>Id</th>  
         <th>Name</th>  
         <th>Email</th>  
       </tr>  
     </thead>  
     <tbody>  
       <aura:iteration items="{!v.data}" var="row" indexVar="rowIndex">  
         <tr>  
           <td>{!row.Id}</td>  
           <td>{!row.Name}</td>  
           <td>{!row.Email}</td>  
         </tr>  
       </aura:iteration>  
     </tbody>  
   </table>   
 </aura:component>  
JS Controller
 ({  
   doInit :function(component,event,helper){  
     // Apex method definition  
     var action = component.get("c.loadData");  
     // callbak function  
     action.setCallback(this,function(response){  
       //get state  
       var state = response.getState();  
       // check if state is 'SUCCESS'  
       if(state == 'SUCCESS'){  
         var result = response.getReturnValue();  
         //set value to "UnfilteredData" attaribute   
         component.set("v.UnfilteredData",result);  
         console.log(result);  
         // set value to "data" attaribute  
         component.set("v.data",result);  
       }else{  
         console.log('something bad happend! ');  
       }  
     });  
     // put the action into queue for server call.  
     $A.enqueueAction(action);  
   },  
   doFilter: function(component, event, helper) {  
     //calling helper  
     helper.FilterRecords(component);  
   }  
 })  
JS Controller Helper
 ({  
   FilterRecords: function(component) {  
     //data showing in table  
     var data = component.get("v.data");  
     // all data featched from apex when component loaded  
     var allData = component.get("v.UnfilteredData");  
     //Search tems  
     var searchKey = component.get("v.filter");  
     // check is data is not undefined and its lenght is greater than 0  
     if(data!=undefined || data.length>0){  
       // filter method create a new array tha pass the test (provided as function)  
       var filtereddata = allData.filter(word => (!searchKey) || word.Name.toLowerCase().indexOf(searchKey.toLowerCase()) > -1);  
       console.log('** '+filtereddata);  
     }  
     // set new filtered array value to data showing in the table.  
     component.set("v.data", filtereddata);  
     // check if searchKey is blank  
     if(searchKey==''){  
       // set unfiltered data to data in the table.  
       component.set("v.data",component.get("v.UnfilteredData"));  
     }  
   }  
 })  
Apex Controller
 public class ListComponentCntrl {  
   @AuraEnabled  
   public static List<Contact> loadData(){  
     List<Contact> conList = [select Id,Name,Email from Contact order by Name asc];  
     return conList;  
   }  
 }  


Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Hope this blog post helps many.

Happy Coding... :)
Share:

Friday, 11 January 2019

Make beautiful,dynamic report chart using Chart JS in Salesforce.

Make beautiful,dynamic report chart using Chart JS in Salesforce.
What is Chart JS? - It is an open source javascript library that can be used to draw different types of chart with the help of the HTML 5 canvas element. 

We can use this javascript library in the Visualforce page to draw the chart on the page. We have to include the script in the <head> tag.


Visualforce Page:
 <apex:page sidebar="false" showHeader="false" controller="ChartCntrl">  
   <html>  
     <head>  
       <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" />  
       <apex:slds />  
       <apex:includeScript value="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.js"/>  
       <style>  
         .chart1{ width:450px; height:300px; border:1px solid rgb(216, 221, 230); border-radius:5px; }  
         .chart2{position:absolute; width:470px; height:500px; border:1px solid rgb(216, 221, 230); border-radius:5px; }  
       </style>  
     </head>  
     <body>  
       <div class="slds">  
         <div class="slds-page-header"><div class="slds-text-heading--large">Reporting Chart</div></div>  
         <div class="slds-grid">  
           <div class="slds-col slds-size--6-of-12" style="border:1px solid rgb(216, 221, 230); border-radius:5px; ">  
             <canvas id="myChart" width="300" height="300"></canvas>  
           </div>  
           <div class="slds-col slds-size--6-of-12" style="border:1px solid rgb(216, 221, 230); border-radius:5px; ">  
             <canvas id="myChart1" width="300" height="300"></canvas>  
           </div>  
         </div>  
         <script>  
         var ctx = document.getElementById("myChart");  
         var array1=new Array();  
         var array2=new Array();  
         var LeadLabel=new Array();  
         var LeadData=new Array();  
         var AccountLabel=new Array();  
         var AccountData=new Array();  
         <apex:repeat value="{!Lead_Label}" var="ld">  
           LeadLabel.push("{!ld}");  
         </apex:repeat>  
         <apex:repeat value="{!Lead_Data}" var="dt">  
           LeadData.push("{!dt}");  
         </apex:repeat>  
         //('lead '+LeadData);  
         <apex:repeat value="{!Account_Label}" var="al">  
           AccountLabel.push("{!al}");  
         </apex:repeat>  
         <apex:repeat value="{!Account_Data}" var="ad">  
           AccountData.push("{!ad}");  
         </apex:repeat>  
         <apex:repeat value="{!data}" var="d">  
           array1.push("{!d}");  
         </apex:repeat>  
         <apex:repeat value="{!label}" var="l">  
           array2.push("{!l}");  
         </apex:repeat>  
         var background_color=new Array();  
         var border_color=new Array();  
         for(var i=0 ; i<array1.length ; i++)  // Random colors
         {  
           var w,x,y,z;  
           w = parseInt(Math.random()*255);  
           x = parseInt(Math.random()*255);  
           y = parseInt(Math.random()*255);  
           z = Math.random();  
           background_color.push('rgba('+w+','+x+','+y+','+z+')');  
           border_color.push('rgba(0,0,0,1)');  
         }  
         var myChart = new Chart(ctx, {  
           type: 'pie',  
           data: {  
             labels: array2,  
             datasets: [{  
               label: '# of Votes',  
               data: array1,  
               backgroundColor: background_color,  
               borderColor: border_color,  
               borderWidth: 1  
             }]  
           }  
         });  
         </script>  
         <!--2nd Canvas--------------------->  
         <script>  
         var ctx = document.getElementById("myChart1");  
         var myChart = new Chart(ctx, {  
           type: 'bar',  
           data: {  
             labels: AccountLabel,  
             datasets: [{  
               label: '# of Account',  
               data: AccountData,  
               backgroundColor: background_color,  
               borderColor: border_color,  
               borderWidth: 1  
             }]  
           },  
           options: {  
             scales: {  
               yAxes: [{  
                 ticks: {  
                   beginAtZero:true  
                 }  
               }]  
             }  
           }  
         });  
         </script>  
       </div>  
     </body>  
   </html>  
 </apex:page>  
The HTML 5 <canvas> tag is used to drag graphis/chats on the web page.
 <canvas id="myChart" width="300" height="300"></canvas>  
Below script will draw the chart on the canvas and here SFDC data fetched from Apex controller and passed as an array in the script below.
 var ctx = document.getElementById("myChart"); // canvas element  
         var myChart = new Chart(ctx, {  
           type: 'pie', //chart type  
           data: {  
             labels: array2, // label from array2  
             datasets: [{  
               label: '# of Votes',  
               data: array1, // data from array2  
               backgroundColor: background_color, // background color  
               borderColor: border_color, // border color  
               borderWidth: 1 // border width  
             }]  
           }  
         });  
Apex Controller:
 public with sharing class ChartCntrl {  
   public list<string> label{get;set;}  
   public list<integer> data{get;set;}  
   public list<string> Lead_Label{get;set;}  
   public list<Integer> Lead_Data{get;set;}  
   public list<string> Account_Label{get;set;}  
   public list<Integer> Account_Data{get;set;}  
   public list<opportunity> oppList{get;set;}  
   public ChartCntrl (){  
     label=new list<string>();  
     data=new list<integer>();  
     Lead_Label=new List<string>();  
     Lead_Data=new List<integer>();  
     Account_Label=new List<string>();  
     Account_Data=new List<integer>();  
     generateData();  
     GenerateLeadData();  
     GenerateAccountData();  
   }  
    public void generateData(){  
   AggregateResult[] groupedResults = [SELECT StageName, Count(Id) cnt FROM Opportunity group by StageName];  
     for (AggregateResult ar : groupedResults)   
     {  
        label.add((string)ar.get('StageName'));  
        data.add((integer)ar.get('cnt'));  
     }  
   }  
   public void GenerateLeadData(){  
     AggregateResult[] groupedResults = [SELECT Status, Count(Id) cnt FROM Lead group by Status limit 5];  
     system.debug(groupedResults);  
     for (AggregateResult ar : groupedResults)   
     {  
        Lead_Label.add((string)ar.get('Status'));  
        Lead_Data.add((integer)ar.get('cnt'));  
     }  
     system.debug(Lead_Label);  
     system.debug(Lead_Data);  
   }  
   public void GenerateAccountData(){  
     AggregateResult[] groupedResults = [SELECT AccountSource, Count(Id) cnt FROM Account group by AccountSource ];  
     system.debug(groupedResults);  
     for (AggregateResult ar : groupedResults)   
     {  
        Account_Label.add((string)ar.get('AccountSource'));  
        Account_Data.add((integer)ar.get('cnt'));  
     }  
   }  
 }  


Output:



Reference Link:

https://www.chartjs.org/docs/latest/
Share:
Trailhead Profile


Follow by Email

Total Pageviews

Followers

Popular Posts

Powered by Blogger.

Contact form

Name

Email *

Message *