1

I am developing Visualforce Charts with JavaScript Remoting & Google Charts API. In this example, I am looking to pass selectedNumber to the

GoogleChartsController

global with sharing class GoogleChartsController{
    public static String selectedNumber {get; set; }

    @RemoteAction
    global static Opportunity[] loadOpps() {
        System.debug('Selected Number : '+selectedNumber);
        if(selectedNumber != null){
            Integer intValue = Integer.valueOf(selectedNumber);
            return [SELECT Id, Name, ExpectedRevenue, Amount FROM Opportunity ORDER BY CreatedDate DESC LIMIT :intValue];
        }
        else
            return [SELECT Id, Name, ExpectedRevenue, Amount FROM Opportunity ORDER BY CreatedDate DESC LIMIT 5];
    }

    global GoogleChartsController(){}

    global List<SelectOption> getdynamiclist() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('PieChart','PieChart'));
        options.add(new SelectOption('Histogram','Histogram'));
        return options;
    }

    global List<SelectOption> getdynamicNumbers() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('10','10'));
        options.add(new SelectOption('20','20'));
        options.add(new SelectOption('50','50'));
        return options;
    }
}

GoogleChartsControllerVFPage

<apex:page controller="GoogleChartsController" sidebar="false">
     <!-- Google API inclusion -->
    <apex:includeScript id="a" value="https://www.google.com/jsapi" />
    <apex:sectionHeader title="Google Charts + Javascript Remoting" subtitle="Demoing - Opportunities by Exepected Revenue" />

    <div id="theF">
        <apex:form id="theForm">
            <b>Chart Type : </b> 
            <apex:selectList size="1" styleclass="chartBlock" onchange="initCharts()">
                <apex:selectOptions value="{!dynamiclist}"></apex:selectOptions>
            </apex:selectList>

            <b>Opportunity Size : </b> 
            <apex:selectList multiselect="false" size="1" label="Type" styleclass="chartBlock" onchange="initCharts()">
                <apex:selectOptions value="{!dynamicNumbers}"></apex:selectOptions>
            </apex:selectList>
        </apex:form> 
    </div>   

    <div id="chartBlock">
        <script>
            // Load the Visualization API and the piechart package.
            google.load('visualization', '1.0', {'packages':['corechart']});

            // Set a callback to run when the Google Visualization API is loaded.
            google.setOnLoadCallback(initCharts);

            function initCharts(selectedNumber){
                GoogleChartsController.loadOpps(
                    function(result, event){
                         var e = document.getElementsByClassName("chartBlock")[0];
                         var strUser = e.options[e.selectedIndex].value;

                        // load Column chart
                        var visualization = null;
                        if(strUser == 'PieChart')
                            visualization = new google.visualization.PieChart(document.getElementById('chartBlock'));
                        else if(strUser == 'Histogram')
                            visualization = new google.visualization.Histogram(document.getElementById('chartBlock'));

                         // Prepare table model for chart with columns
                         var data = new google.visualization.DataTable();
                         data.addColumn('string', 'Opportunity');
                         data.addColumn('number', 'Expected Revenue');
                         data.addColumn('number', 'Amount'); 

                         // add rows from the remoting results
                         for(var i =0; i<result.length;i++){
                            var r = result[i];
                            data.addRow([r.Name, r.ExpectedRevenue, r.Amount]); 
                          }
                        // all done, lets draw the chart with some options to make it look nice.
                        visualization.draw(data, {legend : {position: 'top', textStyle: {color: 'blue', fontSize: 10}}, width:window.innerWidth,vAxis:{textStyle:{fontSize: 10}},hAxis:{textStyle:{fontSize: 10},showTextEvery:1,slantedText:false}});
                }, {escape:true});
            }
        </script>
    </div>
</apex:page>

When I selected any number from the drop down list, value always goes null. why ?

enter image description here

Added screen shot: enter image description here

3
  • RemoteAction methods would not pass state to the controller. This is why value is coming null in controller. You need to pass value explicitly. The answer given below will work.
    – RSG
    Jun 13, 2017 at 17:06
  • you forgot to include selectedNumber while defining variable in function. Compare the code, it should be like 'function initCharts(selectedNumber){.....}.'
    – RSG
    Jun 13, 2017 at 17:20
  • @RSG - Yes thanks, but screen is not rendering with anything.. Its breaking my earlier logic !! Jun 13, 2017 at 17:21

1 Answer 1

0

