Redirecting Users to Different Visualforce Pages
We have a large Salesforce.com org with 400+ recordtypes and 600+ page layouts. When Visualforce was released we wanted to start developing customized Visualforce pages for certain recordtypes. Unfortunately, you cannot assign Visualforce pages by recordtype so you have to implement a hack around it.
Note: There is currently as issue with Visualforce in that inputFields do not respect recordtypes. So if you have picklists with values for different recordtypes, your picklists on your Visualforce pages will show all picklist values and not just those values for that recordtype. There is a thread relating to this on the force.com discussion boards but Sam Arjmandi has posted a picklist component for a workaround.
What you need to do is create a “dispatcher” Visualforce page (Dispatcher_Contact_View.page) and accompanying controller extension (DispatcherContactViewController.cls) and then override the appropriate button/link action (view, edit or new) with this new dispatcher Visualforce page. The code is slightly different depending on whether you are doing view, edit or new so I’ll be showing them all. When a user clicks the view button/link for appropriate object, it loads the new Visualforce page. The Visualforce page loads the controller extension and perform some logic to determine if the user should be dispatched to your new view page (Contact_View_1) or the standard Salesforce.com view page.
You’ll need to override each button to call the specific Visualforce page. Here’s more info on how to do that.
Dispatcher_Contact_View.page
<apex:page standardController="Contact" extensions="DispatcherContactViewController"
action="{!nullValue(redir.url, urlFor($Action.Contact.View, contact.id, null, true))}">
</apex:page>
DispatcherContactViewController.cls
public class DispatcherContactViewController {
public DispatcherContactViewController(ApexPages.StandardController controller) {
this.controller = controller;
}
public PageReference getRedir() {
Contact c = [Select id, recordtypeid From Contact Where Id = :ApexPages.currentPage().getParameters().get('id')];
PageReference newPage;
if (c.recordtypeid == '111111111111') {
newPage = Page.Contact_View_1;
} else {
newPage = new PageReference('/' + c.id);
newPage.getParameters().put('nooverride', '1');
}
newPage.getParameters().put('id', c.id);
return newPage.setRedirect(true);
}
private final ApexPages.StandardController controller;
}
The code is somewhat similar for the edit and new use cases but does have some notable differences.
Dispatcher_Contact_Edit.page
<apex:page standardController="Contact" extensions="DispatcherContactEditController"
action="{!nullValue(redir.url, urlFor($Action.Contact.Edit, contact.id, null, true))}">
</apex:page>
DispatcherContactEditController.cls
public class DispatcherContactEditController {
public DispatcherContactEditController(ApexPages.StandardController controller) {
this.controller = controller;
}
public PageReference getRedir() {
Contact c = [Select id, recordtypeid From Contact Where Id = :ApexPages.currentPage().getParameters().get('id')];
PageReference newPage;
if (c.recordtypeid == '111111111111') {
newPage = Page.Contact_Edit_1;
} else {
newPage = new PageReference('/' + c.id + '/e');
newPage.getParameters().put('nooverride', '1');
}
newPage.getParameters().put('id', c.id);
return newPage.setRedirect(true);
}
private final ApexPages.StandardController controller;
}
Dispatcher_Contact_New.page
<apex:page standardController="Contact" extensions="DispatcherContactNewController"
action="{!nullValue(redir.url, urlFor($Action.Contact.New, null, null, true))}">
</apex:page>
DispatcherContactNewController.cls
public class DispatcherContactNewController {
public DispatcherContactNewController(ApexPages.StandardController controller) {
this.controller = controller;
}
public PageReference getRedir() {
PageReference newPage;
if (ApexPages.currentPage().getParameters().get('RecordType') == '111111111111') {
newPage = Page.Contact_New_1;
return newPage.setRedirect(true);
} else {
return null;
}
}
private final ApexPages.StandardController controller;
}











