Wednesday, 12 April 2017

Use static resource in Visualforce – Salesforce

Force.com platform provides us a facility to upload, manage and use the content that is static (not changing) for your organization, and it can be stored under “Static Resources“. It can be a Javascript file, CSS file, an image or even a zip file containing all the files required in one zip file. Today we’ll see how to use static resource in Visualforce – Salesforce.
Below are the ways to use the static resources in our visualforce pages:
Suppose there is a single file like any single image or standalone css file, that you need to refer in your VF page, then you can directly use the “$Resource.resourceName” to refer the static resource where ‘$Resource‘ is a global variable to use any static resource within visualforce page. You need not to hard code the path of the static resource in VF page code. Below are some examples of the same.
Suppose you have an image file uploaded in static resource with name “Z_test” as shown below in the screenshot.
Static resource
You can refer this image in your code using expression {$Resource.Z_Test}. Below are some other examples as well:
<!-- An image can be referenced like this -->
<img src="<strong>{!$Resource.Z_Test}</strong>"/>
 
<!-- Similarly any CSS file can be referenced like below -->
<apex:stylesheet value="<strong>{!$Resource.sampleCss}</strong>"/>
You need to remember only the keyword “$Resource” and the name of the static resource and not the name of actual file.
Similarly when we have the bundle of files, uploaded as a zip file in static resources section, then along with the name of static resource, you have to give the path to the file within the context of the archived zip.
Suppose below is the directory structure of the zip file with the name “bootstrap” that you have uploaded, in which you have three different folders for storing CSS, images, and JS files respectively.
Static resource archive structure
So, to reference a particular file at a given location, you need to give the path of the file in context of the zip, along with the name of static resource while referencing in Visualforce page code. For this we have to use a function called “URLFOR(nameOfStaticResource, RelativePathOfFile)”. Below code snippets shows you how to refer the particular files.
<meta charset="utf-8" />Force.com Developer<meta name="viewport" content="width=device-width, initial-scale=1.0" />
 
<!-- Static Resources for CSS -->
<apex:styleSheet value="{!URLFOR($Resource.bootstrap, 'bootstrap/css/bootstrap.css')}"/>
<apex:styleSheet value="{!URLFOR($Resource.bootstrap, 'bootstrap/css/bootstrap-responsive.css')}"/>
 
<!-- Static Resource for individual imag -->
<image src="{!URLFOR($Resource.bootstrap, 'img/glyphicons-halflings.png')}"/>
Above we explained the two ways of using the static resources in visualforce page, one for single file, another for the files within a zipped static resources file.
Hope this will help you in your coding.

Saturday, 8 April 2017

Dynamic Visualforce Chart in Salesforce with JQuery:

Here are the sample Code with the help of that you can also build a rich JQuery Chart in salesforce.But before you start on code you must have to create an object for storing the Chart Data. Sample object fields are given below
Custom Controller Apex Code to get the dynamic data from Salesforce.
public class ChartController
{
    private String xAxis;
    private String series1;
    private String series2;
    private String series3;
    private String series4;
    private String series5;

    public ChartController()
    {
        list<string> xAxisValues = new list<string>();
        list<decimal> series1Values = new list<decimal>();
        list<decimal> series2Values = new list<decimal>();
        list<decimal> series3Values = new list<decimal>();
        list<decimal> series4Values = new list<decimal>();
        list<decimal> series5Values = new list<decimal>();
       
        string strYear = string.valueof(system.Today().Year());
        for(Chart_POC__c obj :[select Id,Name,cccInfo__Pipeline_Value__c,cccInfo__X1X_Value__c,cccInfo__X2X_Value__c,
                                cccInfo__X3X_Value__c,cccInfo__X4X_Value__c
                                 from cccInfo__Chart_POC__c where cccInfo__Year__c =: strYear])
        {
            string strX = (obj.Name+'-'+strYear);
            xAxisValues.add(strX);
            series1Values.add(obj.cccInfo__X1X_Value__c);
            series2Values.add((obj.cccInfo__X2X_Value__c - obj.cccInfo__X1X_Value__c));
            series3Values.add((obj.cccInfo__X3X_Value__c-obj.cccInfo__X2X_Value__c));
            series4Values.add((obj.cccInfo__X4X_Value__c-obj.cccInfo__X3X_Value__c));
            series5Values.add(obj.cccInfo__Pipeline_Value__c);
        }
       
        xAxis = JSON.serialize(xAxisValues);
        series1 = JSON.serialize(series1Values);
        series2 = JSON.serialize(series2Values);
        series3 = JSON.serialize(series3Values);
        series4 = JSON.serialize(series4Values);
        series5 = JSON.serialize(series5Values);
    }
   
