5

I'm using a commandLink which calls a Javascript function as below:

<apex:commandlink onClick="downloaditem();" reRender="newItems" rendered="{!cmdrender}">
    Download
</apex:commandlink>

My Javascript is:

<script type="text/javascript">
function downloaditem()
{
  var SFObjectArray = new Array();
  var s = '{!chatteridforscript}';
  alert(s);
  <apex:repeat value="{!chatteridforscript}" var="arrayItem">
    SFObjectArray.push('{!arrayItem}');
  </apex:repeat>

  var url = '{!url}';
  for (var i = 0; i < SFObjectArray.length; i++)
  {
    window.open(url + SFObjectArray[i] );
  }
  clearitem();
}

My issue is the value used in the apex:repeat component in my Javascript ({!chatteridforscript}) is not correct, although I can clearly see the controller variable getting set properly.

What am I doing wrong?

7

Make sure that the script is within an area that is to be rerendered, either by placing it within the element called newItems, or in an outputText or outputPanel (or other targetable rerender area), and include that element's ID within the rerender attribute for your commandLink.

Example

The example shows a minimal usage of this design.

Controller

public with sharing class rerenderjs {
    public integer counter { get; set; }
    {   counter = 0;
    }
    public void increment() { counter++; }
}

Page

<apex:page controller="rerenderjs">
    <apex:form id="form">
        <script>
        function showCounter() {
            alert({!counter})
        }
        </script>
        <apex:commandLink action="{!increment}" value="Increment" oncomplete="showCounter()" reRender="form"/>
    </apex:form>
</apex:page>
  • That's an interesting solution, and I would have thought that it wasn't possible to re-render Javascript and have it work. Great to know that it's an option! – tomlogic Dec 2 '13 at 22:01
  • 1
    @tomlogic I decided to add an example of how it works, for future wanderers that may see this answer. Maybe it will help you, too. – sfdcfox Dec 3 '13 at 1:25
5

The problem might be that your Javascript code is rendered at page load time. When you "View Source" on your web page, does the Javascript look correct? What does your alert(s); display?

If you need to dynamically read values from chatteridforscript and use them in Javascript, you should consider Visualforce Remoting. You can call a global static method that returns a list, and then iterate through that list in the Javascript code tied to the remote method.

As pointed out by @sfdcfox below, the method called can't see the instance data (the view state), but you can pass parameters (like the Id of the record if you're viewing a detail page) in the remoting call.

  • That is indeed one way to go about it, except you can't get to your instance data (the view state) through a static method directly, which can complicate matters. Of course, you can send parameters to the function, which makes the complication not so bad. – sfdcfox Dec 2 '13 at 19:49
  • @sfdcfox, definite tradeoffs to using remoting. One hack I used was to re-render the value in white-on-white text in an outputText component, and then have the Javascript extract the content dynamically. The remoting seems like the proper way to dynamically pass data from an Apex method to Javascript in the browser. You're right about the view stat and passing parameters; hopefully you can pass a single Id to get at the necessary data. – tomlogic Dec 2 '13 at 19:56
  • Remoting is definitely preferable. You can also get a return value from the callback, too, so no reason why you wouldn't go this route if that's your deal. My answer simply goes the direction the question was headed: how does one re-render JavaScript and have it see the updated state? Both methods are 100% acceptable, although remoting is up to 10x faster. – sfdcfox Dec 2 '13 at 20:06

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.