Redirecting Users to Different Visualforce Pages

Posted on November 14, 2008. Filed under: Apex, Salesforce.com, Visualforce |

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.

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;
}

Make a Comment

Make A Comment: ( 13 so far )

blockquote and a tags work here.

13 Responses to “Redirecting Users to Different Visualforce Pages”

RSS Feed for Jeff Douglas – Technology, Coding and Bears… OH MY! Comments RSS Feed

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?

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

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

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?

I am having trouble getting the redirected record to load my Contact_View_1 – or anything but the header and sidebar.

Can you send me post or send some code and I’d be glad to take a look.

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.

whoops, my contact_view_1 page didn’t show -
here (simplified)
(apex:page standardController=”contact”)
(apex:detail /)
(/apex:page)

Any tips, Jeff?

Can you email me your code and I’ll take a look at it? jeffdonthemic at gmail dot com

Jeff, How and where are you calling the getRedir method?

Sorry… it looks like WordPress crushed my code. I have restored it. Thanks!

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))}”


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...