Hi Jeff
Good read, I have one question more about your use of RecordType in general, I am interested in the reason why you have ended up with 400+ of them.
I understand the basic concept of them to control picklists and layouts, but why so many?
I am looking at them to control editing for records in given states i.e. stopping edit’s after an record approved. Are RecordType the only tool from the standard SalesForce toolbag?
MatLeete
December 1, 2008
We run “a large” number of distinct companies within our Org with roughly 2000 users. We utilize recordtypes to separate out access to page layouts, picklist values, records, etc. so that users from one company have a different UI experience than users from another company. HTH
jeffdonthemic
December 1, 2008
First of all congratulation for such a great site. I learned a lot reading here today. I will make sure i visit this site more often so I can learn more.
Make your long Urls shorter – Free Url redirection – Hide your affilate URLS
Josh
January 11, 2009
I looked into the picklist component you linked to, but it doesn’t appear that it helps to handle RecordType filtering of picklists. Are you sure that it can be used to handle this?
Kyle Freeman
February 12, 2009
I am having trouble getting the redirected record to load my Contact_View_1 – or anything but the header and sidebar.
jaw
March 12, 2009
Can you send me post or send some code and I’d be glad to take a look.
jeffdonthemic
March 12, 2009
Jeff, thanks, I kept everything very simple, just copying your code, subbing in my record type id. It works in that the other record type gets the standard view.
For my contact_view_1 after it wasn’t working I simplified it to:
and it never loads – the url in my page is still Dispatcher_Contact_View?id=00(etc).
but weirdly, if I use another object for the say, make it “case” – the contact loads with all detail, but in the case page style.
jaw
March 12, 2009
whoops, my contact_view_1 page didn’t show -
here (simplified)
(apex:page standardController=”contact”)
(apex:detail /)
(/apex:page)
jaw
March 12, 2009
Any tips, Jeff?
jaw
March 27, 2009
Can you email me your code and I’ll take a look at it? jeffdonthemic at gmail dot com
jeffdonthemic
March 27, 2009
Jeff, How and where are you calling the getRedir method?
Kautuk
May 21, 2009
Sorry… it looks like WordPress crushed my code. I have restored it. Thanks!
jeffdonthemic
May 21, 2009
Jeff, great post, you Rock!
I’m having a slight issue implementing the “New” code. It redirects to the VF page when matched on record type… but when returning null the urlFor is not redirecting the page to the Standard object New interface… Instead it just keeps redirecting back to the record type selection page?
The urlFor looks correct?
action=”{!nullValue(redir.url, urlFor($Action.Ticket_Data_Form__c.New, null, null, true))}”
Rob Craven
May 21, 2009
I gave up on implementing the “New” redirects via VF, could never get the URLFOR to work right. I’ve instead implemented via an S-Control. Basically create the object and pass the id value to an VF edit page.
Rob Craven
July 10, 2009
I am having the same issue. Could you post some code on how you got this working? Thanks
rubixtious
August 28, 2009
This comment box will not except code, sorry.
Create an S-Control and set it up as the override page for the “New” action. Once this is done your S-Control page will have access to the following merge field {Object.RecordTypeId}, since the record type page is displayed prior to this S-Control page.
Use branching based on this record type id….
If a VF page should be displayed, create sobject with record type id and default values. Next set a var for url = “apex/page?id=” your new record id. You should also set the retURL, and cancelURL properties. Next set parent.location.href = yourNewUrl
Else redirect to the standard page
url = parent.location.href
url += &nooverride=1
parent.location.href = url
Ensure the script runs during the onload event
Rob Craven
September 24, 2009
I was able to get the New redirect working after selecting a RecordType. Instead of using the URLFOR($Action.Object.New) in my page action parameter, I used URLFOR(‘//e?nooverride=true&RecordType=’+.RecordTypeId). For the Opp it would be URLFOR(‘/006/e?nooverride=true&RecordType=’+Opportunity.RecordTypeId)
Note: the URL is case sensitive so you need to put capitals on RecordType=.
Niki Vankerk
October 3, 2009
Hi, Rob.
Need to know if you solved the problem when you implement the “New” cod. How?
Thanks.
Miguel Chinchilla
November 24, 2009
S-Control you create the record up front with record type and then redirect to that record id…..follow the instructions listed in my Sept 24, 09 comment related to this thread. Please note, I’ve also voiced this issue at Dreamforce 09 during a code consultant review, the URLFOR is not working as intended when using action.NEW? I’m not sure why, hope to provide more answers soon.
Rob Craven
November 24, 2009
Thansk Rob,
I really appreciate your help.
Regards.
Miguel Chinchilla
November 24, 2009
I managed to get the new redirect page working using native visualforce. An outline of the solution is here:
http://community.salesforce.com/sforce/board/message?board.id=Visualforce&thread.id=16528
rubixtious
November 24, 2009
Using the Dispatcher_Contact_Edit.page, I’ve noticed odd behaviour, just not sure what the issue is. Basicly, if your attempting to redirect to a VF page that only contains a standard controller the redirect hangs. For whatever reason your VF page must include a controller extension for the redirect to work correctly.
Rob Craven
July 10, 2009
Your post seems to be relevent.. kindly let me know how to redirect to parent page from a visualforce page. In a visualforce page am doing an action once the action is complete, i want to redirect to same page. I tried with retUrl ,it was in vain.
Vishnu
September 24, 2009
Create method
public PageReference getRedir()
PageReference newPage
If recordtype id = ‘x’
newPage = Page.vfPageName
else if recordtype id = ‘z’
newPage = Page.vfPageName
else
newPage = newPageReference(‘/’ + idOfCurrentRec + ‘/e’)
NewPage.getParameters().put(‘nooverride’, ‘1′)
end if
//add common url values..(id, retURL)
return newPage.setRedirect(true);
end function
Rob Craven
September 24, 2009
Hi.. I have written one standard controller with custom extension.
Whenever user enters value in the Visualforce page and click on Save Button, field value is actually not getting save in the record. So can you please let me know what function is to be written in Apex class for Save button
Standard Contoller:
Agent Name
{!c.name}
Previous
Next
First
Last
Apex Clas:
public class ContactPage
{
private User varuser { get; private set;}
private Profile prof { get; private set;}
private final Contact cont { get; private set;}
public ContactPage(ApexPages.StandardSetController controller)
{
this.cont = (Contact)controller.getRecord();
}
public ApexPages.StandardSetController contactRecords{
get
{
id id1 = userinfo.getProfileId();
id id2 = userinfo.getUserId();
prof = [Select Name from Profile where Id= :id1];
varuser =[Select IsActive , Name from User where Id= :id2];
if(contactRecords == null && id2 != NULL && id1 != null && prof.Name == ‘RI Sales External Wholesalers Profile’ && varuser.IsActive ==true)
{
return new ApexPages.StandardSetController(Database.getQueryLocator(
[SELECT Id, name, AccountId, RI_DriveTo_City__c, RI_DriveTo_State__c, RI_DriveTo_Zip__c, RI_Current_YTD__c, RI_Prior_YTD__c, RI_Production_Goals_This_Year__c, RI_Production_Goals_Next_Year__c, Face_to_Face_Activity_Goal__c, RI_Zone__c, RI_Segment__c, Projected_Sequoia_Seg__c, Tertiary_Territory__c FROM Contact WHERE recordtypeid = '012400000005OLAAA2' and ownerid = :id2 order by RI_Current_YTD__c desc Limit 1000]));
}
else if(contactRecords == null && id2 != NULL && id1 != null && (prof.Name == ‘System Administrator’ || prof.Name == ‘RI Sys Admin’) && varuser.IsActive ==true)
{
return new ApexPages.StandardSetController(Database.getQueryLocator(
[SELECT Id, name, AccountId, RI_DriveTo_City__c, RI_DriveTo_State__c, RI_DriveTo_Zip__c, RI_Current_YTD__c, RI_Prior_YTD__c, RI_Production_Goals_This_Year__c, RI_Production_Goals_Next_Year__c, Face_to_Face_Activity_Goal__c, RI_Zone__c, RI_Segment__c, Projected_Sequoia_Seg__c, Tertiary_Territory__c FROM Contact WHERE recordtypeid = '012400000005OLAAA2' order by RI_Current_YTD__c desc Limit 1000]));
}
else if(contactRecords == null && id2 != NULL && id1 != null && prof.Name != ‘System Administrator’ && prof.Name != ‘RI Sales External Wholesalers Profile’ && prof.Name != ‘RI Sys Admin’ && prof.Name !=NULL )
{
}
return contactRecords;
}
private set;
}
public List getContactPagination() {
return (List) contactRecords.getRecords();
}
public PageReference save()
{
PageReference pageRef= new PageReference(‘/apex/BusReport’);
pageRef.setredirect(true);
return pageRef;
}
}
Raj Tahil
October 9, 2009
Raj, this might be better posted on the Support message boards.
jeffdonthemic
October 9, 2009
Hello friends, I need your help again in Visualforce. I have a selectList, where I choose a value (eg colony) SelectOption (IdZona, colony name)use in class. I need to select a colony takes the IdZona and find the value in the object Zona__c and the name of the area put it in a inputField.
Thanks a lot.
Miguel Chinchilla
December 8, 2009