    public String getxAxis() {
        return xAxis;
    }

    public String getSeries1() {
        return series1;
    }

    public String getSeries2() {
        return series2;
    }
   
    public String getSeries3() {
        return series3;
    }

    public String getSeries4() {
        return series4;
    }
   
    public String getSeries5() {
        return series5;
    }
}
Visualforce page code with JQuery includes
<apex:page controller="ChartController" standardStylesheets="false" docType="html-5.0" showHeader="false">
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" />
    <apex:includeScript value="https://code.highcharts.com/highcharts.js"/>
    <apex:includeScript value="https://code.highcharts.com/highcharts-3d.js"/>
    <apex:includeScript value="https://code.highcharts.com/modules/exporting.js"/>
    <style>
        #container
        {
            height: 400px;
            min-width: 310px;
            max-width: 800px;
            margin: 0 auto;
        }
    </style>
    <script type="text/javascript">
        $(function (){
            $('#container').highcharts({
                chart: {
                    type: 'column',
                    options3d: {
                        enabled: true,
                        alpha: 15,
                        beta: 15,
                        viewDistance: 25,
                        depth: 40
                    },
                    marginTop: 80,
                    marginRight: 40
                },
                title: {
                    text: ''
                },
                xAxis: {
                    categories: {!xAxis}
                },
                yAxis: {
                    allowDecimals: false,
                    min: 0,
                    title: {
                        text: 'Max Values'
                    }
                },
                tooltip: {
                    headerFormat: '<b>{point.key}</b><br/>',
                    pointFormat: '<span style="color:{series.color}">\u25CF</span> {series.name}: {point.y} / {point.stackTotal}'
                },
                plotOptions: {
                    column: {
                        stacking: 'normal',
                        depth: 40
                    }
                },
                series: [{
                    name: '4X',
                    data: {!series4},
                    stack: 'Target'
                },
                {
                    name: '3X',
                    data: {!series3},
                    stack: 'Target'
                },
                {
                    name: '2X',
                    data: {!series2},
                    stack: 'Target'
                },
                {
                    name: '1X',
                    data: {!series1},
                    stack: 'Target'
                },
                {
                    name: 'PipeLine',
                    data: {!series5},
                    stack: 'PipeLine'
                }]
            });
        });
    </script>
    <div id="container" style="height: 400px"></div>
</apex:page>
Here is the final outcome of the above proctice code

Custom Pagination Example on Visualforce Page in Salesforce:

Here are the sample codes with the help of that you can build custom pagination functionality in Salesforce using Apex. For this you need to create some Visualforce and one Apex Class.

So let’s enjoy the coding!!!!

Custom Controller Apex Code to get the data from Salesforce

public class clsCustomPagination
{
    //Variable Declation for Pagination
    public static Integer ROWS_PER_PAGE = 5;
    public integer pageNum {get; set;}
    public boolean pageHasMore {get; set;}
    public boolean pageHasNext {get; set;}
    public boolean pageHasPrev {get; set;}
    public boolean pageHasFirst {get; set;}
    public boolean pageHasLast {get; set;}
    public list<Opportunity> lstAllOpportunity;
    public list<Opportunity> lstPageOpportunity{get;set;}
    public integer tableRowsPerPage{get;set;}
    public string strCurPosition{get;set;}
    public integer intTotalOpp{get;set;}
    public integer firstIndex {get;set;}
   
