[SalesForce] Why does apex:param assignTo work with apex:commandLink but not apex:commandButton

How do command buttons and command links differ when it comes to using <apex:param>?
The param value is not being passed to the controller.

I have the following code in a Controller :

public pagereference Pageredirect_new(){
     currentpageId = Apexpages.currentpage().getparameters().get('id');
    redirectUrl = new pagereference('/a2A/e?CF00NK0000000cZqA='+account_name+'&CF00NK0000000cZqA_lkid='+currentpageId);
    return redirectUrl ;
    }

  <apex:commandLink value="New" action="{!Pageredirect_new}">
           <apex:param assignTo="{!account_name}" value="{!Account.name}" name="account_name"/>
           </apex:commandLink>

I get the resulting URL as :

/a2A/e?CF00NK0000000cZqA=donotshow......

When I do

<apex:commandButton value="New" action="{!Pageredirect_new}">
               <apex:param assignTo="{!account_name}" value="{!Account.name}" name="account_name"/>
               </apex:commandButton>

The resulting URL : a2A/e?CF00NK0000000cZqA=null....

Am I missing something?

Best Answer

It's something that's perceived as a "known bug" by the dev community but it never made to the list...

Jeff Douglas has written this up together with viable workarounds in March 2010: http://blog.jeffdouglas.com/2010/03/04/passing-parameters-with-a-commandbutton/ (the post and comments also contain few useful links to SF message boards).

Simple fix is to use commandLink but style it to look like a button:

<apex:commandLink action="{!Pageredirect_new}" value="New" styleClass="btn" style="color:white;text-decoration:none">
    <apex:param assignTo="{!account_name}" value="{!Account.name}" name="account_name"/>
</apex:commandLink>

Or (ab)use the fact that commandButton suddenly behaves as it should if one of it's side-effects will be a rerender of something (even of a region you don't care about).

<apex:commandButton action="{!Pageredirect_new}" value="New" rerender="hiddenBlock">
    <apex:param assignTo="{!account_name}" value="{!Account.name}" name="account_name"/>
</apex:commandButton>

<apex:pageBlock id="hiddenBlock" rendered="false"></apex:pageBlock>

Last but not least, allow me to chip in my usual rant ;) Do you realize that you don't need an action method in your controller at all? Well, unless you have greatly simplified the code...

<apex:commandLink action="/a2A/e?CF00NK0000000cZqA={!Account.name}&CF00NK0000000cZqA_lkid={!$CurrentPage.parameters.id}" value="New" />

In fact you could go even further, if you'll realize you need immediate="true" in this link then you might be better of with plain old <a> tag...

If you'll keep such links in VF and not Apex they're much easier to modify later on (new fields, forgotten URLENCODE'ing etc) plus that's always couple lines less to cover with unit test ;)

Related Topic