Tag Archives: CONTROLLERS

Simple dashboard using Bootstrap + Chart.js inside Salesforce.com

This post is about  developing a very simple dashboard inside Salesforce.com using Chart.js and Bootstrap. Click here to see this in action

Recently I came across Chart.js which seems to be the simplest way to achieve this. Being a fan of developing things inside Salesforce.com using Bootstrap so decided it to mix with Bootstrap (a bit).

Benefits —

Looks beautiful

Animates

Responsive

Light weight

To get started with it you need to download package available at Chart.js website and upload it to your Salesforce.com org as Static Resource as name chart

http://www.chartjs.org/

graphweb

In our case the  path become like this

{!URLFOR($Resource.chart,'Chart.js-master/Chart.js')}

To use bootstrap with this I have used bootstrap’s CDNs.

bootstrap

Bootstrap3 – http://getbootstrap.com/

The implementation of chart.js is very straight forward and we only need to define the dataset/datastructure to draw the charts . Label denotes the labels you want to put across and supply the values with repect to them. Below is the complete code, I have tried to keep it as simple as I can.

Visualforce Page 1 – for Bar and curve chart

1

 
     
     
        
            Charts
            
            
            
            
        
      
          
         

Controller for above page –

public class ChartCreatorCls {
    public Integer prospecting {get;set;}
    public Integer qualification {get;set;}
    public Integer needsAnalysis {get;set;}
    public Integer valueProposition {get;set;}
    public Integer iDDecisionMakers {get;set;}
    public Integer perceptionAnalysis {get;set;}
    public Integer proposalOrPriceQuote {get;set;}
    public Integer negotiationOrReview {get;set;}
    public Integer closedWon {get;set;}
    public Integer closedLost {get;set;}
    
     
    public chartCreatorCls(){
         
        prospecting = 0;
        qualification = 0;
        needsAnalysis = 0;
        valueProposition = 0;
        iDDecisionMakers = 0;
        perceptionAnalysis = 0;
        proposalOrPriceQuote = 0;
        negotiationOrReview = 0;
        closedWon =  0;
        closedLost = 0;
               
        generateData();
         
     
    }
     
     
    
   public void generateData(){
    
    
    AggregateResult[] groupedResults  = [SELECT StageName, Count(Id) cnt FROM Opportunity group by StageName];
 
        for (AggregateResult ar : groupedResults)  {
            if(ar.get('StageName').equals('Prospecting'))
                prospecting = (Integer) ar.get('cnt');
            if(ar.get('StageName').equals('Qualification'))
                qualification = (Integer) ar.get('cnt');    
            if(ar.get('StageName').equals('Needs Analysis'))
                needsAnalysis = (Integer) ar.get('cnt'); 
            if(ar.get('StageName').equals('Value Proposition'))
                valueProposition = (Integer) ar.get('cnt'); 
            if(ar.get('StageName').equals('Id. Decision Makers'))
                iDDecisionMakers  = (Integer)  ar.get('cnt'); 
            if(ar.get('StageName').equals('Perception Analysis'))
                perceptionAnalysis = (Integer) ar.get('cnt'); 
            if(ar.get('StageName').equals('Proposal/Price Quote'))
                proposalOrPriceQuote =(Integer) ar.get('cnt'); 
            if(ar.get('StageName').equals('Negotiation/Review'))
               negotiationOrReview  =(Integer) ar.get('cnt'); 
            if(ar.get('StageName').equals('Closed Won'))
               closedWon = (Integer) ar.get('cnt'); 
            if(ar.get('StageName').equals('Closed Lost'))
               closedLost  = (Integer) ar.get('cnt');       
        }
    }
 
}

Visualforce Page 2 – Donut and Radar Chart
1


 
    
        Charts
        
        
        
        
    
    
        
        