    //Class Constructor
    public clsCustomPagination()
    {
        strCurPosition = '';
        pageHasNext = false;
        pageHasPrev = false;
        pageHasFirst = false;
        pageHasLast = false;
        pageNum = 1;
        intTotalOpp = 0;
        tableRowsPerPage = 15;
        lstAllOpportunity = new list<Opportunity>();
        lstPageOpportunity = new list<Opportunity>();
       
        lstAllOpportunity = [SELECT Account.Name,AccountId,Amount,CampaignId,CloseDate,Description,ExpectedRevenue,
                                LeadSource,Name,TotalOpportunityQuantity,Type FROM Opportunity where AccountId != null];
                               
        setPaginationNumber();
        DoPaginationOnList();
    }
   
    public void DoPaginationOnList()
    {
        lstPageOpportunity = new list<Opportunity>();
        firstIndex = ((ROWS_PER_PAGE * pageNum) - ROWS_PER_PAGE) ;
        pageHasMore = pageNum < getTotalPages();
        intTotalOpp = lstAllOpportunity.size();
        System.debug('Opportunity 0 is ' +lstAllOpportunity[0]);
        if(intTotalOpp > 0)
        {
            for(Integer i=firstIndex; i<firstIndex+ROWS_PER_PAGE && intTotalOpp > i; i++)
            {
               lstPageOpportunity.add(lstAllOpportunity.get(i));
            }
           
            if(pageNum >= 1 && pageNum != getTotalPages())
            {
                pageHasNext = true;
                pageHasLast = true;
            }
            else if(pageNum == getTotalPages())
            {
                pageHasNext = false;
                pageHasLast = false;
            }
        }
        else
        {
            pageHasNext = false;
            pageHasPrev = false;
            pageHasLast = false;
            pageHasFirst = false;
        }
        if(lstPageOpportunity.size() == 0)
        {
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'No record found'));
        }
    }
   
    public void firstPage()
    {
        pageNum = 1;
        pageHasPrev = false;
        pageHasNext = true;
        pageHasFirst = false;
        pageHasLast = true;
        setPaginationNumber();
        DoPaginationOnList();
    }
   
    public void previousPage()
    {
        pageNum--;
        if(pageNum <= 0)
        {
            pageHasPrev = false;
            pageHasNext = true;
        }
        else if (pageNum == 1)
        {
            pageHasPrev = false;
            pageHasNext = true;
        }
        else
        {
            pageHasPrev = true;
            pageHasNext = true;
        }
        setPaginationNumber();
        DoPaginationOnList();
    }
   
    public void nextPage()
    {
        pageNum++;
        pageHasPrev = true;
        pageHasFirst = true;
        setPaginationNumber();
        DoPaginationOnList();
    }
   
    public void lastPage()
    {
        pageNum = getTotalPages();
        pageHasPrev = true;
        pageHasNext = false;
        pageHasFirst = true;
        pageHasLast = false;
        setPaginationNumber();
        DoPaginationOnList();
    }
   
    public Integer getTotalPages()
    {
        if(System.Math.mod(lstAllOpportunity.size(), ROWS_PER_PAGE ) == 0)
            return lstAllOpportunity.size() / ROWS_PER_PAGE ;
        else
            return (lstAllOpportunity.size() / ROWS_PER_PAGE ) + 1;
    }
   
    public void setPaginationNumber()
    {
       strCurPosition = 'Page '+ string.valueof(pageNum)+' of ' + string.valueof(getTotalPages());
    }
}

Visualforce Page Code

