+ Start a Discussion
AC SlaterAC Slater 

CommandButton + param

I'd like to be able to dynamically generate buttons on my Visualforce page. Once the user has clicked on one of the buttons, I'd like to redirect the user to a second page and display different information on that page depending on which button the user clicked on. I've poked through a number of posts on these boards and can't quite figure out how to accomplish this. These these posts seem close, but the solutions described require a 'reRender', which I don't want to deal with for reasons irrelevant to this discussion:

http://community.salesforce.com/sforce/board/message?board.id=Visualforce&message.id=1000  http://community.salesforce.com/sforce/board/message?board.id=Visualforce&message.id=1000

http://community.salesforce.com/sforce/board/message?board.id=Visualforce&thread.id=810

Here's a picture of what I'm trying to accomplish:
 


Here's my VF page:
Code:
<apex:page controller="SimpleRepeatController"> 
  <apex:form >
    <apex:pageBlock mode="edit" >
        Lorem Ipsum
        <apex:pageBlockButtons >
            <apex:repeat value="{!Users}" var="user" id="repeat">
                 <apex:commandButton action="{!NextPage}" id="cmdBtn" value="Select '{!user.Name}'">
                      <apex:param value="{!user.Id}" name="UserId"/>
                 </apex:commandButton>
            </apex:repeat>
        </apex:pageBlockButtons> 
    </apex:pageBlock>
  </apex:form>
</apex:page>


 Here's my controller:
Code:
public class SimpleRepeatController 
{
 public List<User> Users
 {
     get
     {  
      return [SELECT Id, Name
                       FROM User
                       WHERE Name != 'License Manager'
                       AND IsActive = true
                       ORDER BY LastName];
    }
 }
    
    public PageReference NextPage()
    {
     PageReference selectedUserResults = Page.SelectedUserResults;
     selectedUserResults.setRedirect(true);
     return selectedUserResults;
    }
}


Here's my second VF page:
Code:
<apex:page controller="SimpleRepeatController">
    Selected User: "{!$CurrentPage.parameters.UserId}"
</apex:page>

Unfortunately, the results are always:      

     Selected User: ""


Is there a better way to accomplish what I'm trying to do?

Thanks in advance!
Mark YoungMark Young

Pretty much there, but bear in mind that $CurrentPage.parameters for the new page won't contain the query parameter.  (It's a query parameter for the first page that is posted back to, not the second page that you've redirected to).

To fix, change the NextPage() method to:

Code:
    public PageReference NextPage()
    {
     PageReference selectedUserResults = Page.SelectedUserResults;
     selectedUserResults.getParameters().put('UserId', ApexPages.currentPage().getParameters('UserId'));
     selectedUserResults.setRedirect(true);
     return selectedUserResults;
    }

Sometimes I've also had issues getting through the parameter from a commandButton - changing this to a commandLink often seemed to resolve this.
 

Adam1Adam1

I'm having the same issue with commandButton. The param does not come through. It comes through with commandLink.

Can someone from SalesForce speak to this limitation with commandButton? Is there another trick? This is kind of a big deal - passing parameters to action methods is fundamental.

dchasmandchasman
There is a known issue with full page refreshes and commandButtons - can you confirm that this is the problem you are seeing?

Use this page and notice the value is returned in the partial page update:

Code:
<apex:page>
  <apex:panelGrid columns="2" id="grid">
    <apex:outputText value="param key: "/>
    <apex:outputText value="{!$CurrentPageReference.parameters.key}"/>
  </apex:panelGrid>
  <apex:form>
    <apex:commandButton value="click me!" rerender="grid"><apex:param name="key" value="value"/></apex:commandButton>
    <apex:commandButton value="clear" rerender="grid"><apex:param name="key" value=""/></apex:commandButton>
  </apex:form>
</apex:page>

Now remove the rerender attributes from the commandButton tags and notice that when clicking on the button to display the param value that the page refreshes but the value is not displayed as before.
AC SlaterAC Slater
Mark, Adam1 and dchasman - thank you all for your help. My NextPage() method did need one extra line:

Code:
    public PageReference NextPage()
    {
        PageReference selectedUserResults = Page.SelectedUserResults;
        selectedUserResults.getParameters().put('UserId', ApexPages.currentPage().getParameters().get('UserId')); //was missing this before.
        selectedUserResults.setRedirect(true);
        return selectedUserResults;
    }

I was also running in to that (very frustrating) commandButton bug that dchasman referred to, because once I switched to commandLink everything worked great.

AC SlaterAC Slater
One last question: I came up with a workaround that leverages an inputHidden field and I'm wondering if either solution is preferrable for some reason.

VF page:
Code:
<apex:page controller="SimpleRepeatController2"> 
    <script>
    function setHiddenUserId(hUserId, hiddenInputId) 
    {    
        var hiddenElement = document.getElementById(hiddenInputId);
        hiddenElement.value = hUserId;
    }
    </script>
    <apex:form >
        <apex:pageBlock mode="edit" >
            This page uses an apex:inputHidden control.
            <apex:inputHidden id="hiddenUserId" value="{!HiddenUserId}"/>
            <apex:pageBlockButtons >
                <apex:repeat value="{!Users}" var="user" id="repeat">
                    <apex:commandButton onclick="setHiddenUserId('{!user.Id}', '{!$Component.hiddenUserId}');" action="{!NextPage}" id="cmdBtn" value="Select '{!user.Name}'">
                    </apex:commandButton>
                </apex:repeat>
            </apex:pageBlockButtons> 
        </apex:pageBlock>
    </apex:form>
</apex:page>

 Controller code:
Code:
public class SimpleRepeatController2 
{
    public List<User> Users
    {
        get
        {   
            return [SELECT Id, Name
                          FROM User
                          WHERE Name != 'License Manager'
                          AND IsActive = true
                          ORDER BY LastName];
        }
    }
    
    private Id hUserId;
    public Id getHiddenUserId()
    {
        return hUserId;
    }
        
    public void setHiddenUserId(Id value)
    {
        hUserId = value;
    }
    
    public PageReference NextPage()
    {
        PageReference selectedUserResults = Page.SelectedUserResults;
        selectedUserResults.setRedirect(false);
        return selectedUserResults;
    }
}

 Second VF page:
Code:
<apex:page controller="SimpleRepeatController2">
Hidden Input Selected User Id: {!HiddenUserId}
</apex:page>

 
The initial param-based solution appears to work regardless of the value of the PageReference's "redirect" attribute.  The inputHidden solution will of course only work in "wizard" mode (setRedirect(false)). Other than that, I can't observe any differences. Is one preferrable to the other?

Thank you again!