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

  • 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 '17 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 '17 at 17:20
  • @RSG - Yes thanks, but screen is not rendering with anything.. Its breaking my earlier logic !! – user4567570 Jun 13 '17 at 17:21
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;
    }
}
  • 1
    Integer.valueOf(selectedNumber) is not necessary; it's already an Integer. – sfdcfox Jun 13 '17 at 17:04
  • @sfdcfox Right, I just copied an pasted what was there. Good catch. – Andrew L. Jun 13 '17 at 17:06
  • You're missing the parameter in the JavaScript function. Should be function initCharts(selectedNumber) {} – Andrew L. Jun 13 '17 at 17:14
  • I added my whole code, so that one can try to provide the solution.. – user4567570 Jun 13 '17 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 '17 at 17:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.