Thursday 10 March 2016

Replicate Lightning Experience Opportunity Progress Bar into Salesforce Classic UI

In Salesforce Experience, we have seen a beautiful progress bar on Opportunity displaying different stages of sales path wherein current stage, completed stages and uncompleted stages in different colors.
How about we could display the same in Salesforce Classic?  Amazing, Right!
I had a similar requirement in one of my projects and I implemented it using Salesforce Lightning Design System (SLDS) and referring to one of the Bob Buzzard blog for one of my steps.
Don't forget to upload SLDS as static resource from https://www.lightningdesignsystem.com/resources/downloads/ 
Below are some screenshots showing the final progress bar view in Classic UI.








Note: The progress bar is non-editable at this moment. It can be further customized to make it editable.


Apex Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
public with sharing class ProgressBarVisualforce_cls
{
    //Attributes for parsing picklist values
    public List<String> pickListVals {get; set;}  //list to hold picklist values on a given record type
    public String valsText {get; set;}
    public Boolean loadOnce {get; set;}
    private Opportunity opp;
   
    //attributes for segregating picklist values
    public String sCurrentStageValue {get; set;}
    public list<String> listCompletedStages {get; set;}
    public list<String> listNotCompletedStages {get; set;}
   
    public map<Integer, String> mapStageNr2StageValue ;
    public map<String, Integer> mapStageValue2StageNr ;
    public Integer sCurrentStageNr ;
   
    public ProgressBarVisualforce_cls(ApexPages.StandardController std){
        sCurrentStageValue = '' ;
        sCurrentStageNr = 0 ;
        mapStageNr2StageValue = new map<Integer, String>() ;
        mapStageValue2StageNr = new map<String, Integer>() ;
        listCompletedStages = new list<String>() ;
        listNotCompletedStages = new list<String>() ;

        String sOpportunityId = ApexPages.currentPage().getParameters().get('Id') ;
        system.debug('Sudhir sOpportunityId:: ' + sOpportunityId) ;
       
        Opportunity oOpportunity = [SELECT Id, Name, toLabel(StageName) FROM Opportunity where Id =: sOpportunityId] ;
        //toLabel is used because Translation Workbench is enabled in my org.
        sCurrentStageValue = oOpportunity.StageName ;
        system.debug('opp.StageName:: ' + opp.StageName) ;
      
        loadOnce=true;
        //reload();
    }

    public void reload(){
        pickListVals=new List<String>();
        Boolean skip=true;
        for (String val : valsText.split(':')){
            if (skip){
                skip=false;
            }else {
                pickListVals.add(val);
            }
        }
        loadOnce=false;
        //
       
        for(Integer i = 0; i < pickListVals.size(); i++){
            mapStageNr2StageValue.put(i+1, pickListVals[i]) ;
            mapStageValue2StageNr.put(pickListVals[i], i+1) ;
        }
        system.debug('Sudhir mapStageNr2StageValue:: ' + mapStageNr2StageValue) ;
        system.debug('Sudhir mapStageValue2StageNr:: ' + mapStageValue2StageNr) ;
       
        if(mapStageValue2StageNr.containsKey(sCurrentStageValue)){
       
            sCurrentStageNr = mapStageValue2StageNr.get(sCurrentStageValue) ;
            system.debug('Sudhir sCurrentStageNr:: ' + sCurrentStageNr) ;
           
            for(Integer i : mapStageNr2StageValue.keySet()){
                if(i < sCurrentStageNr){
                    listCompletedStages.add(mapStageNr2StageValue.get(i)) ;
                } else if(i > sCurrentStageNr){
                    listNotCompletedStages.add(mapStageNr2StageValue.get(i)) ;
                }
            }
           
            system.debug('Sudhir listCompletedStages:: ' + listCompletedStages) ;
            system.debug('Sudhir listNotCompletedStages:: ' + listNotCompletedStages) ;
        }
    }


}

Visualforce page




Please note that this is my first step to implement this. However it may further customized/optimized.