09
Aug
09

Force.com Tip: ‘New’ Button Override to Assign VisualForce Page to Specific Record Type Using Native Apex Code

* Updated 8.14.09 with a link to a similar post by Jeff Douglas and refactored code that is more applicable to a broader audience using Apex PageReference methods rather than the original string concatenation that was used for human (non-Salesforce developer) readability

You’ve probably come across this before…you need to create a custom VisualForce page for a specific Record Type, but overriding the ‘New’ or ‘Edit’ button seems to be an all-or-nothing proposition (i.e. you can do a single VisualForce page and embed the Page Layout using Apex:Detail, but you can’t mix custom pages with standard Page Layouts). We came across this recently at Delivered Innovation, and we want to share our solution with the community. This specific example involves the Saleforce Case object, but can be applied to any Standard or Custom Object.

Use Case: Client has multiple call centers supporting various product lines; support team ‘A’ requires a custom Wizard to rapidly search for and collect details for the Case record that the standard Salesforce search interface cannot provide.

Solution: While you can assign a specific Page Layout to a specific Record Type and embed VisualForce pages in the object Detail view, currently salesforce.com does not support embedded VisualForce Pages in the Edit view of a Page Layout; likewise, salesforce.com does not support custom VisualForce pages for specific Record Types.  The solution is to “intercept” the command to create a new record in an Object before Salesforce processes it, and this is accomplished with a 1-line VisualForce page and a StandardController extension that pulls and analyzes certain URL parameters to enhance the out-of-the-box process routing capabilities of Salesforce.

The VisualForce Page code:

<apex:page standardController="Case" extensions="caseRedirect" tabStyle="Case" showheader="true" action="{!redirect}" />

The Apex controller extension:

public with sharing class caseRedirect {

private ApexPages.StandardController controller;
public String retURL {get; set;}
public String saveNewURL {get; set;}
public String rType {get; set;}
public String cancelURL {get; set;}
public String ent {get; set;}
public String confirmationToken {get; set;}
public String accountID {get; set;}
public String contactID {get; set;}

public caseRedirect(ApexPages.StandardController controller) {

this.controller = controller;

retURL = ApexPages.currentPage().getParameters().get('retURL');
rType = ApexPages.currentPage().getParameters().get('RecordType');
cancelURL = ApexPages.currentPage().getParameters().get('cancelURL');
ent = ApexPages.currentPage().getParameters().get('ent');
confirmationToken = ApexPages.currentPage().getParameters().get('_CONFIRMATIONTOKEN');
saveNewURL = ApexPages.currentPage().getParameters().get('save_new_url');
accountID = ApexPages.currentPage().getParameters().get('def_account_id');
contactID = ApexPages.currentPage().getParameters().get('def_contact_id');

}

public PageReference redirect(){

PageReference returnURL;

// Redirect if Record Type corresponds to custom VisualForce page

IF(rType == 'xxxxxxxxxxxxxxx') {

returnURL = new PageReference('/apex/insert_VF_Page_Here');
}

ELSE {

returnURL = new PageReference('/500/e');

}

returnURL.getParameters().put('retURL', retURL);
returnURL.getParameters().put('RecordType', rType);
returnURL.getParameters().put('cancelURL', cancelURL);
returnURL.getParameters().put('ent', ent);
returnURL.getParameters().put('_CONFIRMATIONTOKEN', confirmationToken);
returnURL.getParameters().put('save_new_url', saveNewURL);
returnURL.getParameters().put('nooverride', '1');

IF (accountID != null){

returnURL.getParameters().put('def_account_id', accountID);

}

IF (contactID != null){

returnURL.getParameters().put('def_contact_id', contactID);

}

returnURL.setRedirect(true);
return returnURL;

}

}

Original code (prior to refactoring):

