November 4, 2010

apex:actionFunction and apex:param - Or How to Pass Values from Javascript to an Apex Controller

Just a quickie, because I've been beating my head against a wall for a couple of hours over this and no amount of Googling could help me find the answer, but eventually I tripped over the solution completely by accident.

The Scenario

I want to pass values back to a Visualforce controller without having to resort to hidden input fields and using the {!$Component.<<fieldid>>} notation because that's only evaluated when the page is generated and so doesn't lend itself well to dynamic setups.

The problem

All of the solutions I was able to find involved using an <apex:actionFunction> with nested <apex:param> tags (e.g. see here and here), which is fine except that whenever I tried this the generated JavaScript function never had any parameters, i.e. doStuff() {...}.

<apex:actionFunction name="doStuff" action="{!myAction}"> 
  <apex:param name="x" value="x" assignTo="{!m_x}"/> 
</apex:actionFunction>

And the Solution

You must specify a rerender attribute in the <apex:actionFunction> tag! Without this the generated function does take any parameters, but as soon as you put it in then it does - even if you just leave it empty, i.e. the below code will generate doStuff(x) {...} Go figure.

<apex:actionFunction name="doStuff" action="{!myAction}" rerender="">
  <apex:param name="x" value="x" assignTo="{!m_x}"/>
</apex:actionFunction>