5

I'm trying to rerender two apex chart components after a form field change, and can only seem to rerender one of them.

Here's my page:

<apex:page showHeader="false" sidebar="false" controller="chartTestCtrl">
    <style>
        .chartContainer {
            width: 700px;
            background: #57b6dd;
            text-align: center;
            display: inline-block;
            margin-right: 10px;
        }
        .chartContainer h1, .chartContainer h2 {
            display: block;
            color: #000;
        }
        .chartContainer h1 {
            padding: 20px 0 10px 0;
            font-size: 30px;
            font-weight: 300;
        }
    </style>
    <apex:form id="chartsForm">
        <apex:outputPanel id="charts">
            <apex:repeat value="{!charts}" var="chart">
                <div class="chartContainer">
                    <h1>
                        Chart {!chart.chartNumber}
                    </h1>
                    <apex:inputText value="{!chart.chartNumber}">
                        <!-- Subsituting any of the below actionSupport components does not change the result -->
                        <!-- <apex:actionSupport action="{!doSomething}"
                                event="onchange"
                                reRender="{!Component.charts}"/> -->
                        <!-- <apex:actionSupport action="{!doSomething}"
                                event="onchange"
                                reRender="charts"/> -->
                        <!-- <apex:actionSupport action="{!doSomething}"
                                event="onchange"
                                reRender="chartsForm"/> -->
                        <apex:actionSupport action="{!doSomething}"
                                event="onchange"
                                reRender="{!$Component.chartsForm}"/>
                    </apex:inputText>
                    <span id='chart-{!chart.chartNumber}'>&nbsp;</span>
                    <apex:chart height="400" width="700" legend="true" data="{!chart.data}"
                                renderto="chart-{!chart.chartNumber}" rendered="true">
                        <apex:axis type="Category" position="bottom" fields="category"/>
                        <apex:axis type="Numeric" minimum="0" maximum="5" position="left" fields="value"/>
                        <apex:barSeries orientation="vertical" title="Bar Series" axis="bottom" 
                                xField="category" yField="value"/>
                    </apex:chart>
                </div>
            </apex:repeat>
        </apex:outputPanel>
    </apex:form>
</apex:page>

and my controller:

public with sharing class chartTestCtrl {

    private static Integer COUNT = 0;

    public List<Chart> charts {get;set;}

    public chartTestCtrl() {
        charts = new List<Chart> {
            new Chart(),
            new Chart()
        };
    }

    public void doSomething() { }

    public class Chart {
        public Integer chartNumber {get;set;}
        public List<Data> data {get;set;}

        public Chart() {
            COUNT++;
            chartNumber = COUNT;
            data = new List<Data> {new Data()};
        }
    }

    public class Data {
        public String category {get;set;}
        public Integer value {get; set;}

        public Data() {
            category = 'C ' + COUNT;
            value = COUNT;
        }
    }
}

And the resulting output:

initial

Output after changing the first chart form field to '3':

first form field changed

Output after changing the second chart form field to '4':

enter image description here

The rerender seems to be only able to generate one chart, and that's the chart closes to the actionSupport component. How do I modify the page/controller so both charts can be rerendered?

3
  • the doSomething() -- does it iterate through both charts in chartList and refresh with data based on the value of chartNumber ? Perhaps that is where the problem lies
    – cropredy
    Dec 15 '15 at 20:30
  • The doSomething() method doesn't do anything! All the information required to rerender both charts is always available, but only one chart is ever rerendered.
    – bafuda
    Dec 16 '15 at 17:03
  • ah, I misunderstood - I thought you were cycling through various charts that were dynamically constructed.
    – cropredy
    Dec 16 '15 at 17:13
2

This appears to currently be a known issue with charts and the apex:repeat tag. The known issues article in the salesforce success community identifies a workaround for the problem to fall back to some raw html.

However you appear to have tried that workaround and it still fails.

I have copied your code and have tried numerous variations to get it to work based on the proposed workaround, but I am not having any success.

Bottom line. I think this is a bug. And if the workaround ever worked, it doesn't appear to anymore. Please file a case with support. If you are a developer not affiliated with a customer org, you can post this to the developer forums and developer support will rase a case from there.

3
  • nice! although I didn't see the raw HTML attempt in OP (there is still a repeat)
    – cropredy
    Dec 16 '15 at 21:14
  • <span id='chart-{!chart.chartNumber}'>&nbsp;</span> is intended to be the place that the apex:chart component is set to render to. I tried multiple variants of that, with span and div tags. Fixed renderTo to be case-sensitive, and even subbed different iterating components like dataTable and pageBlockTable. No love on anything I tried.
    – pchittum
    Dec 17 '15 at 0:24
  • I've posted it to the forms here developer.salesforce.com/forums/ForumsMain?id=906F0000000MIMS. In my case I was able to put the charts in an iframe and refresh the whole page, which does seem to work. In general I think JS Remoting would be a better approach: developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/…
    – bafuda
    Dec 17 '15 at 17:48
3

The reRender attribute takes a literal, comma-delimited set of id's.

reRender="thiscomponent,thatcomponent,theothercomponent"

In your case, I would think you could simply do the following:

reRender="charts"
1
  • Thanks for the suggestion, but the results seem to be the same.
    – bafuda
    Dec 15 '15 at 19:41

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.