public with sharing class caseRedirect {

private ApexPages.StandardController controller;
public String retURL {get; set;}
public String rType {get; set;}
public String cancelURL {get; set;}
public String ent {get; set;}
public String confirmationToken {get; set;}

public caseRedirect(ApexPages.StandardController controller) {

this.controller = controller;

retURL = ApexPages.currentPage().getParameters().get('retURL');
rType = ApexPages.currentPage().getParameters().get('RecordType');
cancelURL = ApexPages.currentPage().getParameters().get('cancelURL');
ent = ApexPages.currentPage().getParameters().get('ent');
confirmationToken = ApexPages.currentPage().getParameters().get('_CONFIRMATIONTOKEN');

}

public PageReference redirect(){

PageReference returnURL;

// Redirect if the Record Type with custom VF page has been selected

// Note, rType represents 15-charater ID for Record Type

IF(rType == 'xxxxxxxxxxxxxxx'){

returnURL = new PageReference('/apex/(insert VF page here)' + '?' + 'retURL=' + retURL + '&' + 'RecordType=' + rType + '&' + 'cancelURL=' + cancelURL + '&' +
'ent=' + ent + '&' + 'nooverride=1' + '&' + '_CONFIRMATIONTOKEN=' + confirmationToken);

}

// Now we need to tell Salesforce what to do in the event that this is not the Record Type we're looking for

ELSE{

returnURL = new PageReference('/500/e' + '?' + 'retURL=' + retURL + '&' + 'RecordType=' + rType + '&' + 'cancelURL=' + cancelURL + '&' +
'ent=' + ent + '&' + 'nooverride=1' + '&' + '_CONFIRMATIONTOKEN=' + confirmationToken);

}

returnURL.setRedirect(true);
return returnURL;

}

}

Now for the important part – in order for this to work when Salesforce users create new Case records, you need to override the ‘New’ button for the ‘Case’ Standard Object.  This can be accomplished by selecting ‘Setup / Customize / Cases / Buttons and Links / ‘Override’ on ‘New’.  Select ‘VisualForce Page’ for “Content Type,” and then select the VisualForce page you created using your modification of the code above in the “Content Name” dropdown list, and you’re set.  The “Comment” area is optional. Don’t forget to set the security for this VisualForce page to provide the required Profiles with access.

Jeff Douglas has provided another method for achieving automated redirection to VisualForce pages on his blog.  You can find the link here.

Questions? Suggestions? Leave us a comment, or email me directly at blog[at]deliveredinnovation.com.

Mike Topalovich, CTO
Delivered Innovation


7 Responses to “Force.com Tip: ‘New’ Button Override to Assign VisualForce Page to Specific Record Type Using Native Apex Code”


  1. August 12, 2009 at 7:55 am

    Nice work Mike! Until Salesforce.com allows Visualforce pages by recordtype we are forced to use this workaround. There a slightly different implementation based upon the type of page. I have outlined it here for reference: http://blog.jeffdouglas.com/2008/11/14/redirecting-users-to-different-visualforce-pages.

    Thanks!
    Jeff Douglas

  2. August 14, 2009 at 12:44 pm

    Thanks, Jeff! I had just come across your post recently as well through a link in the Developer discussion boards, this looks good and I will post a link from the original post. I am also going to post refactored code that is more generic, as the original code was purpose-built and done in a slightly non-standard way.

    Mike

  3. 3 David lee
    September 22, 2009 at 8:54 pm

    good works!

  4. 4 MMA
    December 16, 2009 at 9:58 pm

    Would you happen to have a testmethod on this… I am so lost with my testmethod .. I have post it up on the Apex board here is the link:
    http://community.salesforce.com/sforce/board/message?board.id=apex&thread.id=23824&view=by_date_ascending&page=2

    Any help is appreciated…
    Happy Holidays
    Thanks

  5. 5 Bryan Rountree
    December 17, 2009 at 11:15 am

    Thanks this solved a problem we had with the customer portal.

  6. April 16, 2010 at 9:48 am

    Great Article, thanks for sharing



Cloud computing application & service design by Delivered Innovation

Subscribe to Delivered Innovation with RSS  Follow Delivered Innovation on Twitter  Find Delivered Innovation on Facebook