public class ChartCreatorCls2 {
 
     
    public Integer openNotContacted {get;set;}
    public Integer workingContacted {get;set;}
    public Integer closedConverted {get;set;}
    public Integer closedNotConverted {get;set;}
     
     
    public chartCreatorCls2(){
 
         
        openNotContacted = 0;
        workingContacted =0; 
        closedConverted = 0;        
        closedNotConverted = 0;       
        generateData();
         
     
    }
     
     
 
    
   public void generateData(){
        AggregateResult[] groupedResults  = [SELECT Status, Count(Id) cnt FROM Lead group by Status];
 
        for (AggregateResult ar : groupedResults)  {
            if(ar.get('Status').equals('Open - Not Contacted'))
                openNotContacted = (Integer) ar.get('cnt');
            if(ar.get('Status').equals('Working - Contacted'))
               workingContacted = (Integer) ar.get('cnt');    
            if(ar.get('Status').equals('Closed - Converted'))
                closedConverted = (Integer) ar.get('cnt'); 
            if(ar.get('Status').equals('Closed - Not Converted'))
                closedNotConverted  = (Integer) ar.get('cnt'); 
              
        }
   } 
}

You can see this in action here.

Visualforce Remote Objects

Salesforce launched Visualforce Remote Objects with Spring’14 release.

Note: This feature is currently available as developer preview.

Visualforce remote objects are proxy objects that you can use to perform DML operations on Saleforce objects and these do not counts towards API limits.

Benefits of using Remote Objects:

1. No need to use controllers or extensions.

2. Reduces the need for @RemoteAction methods in an Apex controller or extension.

3. No test classes.

Let’s go thru an example

In this example I have tried to search accounts based on their type.

1.First of all we need to define about the object we are going to use.

<apex:page>

    <apex:remoteObjects >

          <apex:remoteObjectModel name=”Account” fields=”Name” jsShorthand=”ac”>

                <apex:remoteObjectField name=”Type” jsShorthand=”ty”></apex:remoteObjectField>

        </apex:remoteObjectModel>

    </apex:remoteObjects>

Here, <apex:remoteObjects >  tag  is used to define the block were we will include everything related to Remote Objects.

This   <apex:remoteObjectModel name=”Account” fields=”Name” jsShorthand=”ac”>  is being used to  define the object on which the DML operations will be performed. Attribute name is used to hold the API name of the Object, fields attribute holds the fields you want to perform DML upon and jsShorthand is the shorthand notation for the object that you can use with the javaScript.

<apex:remoteObjectField name=”Type” jsShorthand=”ty”></apex:remoteObjectField> is being used to refer the fields if you additionally want to add some conditions in your DML operation.

Let’s go on the javaScript code

<script type=”text/javaScript”>

        function retrieveAccount(){

            clear();                     //calling clear method to clear the existing records if shown in table

            var t = document.getElementById(“srch”).value;      //getting the value from input box

            var acc = new SObjectModel.Account();                 // this defines the object on which we going to perform operations

// the below code will retrieve the 100 records from account object where Type field of the record is equal to the type defined in input box on page and will display records as part of a table.

            var acnt = acc.retrieve({where: {ty: {eq: t }},limit : 100},

                       function(err,records){

                           if(err){

                               alert(“Encountered Error”+err.message);

                           }

                           else{

                               records.forEach(

                                   function(record){

                                       var name = record.get(“Name”);

                                       var row = document.createElement(“tr”);

                                       row.appendChild(document.createTextNode(name));

                                       var table = document.getElementById(“accountTable”);

                                       table.appendChild(row);

                                }   

                               );

                           }

                        }

            );

        }

        function clear(){   // clear function to clear the existing records on page.

            document.getElementById(“accountTable”).innerHTML = “”;

        }

        </script>

Enter account type here:<input id=”srch”></input>  <!–Input box –>

    <button onclick=”retrieveAccount()”>Search</button>  <!–button which on click will javaScript method retrieveAccount –>

    <table id=”accountTable” border=”1″ cellspacing=”10″></table> <!–table that will hold records–>

</apex:page>

Now you can take a look at the functionality, this feature also works on Salesforce1 !!

Image