If you are going to use a remote action you need to pass in selectedNumber as a parameter.

Page:

<apex:page controller="GoogleChartsController" sidebar="false">
     <!-- Google API inclusion -->
    <apex:includeScript id="a" value="https://www.google.com/jsapi" />
    <apex:sectionHeader title="Google Charts + Javascript Remoting" subtitle="Demoing - Opportunities by Exepected Revenue" />

    <div id="theF">
        <apex:form id="theForm">
            <b>Chart Type : </b> 
            <apex:selectList id="dynamicList" size="1" styleclass="chartBlock" onchange="initCharts()">
                <apex:selectOptions value="{!dynamiclist}"></apex:selectOptions>
            </apex:selectList>

            <b>Opportunity Size : </b> 
            <apex:selectList id="dynamicNumbers" multiselect="false" size="1" label="Type" styleclass="chartBlock" onchange="initCharts()">
                <apex:selectOptions value="{!dynamicNumbers}"></apex:selectOptions>
            </apex:selectList>
        </apex:form> 
    </div>   
    <div id="chartBlock"></div>
    <div id="histogramBlock"></div>
    <script>
        // Load the Visualization API and the piechart package.
        google.load('visualization', '1.0', {'packages':['corechart']});            
        // Set a callback to run when the Google Visualization API is loaded.
        google.setOnLoadCallback(initCharts);

        function initCharts() {
            var selectedNumber = document.getElementById('{!$Component.theForm.dynamicNumbers}').value;
            GoogleChartsController.loadOpps(
                selectedNumber,
                function(result, event) {
                    var selectedChart = document.getElementById('{!$Component.theForm.dynamicList}').value;
                    // load Column chart
                    var visualization = null;  
                    if (selectedChart === 'PieChart') {
                        visualization = new google.visualization.PieChart(document.getElementById('chartBlock'));
                    }
                    if (selectedChart === 'Histogram') {
                        visualization = new google.visualization.Histogram(document.getElementById('histogramBlock'));
                    }
                    // Prepare table model for chart with columns
                    var data = new google.visualization.DataTable();
                    data.addColumn('string', 'Opportunity');
                    data.addColumn('number', 'Expected Revenue');
                    data.addColumn('number', 'Amount'); 

                    // add rows from the remoting results
                    for(var i =0; i < result.length;i++){
                        var r = result[i];
                        data.addRow([r.Name, r.ExpectedRevenue, r.Amount]); 
                    }
                    // all done, lets draw the chart with some options to make it look nice.
                    visualization.draw(data, {legend : {position: 'top', textStyle: {color: 'blue', fontSize: 10}}, width:window.innerWidth,vAxis:{textStyle:{fontSize: 10}},hAxis:{textStyle:{fontSize: 10},showTextEvery:1,slantedText:false}});
                }, {escape:true}
            );
        }
    </script>
</apex:page>

Controller:

global with sharing class GoogleChartsController {

    global GoogleChartsController() {}

    @RemoteAction
    global static Opportunity[] loadOpps(Integer selectedNumber) {
        if (selectedNumber != null) {
            return [SELECT Id, Name, ExpectedRevenue, Amount FROM Opportunity ORDER BY CreatedDate DESC LIMIT :selectedNumber];
        } else {
            return [SELECT Id, Name, ExpectedRevenue, Amount FROM Opportunity ORDER BY CreatedDate DESC LIMIT 5];
        }
    }

    global List<SelectOption> getdynamiclist() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('PieChart','PieChart'));
        options.add(new SelectOption('Histogram','Histogram'));
        return options;
    }

    global List<SelectOption> getdynamicNumbers() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('10','10'));
        options.add(new SelectOption('20','20'));
        options.add(new SelectOption('50','50'));
        return options;
    }
}
9
  • 1
    Integer.valueOf(selectedNumber) is not necessary; it's already an Integer.
    – sfdcfox
    Jun 13, 2017 at 17:04
  • @sfdcfox Right, I just copied an pasted what was there. Good catch.
    – Andrew L.
    Jun 13, 2017 at 17:06
  • You're missing the parameter in the JavaScript function. Should be function initCharts(selectedNumber) {}
    – Andrew L.
    Jun 13, 2017 at 17:14
  • I added my whole code, so that one can try to provide the solution.. Jun 13, 2017 at 17:29
  • @user4567570 I provided the solution why the Integer was null, but you will need to refactor other parts of the page and functionality around that solution.
    – Andrew L.
    Jun 13, 2017 at 17:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .