Search code examples
salesforcevisualforce

Passing STATIC/hardcoded value to controller from visualforce page


I'm creating 8 visualforce pages (VFPs) for a dashboard and because of the similarity of the data needed for each VFP, I'm hoping to leverage a single custom controller (rather than 8 controllers).

The only difference between each VFP will be the WHERE clause of a SOQL statement found in the controller. My thought is to have each VFP pass a static (non-changing/hard-coded) string to the controller to use as in the controller's SOQL WHERE clause. Here's an example of what I'm looking for:

Controller:

public class SalesRev_UpFrontFees {
    public String StageVal {get;set;}
    public Integer salesVal = 0;
    public Integer intTCV;

    public SalesRev_UpFrontFees(){
        getData();
        }

    public void getData() {

    //Insert code to pull the hardcoded 'StageVal' from visualforce pages

    String SoqlString = 'SELECT SUM(Total_Subscription_Fees__c) RevSum\n' +
                  'FROM Opportunity\n' +
                  'WHERE CloseDate >= 2018-01-01 AND CloseDate <= 2018-12-31\n' +
                  'AND Opportunity.RecordType.Name = \'Enterprise Opportunity\'\n' +
                  'AND StageName = \':StageVal\'';

    AggregateResult[] groupedResults = Database.query(SoqlString);

    objTCV = groupedResults[0].get('RevSum');
    intTCV = Integer.valueOf(objTCV);
    salesVal = (intTCV  == null) ? 0 : intTCV ;   
   } 
    /*public void setStageVal(String sStageVal) {
        StageVal = sStageVal;        
        } */

    public Integer getsalesVal() {
        return intTCV;
        }
}

Visualforce Page:

    <apex:page controller="SalesRev_UpFrontFees">

        <head>
            <apex:includeScript value="{!URLFOR($Resource.VFGauge, 'VFGauge/jQuery/jquery-1.10.2.min.js')}" /> 
            <apex:includeScript value="{!URLFOR($Resource.VFGauge, 'VFGauge/jQuery/jquery-ui-1.10.2.custom.min.js')}" /> 

            <apex:includeScript value="{!URLFOR($Resource.Raphael, 'Raphael/resources/js/raphael.2.1.0.min.js')}" /> 
            <apex:includeScript value="{!URLFOR($Resource.Raphael, 'Raphael/resources/js/justgage.1.0.1.js')}" />
            <apex:stylesheet value="{!URLFOR($Resource.Raphael, 'Raphael/styles/style.css')}"/>
        </head>

        <apex:form id="myForm">

            <!--- Insert way to feed the controller a string value, e.g. String StageVal = 'Closed Won'--->

            <body>
                <apex:pageBlock id="xxx"> 
                    <div id="gauge1" style="width:320px; height:256px"></div>
                    <script type="text/javascript"> 

                    var g1 = new JustGage({      
                            id: "gauge1",
                            value: {!salesVal},
                            min: 0,
                            max: 1000000000,
                            title: "WW Sales Revenue",
                            levelColorsGradient: false,
                            gaugeWidthScale: 0.4,
                            valueFontSize: "5px"
                            });
                    </script>
                    <a id="linear-gauge" href=""></a>
                </apex:pageBlock>
            </body>
        </apex:form>
    </apex:page>

I've looked at dozens of posts similar to this, but all existing posts either 1) deal with passing dynamic values (usually defined via JS script) from the VFP to the control VIA a button/selectList/etc. or 2) they deal with passing variables from the controller to the VFP; neither of which are what I need. The closest I got to a solution was by using this source: https://salesforce.stackexchange.com/questions/24666/how-to-pass-javascript-value-to-controller ... but this example required the use of a button on the VFP.

Goes without saying, I'm new to visualforce but have ~4 years of coding experience in Python (which hasn't helped as much as I was hoping). Any example of how to accomplish this would be greatly appreciated!!


Solution

  • Try looking at the < apex:actionFunction > tag with a < apex:param > tag That should get you where you want to go. Action functions let you call a controller method an also lets you pass params assigned to a property with a value that you can set.

    <apex:actionFunction action="{!someMethod}" name="someMethodName" rerender="ifNeeded">
        <apex:param name="stageParam" assignTo="{!StageVal}" value="Closed Won" />
    </apex:actionFunction>
    

    from javascript after load make a call to

    someMethodName('Closed Won')// you may be able to call without params since the value in the param is hard coded but not sure that would be something to test
    

    Update

    So I create a fully working sample page so you could better see it in action.

    VF Page

    <apex:page controller="TestController" >
      <h1>Congratulations</h1>
          This is your new Page: Test
      <apex:form >
          <apex:actionFunction action="{!someMethod}" name="someMethodName" rerender="ifNeeded">
              <apex:param name="stageParam" assignTo="{!StageVal}" value="Closed Won" />
          </apex:actionFunction>
          <apex:outputPanel id="ifNeeded">{!StageVal} {!opps.size}
    
          </apex:outputPanel>
          <script>
              window.onload = function() {
                   someMethodName();//or someMethodName('Closed Lost'); to replace default of param variable
              }
          </script>
       </apex:form>
    </apex:page>
    

    Controller

    public class TestController {
    
        public String StageVal {get;set;}
    
        public List<Opportunity> opps {get;set;}
    
        public PageReference someMethod() {
            opps = [Select Name from Opportunity WHERE StageName = :StageVal];
            return null;
        }
    }
    

    What's happening ... the actionfunction tag declares a js function that would make an async call to the controller, with params listed in the param tag in the order that they appear in. That causes a partial postpack to the serverside controller calling the method designated by the action property of the action function tag, the name of the js method in the name property of the actionfunction tag. As part of a postback properties are updated hence your param becomes available for use in the controller.