Category Archives: Visualforce

Visualforce related blog posts

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.

Force.com Winter 15 Visualforce Enhancements

So Force.com’s winter release has arrived with lots of new features. There are various new enhancements to Visualforce in this release that are very important for developers, so here are these

2014-09-09 17_23_00-Salesforce.com Winter ’15 Release Notes - salesforce_winter15_release_notes.pdf

1. Remote Objects for Visualforce are now generally available with this release, if you are not familiar about these you can follow up my previous post http://forceexperiment.wordpress.com/2014/03/12/visualforcce-remote-objects/

2. Standard Style Sheets are combined in Visualforce now, this will reduce the number of network connections made during the load of a single page and will greatly improve the performance of a page.The content of this combination is unchanged so you don’t need to worry about references to make and you don’t need to do anything to make use of this enhancement.

3. Preserve sObject Field Encryption in Visualforce Expression, In Visualforce pages set to API  32.0 or above expressions that points to encrypted sObject Fields will return encrypted values instead of plain values. Visualforce pages set to API version 31.0 or earlier continue to display decrypted values for encrypted sObject fields, except when displayed by using <apex:inputField> and <apex:outputField>

 

 

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

Salesforce1 Development [using Google Chrome]-Part 1

6a00d83451ba7369e2019b0234ddcf970c-320wi

In Dreamforce’13 Salesforce1 was announced , a new mobile app for Salesforce platform,that makes the platform easier to use.

Available for :

1.iOS 6+

2.Android 4.2+

We can do development with Salesforce1 right from the Google Chrome browser on our Desktop.

First of all we need to make sure that the user have rights to access the salesforce1 .

In-order to make the user capable to access salesforce1 we need to grant access to that user , that we can do by Manage Users>Users>Edit [in front of that user]>check the check box “Salesforce1 User”.

UntitledSecond thing to do is to allow the salesforce1 to run as the mobile browser app right from our desktop web browser , to do this go to  Mobile Administration>Salesforce1

UntitledThen check the check box “Enable the Saleforce1 mobile browser app”

UntitledNow by doing so we can simply access the mobile app right from our desktop [by using google chrome only]

To do that simply prefix /one/one.app after your salesforce instance in the address bar of  our google chrome browser.

For example my instance is https://ap1.salesforce.com

So the URL to access the salesforce platform becomes like this :

https://ap1.salesforce.com/one/one.app

When we go on this URL we get following screen with a cool salesforce logo

Untitled

Home page is like this :

UntitledNow if we need to test this app according to the end user device and configuration we can do it by pressing F12 or right-click to Inspect Element.

UntitledNow we can see the inspect element section [Developer Tools]

UntitledNow click on the Elemens Tab and then the Gear Icon [as highlighted in the above image by red squares].

Now settings will open up where we need to select Overrides , here we can change the user agent and simulate the behavior  of this app on the respective device.

Untitled

Visualforce Developer’s Guide: A book review.

If you are looking for a guide to learn visualforce then a new guide has arrived, that is well organized for both newbies and advance developers. Thanks to @chamilmadusanka for putting all his hardwork in this book.

9818EN_Cover

I got a chance to review this book(Thanks to Packt Publishing and Sagar Malage ) and here are my thoughts :

1.This book is having 8 chapters with step by step things to follow ,it covers basics in the first chapter to advance level in the final chapter.

2.Key point of this book is best practices  and security tips for the visualforce are also included.

3.Steps are detailed and easy to follow, you hardly miss anything that visualforce have.

Following are the chapter wise things i liked and which i think that makes this book different

1.Chapter One: Advantages of visualforce.

2.Chapter Two:  Working with large sets of data on visualforce page.

                          Using Transient Keyword

                         Considerations for creating custom controllers and controller extensions ( That is         again as i said is part of best practices).

3.Chapter Three: I liked the way javascript and jQuery  explained in this chapter.

4.Chapter Four: Good  brief description about custom components

5.Chapter Five: Detailed discussion about dynamic binding .

6.Chapter Six: Visualforce Charting: This a must read chapter if you have never touched the charting part of visualforce best effort are made by author to explain . I also got good knowledge from this chapter.

7.Chapter Seven : Going Mobile with visualforce? Take look at this chapter, nicely written and explained .I recommend developers who are looking to learn the mobile part of visualforce to start with this book .

8.Chapter Eight: It includes best practices part, that most books miss.

I loved the way this book ends with Security tips.

Why to go for this book?

1.Easy and quick to understand.

2.Hands-on Approach

3.Basic development to Mobile Development Included.

4.Security and Best Practices Included.

You can buy this book from here : http://bit.ly/Ii5X6p

Chatter Actions

Recently i had a requirement with salesforce’s new feature Chatter Publisher Actions. I struggled to understand what it is and how it works and finally learned it ! So making it easier for all others like me here comes my post to understand this new feature. And as Mark Benioff already announced that chatter will become primary interface for salesforce. I believe its necessary to post about it.

So it was a big paragraph? Let come directly on the point !

Chatter Actions

A new feature which allows us to create actions and they can be added on:

1.Chatter Publisher on Home Page.

2.The Chatter Tab.

3.Record Detail Pages.

Type of Actions

1.Create Actions  : you can create a record on target object.

2.Custom Actions : let you define your own custom action. (Note that these are visualforce pages).

We can create actions that let user create these types of records:

Account, Campaign, Case, Contract, Contact, Custom Objects, Event (without invitees), Lead, Opportunity and Task.

These Actions can be specifically categorized as

1.Object Specific. (Supported Objects: Account, Campaign, Case, Contract, Custom Objects, Lead and Opportunity.) Remember the visualforce page you are going to bind it with Object specific action must have its standard controller of that object.

2.Global Actions: lets you create actions that are available globally .

Enable Chatter Actions:

Under Chatter>Settings>Publisher Actions>Enable Publisher Actions.

1 step

Now lets take an example:

Suppose you want to add a contact record to an account record by using object specific actions

In this case your object specific action will be defined on Account.

So go under Customize>Accounts>Buttons, Links and Actions

2 step

on the next screen click on New Action

You have to define action like this :

step3

Click Save

Now comes the last part Adding this Action to Page Layout

Customize>Accounts>Page Layouts 

edit Account Layout

Now you can see a additional Option as Actions

4 step

Now before dragging Add Contact Action to layout don’t forget to click on “override the global layout“.

The reason behind this is you are setting a customized list of actions for this layout and no more need the default functionality anymore.

5 step

Now drag your action

55step

Now save this layout.

Now if there is feed enabled for accounts you will be able to see your created action like this

axtion

NOTE :If you want to  use a custom action make sure you have a visualforce page that is having a standard controller for that object.At the time of defining the custom action you will see only those visualforce pages who have  standard controller for that object for which you are defining the custom action.

Thank you for reading this post.