<apex:page controller="clsCustomPagination" id="idPage">
    <apex:sectionHeader title="Custom Pagination Example" id="idSecHeader"/>
    <style>
        .Processing{
         position: fixed;
         background: url('/img/loading32.gif');
         background-repeat: no-repeat;
         background-position: center;
         width: 100%;
         height: 100%;
         z-index: 10004;
         left: 0%;
         top: 0%;
        }
    </style>
    <apex:form >
        <apex:actionStatus id="idStatus" startStyleClass="Processing" ></apex:actionStatus>
        <apex:pageBlock id="idPB">
            <apex:outputPanel id="pnlOpp">
                <apex:pageBlockTable value="{!lstPageOpportunity}" var="objOpp" id="idPBT">
                    <apex:column value="{!objOpp.Name}"/>
                    <apex:column value="{!objOpp.Account.Name}"/>
                    <apex:column value="{!objOpp.Amount}"/>
                    <apex:column value="{!objOpp.CloseDate}"/>
                </apex:pageBlockTable>
            </apex:outputPanel>
               
            <!-- Start  Pagination Functionality -->
            <apex:outputPanel id="PanelPagination" rendered="{!IF(lstPageOpportunity.size > 0,true,false)}">
                <div style="margin-left:40%;margin-top: 1%;">
                    <table>
                        <tr>
                            <td>
                                <apex:commandButton action="{!firstPage}" disabled="{!NOT(pageHasFirst)}" status="idStatus" id="idBtnFirst" rerender="pnlOpp,PanelPagination" value="|< First"/>
                                <apex:commandButton action="{!previousPage}" disabled="{!NOT(pageHasPrev)}" status="idStatus" id="idBtnPrev" rerender="pnlOpp,PanelPagination" value="Previous"/>
                            </td>
                            <td>
                                <span style="float:left;font-size: 12px !important;font-weight: bold;margin-top: 1.75%;">
                                    <apex:outputLabel id="pageposition" value="{!strCurPosition}"></apex:outputLabel>
                                </span>
                            </td>
                            <td>
                                <apex:commandButton action="{!nextPage}" disabled="{!NOT(pageHasNext)}" status="idStatus" id="idBtnNext" rerender="pnlOpp,PanelPagination" value="Next"/>
                                <apex:commandButton action="{!lastPage}" disabled="{!NOT(pageHasLast)}" status="idStatus" id="idBtnLast" rerender="pnlOpp,PanelPagination" value="Last >|"/>
                            </td>
                        </tr>
                    </table>
                </div>
            </apex:outputPanel>
            <!-- End  Pagination Functionality -->
        </apex:pageBlock>
    </apex:form>
</apex:page>

....and here we are with finale output.

Displaying Duplicate Error and Matching Records on VF Page:

Before going to understand the below code you must have to create a duplicate rule for object which you want to upsert(insert / update) from Visualforce page action button(command button). So to achieve this you have to create a duplicate rule on your Dev Org / SB Org and then create a Visualforce page with custom controller. For e.g.
VF Page Name- MatchingRuleDataDisplay
Class Name- clsMatchingRuleDataDisplay

Custom Controller Apex Code Method in Salesforce

//Adding only method to minimize the code in this post
public void insertUsageData()
{
    //Variable is defined at class level
    hasDuplicateResult = false;
    intUsageDataCount = 0;
  
    //Variable(Property) is defined at class level
    if(lstUsageToInsert.size() > 0)
    {
        //Variable(Property) is defined at class level
        duplicateRecords = new List<sObject>();
      
        // DML statement and perpare your data with your required SObject that has duplicate rule
        Database.SaveResult[] srList = Database.insert(lstUsageToInsert, false);
      
        for (Database.SaveResult sr : srList)
        {
            if (!sr.isSuccess())
            {
                for (Database.Error error : sr.getErrors())
                {
                    if (error instanceof Database.DuplicateError)
                    {
                        Database.DuplicateError duplicateError =  (Database.DuplicateError)error;
                        Datacloud.DuplicateResult duplicateResult = duplicateError.getDuplicateResult();
                      
                        // Display duplicate error message as defined in the duplicate rule
                        ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.Severity.ERROR, 'Duplicate Error: ' +  duplicateResult.getErrorMessage());
                        ApexPages.addMessage(errorMessage);
                      
                        for(Datacloud.MatchResult matchResult : duplicateResult.getMatchResults())
                        {
                            // Add matched record to the duplicate records variable
                            for (Datacloud.MatchRecord matchRecord : matchResult.getMatchRecords())
                            {
                                System.debug('MatchRecord: ' + matchRecord.getRecord());
                                duplicateRecords.add(matchRecord.getRecord());
                            }
                        }
                      
                        hasDuplicateResult = !duplicateRecords.isEmpty();
                    }
                }
            }
        }
      
        if(!hasDuplicateResult)
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm,'Process has been completed successfully.'));
    }
}

