Lot of times I get this question from developers, is “How to pass parameter to a controller method” So in this blog post I will walk you through step by step how to do that.
In this tutorial, we will create a visualforce page which will display the account and the list of contact associated with the account. We will create an extension as well:
Step 1: Enable the developer mode to create visualforce pages.
1.a Click on the username drop down
1.b Go to the settings
1.c under personal settings,click on advanced User Details.
1.d enable the developer mode.
Step 2: Now we will create a visualforce page and add the below contents to the page.
<apex:page standardController="Account" extensions="AccountContactController"> <apex:outputPanel id="all"> <apex:form> <apex:pageBlock title="Account Detail"> <apex:pageBlockSection title="Account"> <apex:outputField value="{!Account.Name}"/> <apex:outputField value="{!Account.Description}"/> </apex:pageBlockSection> <apex:pageBlockSection title="Contacts" columns="1"> <apex:pageBlockTable value="{!conts}" var="cont" rows="10"> <apex:column value="{!cont.Id}"/> <apex:column value="{!cont.Name}"/> <apex:column value="{!cont.Email}"/> <apex:column value="{!cont.Phone}"/> </apex:pageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:outputPanel> </apex:page>
Step 3: Now we will create the controller “AccountContactController”
If you notice in the controller I have created a variable to store the list of contacts.
public class AccountContactController { private ApexPages.StandardController stdCtrl {get; set;} public List<Contact> conts {get; set;} public AccountContactController(ApexPages.StandardController std) { stdCtrl=std; setupContacts(); } private void setupContacts() { conts=[select id, Name, Email, Phone from Contact where AccountId=:stdCtrl.getId()]; } }
to test this enter the url in the browser:
Now let’s assume i want to add a column next to contact which provides an option to delete the contact. So we need to pass the contact id of the contact which we need to delete.
<apex:column headerValue="Action"> <apex:commandButton value="Del" action="{!delCont(cont.id)}"/> </apex:column>
however, the above lines fail to compile, because delCont is a unknown function. Controller action doesn’t take parameters in this way.
The compiler thinks its a formula function but no function with that name exist so it fails to compile.
So how to pass the contact id to the controller?
The answer is <apex:param>: it allows parameters to be defined for a parent component, which can be assigned to a controller property.
<apex:commandButton value="Del" action="{!delCont}" rerender="all"> <apex:param name="contIdParam" value="{!cont.id}" assignTo="{!contIdChosen}"/> </apex:commandButton>
Note: I am using rerender attribute of commandButton, if I don’t use rerender then parameter won’t be sent back to the controller.
Now we will create a getter and setter :
public String contIdChosen {get; set;} public PageReference delCont() { Contact toDel=new Contact(id=contIdChosen); delete todel; setupContacts(); return null; }
The important point to note here is that: when we click the Del button, the id of the contact is assigned to the controller property before calling the delCont method.
So when the delCont method is invoked it already had the contact id which needs to be deleted in the property.I have to use rerender attribute in order to make parameter passing to work is the reason why I maintain separate list of Contacts independent of the Account record from the standard controller.
I can’t make the browser refresh the page and thus rebuild the related contacts from scratch, so I have to rebuild the list server side.