Visualforce Page Code

<apex:pageBlock title="Usage Duplicate Records" rendered="{!hasDuplicateResult}">
    <apex:pageBlockTable value="{!duplicateRecords}" var="item">
        <apex:column >
            <apex:facet name="header">Name</apex:facet>
            <apex:outputLink value="/{!item['Id']}" target="_blank">{!item['Name']}</apex:outputLink>
        </apex:column>
        <apex:column >
            <apex:facet name="header">Owner</apex:facet>
            <apex:outputField value="{!item['OwnerId']}"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">Last Modified Date</apex:facet>
            <apex:outputField value="{!item['LastModifiedDate']}"/>
        </apex:column>
    </apex:pageBlockTable>
</apex:pageBlock>
....AND HERE WE ARE WITH FINAL OUTPUT.

Display page block section collapsed on page load in Visualforce page:


While your Visual force page development in Salesforce many of the developer got a requirement from their clients that they want this particular page block section collapsed on page load.
So to achieve this, let’s go one by one step.
I have created one VF page to display the list of contact in page block section. Here is my page and class code.

Class Code-

public class clsTwistSection
{
    public list<Contact> lstCon{get;set;}
   
    public clsTwistSection()
    {
        lstCon = [select Id,Name,Email from Contact];
    }
}

Page Code -

<apex:page controller="clsTwistSection" tabStyle="Contact" id="idPage">
  <apex:sectionHeader title="All" subtitle="Contact Records"/>
  <apex:form id="idForm">
      <apex:pageBlock id="pgBlock">
          <apex:pageBlockSection title="Contact Records" columns="1" id="idPBS">
              <apex:pageBlockTable value="{!lstCon}" var="x">
                  <apex:column value="{!x.Name}"/>
                  <apex:column value="{!x.Email}"/>
              </apex:pageBlockTable>
          </apex:pageBlockSection>
      </apex:pageBlock>
  </apex:form>
</apex:page>
Now your page will look like below-(in this you can see that your page block section is open when page loads.
And your client is asking something like below screen
As we know that when page block section rendered as HTML then we can see below html code. And to get that code just right click on your page block section and you will see that, and in my case here it is-
So to achieve your requirement, put below line code just after page block section tag in your page code
<script> twistSection(document.getElementById("idPage:idForm:pgBlock:idPBS").getElementsByTagName("img")[0]) </script>
And after putting above line your VF page code looks like 
<apex:page controller="clsTwistSection" tabStyle="Contact" id="idPage">
  <apex:sectionHeader title="All" subtitle="Contact Records"/>
  <apex:form id="idForm">
      <apex:pageBlock id="pgBlock">
          <apex:pageBlockSection title="Contact Records" columns="1" id="idPBS">
              
<script> twistSection(document.getElementById("idPage:idForm:pgBlock:idPBS").getElementsByTagName("img")[0]) </script>
              <apex:pageBlockTable value="{!lstCon}" var="x">
                  <apex:column value="{!x.Name}"/>
                  <apex:column value="{!x.Email}"/>
              </apex:pageBlockTable>
          </apex:pageBlockSection>
      </apex:pageBlock>
  </apex:form>
</apex:page>
So when you save the changes you just made, you will get the required output on page load.