+ Start a Discussion
rubixtiousrubixtious 

Using Record Types with Visualforce Pages

We have overidden our new and edit buttons for Cases to go to a custom visualforce page.  This was fine until now we want to utilize Record Types.  Now, regardless of the record type chosen, new cases go to the custom visualforce page instead of the page layout for the record type.  I am thinking that I need another VF page to act as a proxy to route the user to the correct page.  I have read a couple of forum posts but am unsure if they are applicable to my problem.

 

http://forums.sforce.com/sforce/board/message?board.id=Visualforce&thread.id=4875

Best Answer chosen by Admin (Salesforce Developers) 
ThomasTTThomasTT
I found a solution for it. Rather than using URLFOR, use

 

'/(keyprefix)/e?nooverride=1&RecordType={!$Request.RecordType}'

 

so that you can redirect to Standard New pages and it will take the selected RecordType.

 

This URL is called after Record Type selection, and selected RecordType is put in RecordType parameter (because you don't use URLFOR anymore, you have to put all parameters by yourself). The parameter nooverride=1 does the same thing as URLFOR(Action..., null, null, true) so that you can call original New page. You just add your field id & value pairs and other parameters (retURL, cancelURL, etc.) in the URL.

 

In my case, I put the routing logic in an action method (redirect()) and let it return PageReference for '/(keyprefix)/e?nooverride=1&RecordType={!$Request.RecordType}' based on given parameters.You can do the same thing with javascript document.location.

 

When I inherited "save_new" parameter, it still showed RecordType Selection page twice.

 

I hope this can help you (it worked perfect in my case).

 

ThomasTT

 

<apex:page standardController="Opportunity" extensions="OpportunityRedirectExtension" action="{!redirect}">
</apex:page>

 

public with sharing class OpportunityRedirectExtension {

private ApexPages.StandardController controller = null;

public OpportunityRedirectExtension (ApexPages.StandardController controller){
this.controller = controller;
}


public PageReference redirect(){

String prefix = Opportunity.SObjectType.getDescribe().getKeyPrefix();
String param = getParameters() + '&(your field id)=(your field value)';
return new PageReference('/'+prefix+'/e?nooverride=1&'+param);
}

// Inherit previous parameters, more imporatntly, RecordType parameter!
private String getParameters(){
string param = '';
Map<String, String> strMap = ApexPages.currentPage().getParameters();
String[] keys = new String[]{'RecordType', 'retURL', 'cancelURL'};
for(String s : keys){
if(strMap.containsKey(S)) param += s + '=' + strMap.get(s) + '&';
}
if(param.length() > 0) param = param.substring(0, param.length()-1);
return param;
}

}

 

Message Edited by ThomasTT on 09-09-2009 06:12 AM
Message Edited by ThomasTT on 09-09-2009 04:06 PM
Message Edited by ThomasTT on 09-09-2009 04:06 PM

All Answers

ryan_marplesryan_marples
Hi rubixtious - Yes I think what most people do in this case is create a VF page that does quick check to see which recordtype was selected and then forwards onto a "record-type-specific" VF page. You'll notice that after the user selects a record type and it forwards to your VF page, there is a 'RecordType' item in the query string which is the hint that you need.

Here's an example of a simple VF page that acts as a proxy/redirector which can be set of the overriden "New" page:

<apex:page standardController="DemoObject__c" extensions="NewDemoObjDispatcher" action="{!redirectToPage}">
</apex:page>

 


Then here is the supported controller extension:
public class NewCasePageDispatcher {
public NewCasePageDispatcher(ApexPages.StandardController sc) {
}

public PageReference redirectToPage() {
String selectedRecordType = ApexPages.currentPage().getParameters().get('RecordType');
if (selectedRecordType == '01280000000BPUT')
return Page.NewCaseTypeAPage.setRedirect(true);
else
return Page. NewCaseTypeBPage.setRedirect(true);
}
}

Make sense?
rubixtiousrubixtious

Hi Ryan,

 

I have some of this working using a variation of the code you posted. My problem now is redirecting to the standard new page for a particular record type.  I am not sure what to return to get to the standard controller.  If I return null, the redirect works but only after returning to the record types screen first.  So essentially the user is asked to choose the record type twice.  The redirect to the custom VF page is working fine.  Thanks for your help.

public class ControllerDispatcherNewCase { public ControllerDispatcherNewCase(ApexPages.StandardController controller) { this.controller = controller; } public PageReference getRedir() { Pagereference newPage; if(Apexpages.currentPage().getParameters().get('RecordType') == '012R00000000Mu1') { // Case Standard Page return null; } else if(Apexpages.currentPage().getParameters().get('RecordType') == '012R00000000Mu6') { newPage = Page.editCase; // Case VF Page return newPage.setRedirect(true); } else { return null; } } private final ApexPages.StandardController controller; }

 

 

<apex:page standardController="Case" extensions="ControllerDispatcherNewCase" action="{!nullValue(redir.url, urlFor($Action.Case.NewCase, null, null, true))}"> </apex:page>

 

ryan_marplesryan_marples
So just to clarify, you're saying that for a certain recordType you just want the standard screen and then for another recordType you want to show your custom visualforce page?
rubixtiousrubixtious

Yes, thats right. 

 

RecordType 1 should go to custom VF page

RecordType 2 should go to standard 'new' case page for that record type

 

RecordType1 works fine and redirects to the custom VF page

RecordType2 redirects to the 'select record type' screen twice and only then redirects to the standard 'new' case page.

ryan_marplesryan_marples
FYI - still trying to get this to work, I haven't been able to get the right syntax. I'll get back to you soon.
ThomasTTThomasTT
I found a solution for it. Rather than using URLFOR, use

 

'/(keyprefix)/e?nooverride=1&RecordType={!$Request.RecordType}'

 

so that you can redirect to Standard New pages and it will take the selected RecordType.

 

This URL is called after Record Type selection, and selected RecordType is put in RecordType parameter (because you don't use URLFOR anymore, you have to put all parameters by yourself). The parameter nooverride=1 does the same thing as URLFOR(Action..., null, null, true) so that you can call original New page. You just add your field id & value pairs and other parameters (retURL, cancelURL, etc.) in the URL.

 

In my case, I put the routing logic in an action method (redirect()) and let it return PageReference for '/(keyprefix)/e?nooverride=1&RecordType={!$Request.RecordType}' based on given parameters.You can do the same thing with javascript document.location.

 

When I inherited "save_new" parameter, it still showed RecordType Selection page twice.

 

I hope this can help you (it worked perfect in my case).

 

ThomasTT

 

<apex:page standardController="Opportunity" extensions="OpportunityRedirectExtension" action="{!redirect}">
</apex:page>

 

public with sharing class OpportunityRedirectExtension {

private ApexPages.StandardController controller = null;

public OpportunityRedirectExtension (ApexPages.StandardController controller){
this.controller = controller;
}


public PageReference redirect(){

String prefix = Opportunity.SObjectType.getDescribe().getKeyPrefix();
String param = getParameters() + '&(your field id)=(your field value)';
return new PageReference('/'+prefix+'/e?nooverride=1&'+param);
}

// Inherit previous parameters, more imporatntly, RecordType parameter!
private String getParameters(){
string param = '';
Map<String, String> strMap = ApexPages.currentPage().getParameters();
String[] keys = new String[]{'RecordType', 'retURL', 'cancelURL'};
for(String s : keys){
if(strMap.containsKey(S)) param += s + '=' + strMap.get(s) + '&';
}
if(param.length() > 0) param = param.substring(0, param.length()-1);
return param;
}

}

 

Message Edited by ThomasTT on 09-09-2009 06:12 AM
Message Edited by ThomasTT on 09-09-2009 04:06 PM
Message Edited by ThomasTT on 09-09-2009 04:06 PM
This was selected as the best answer
rubixtiousrubixtious

Thanks Thomas!  This seems to work but I am not sure I understand what/why I need to specify the field id and value pairs.  I have removed that string and my page works as intended.  Also, I have not specified a retURL or cancelURL, the defaults work fine.

ThomasTTThomasTT

> I have removed that string and my page works as intended.

You mean, you removed the following part?

 

 

...
return new PageReference('/'+prefix+'/e?nooverride=1&'+param);

...

Map<String, String> strMap = ApexPages.currentPage().getParameters();
String[] keys = new String[]{'RecordType', 'retURL', 'cancelURL'};
for(String s : keys){
if(strMap.containsKey(S)) param += s + '=' + strMap.get(s) + '&';
}
if(param.length() > 0) param = param.substring(0, param.length()-1);
return param;

...

 

In my case, if I just use "PageReference('/'+prefix+'/e?nooverride=1)", any parameter was not inherited from the original or RecordType selection page. In my actual code, I inherits all parameters except "save_new".

 

If they are automatically inherited without any adding parameters by yourself, that's fine... I don't know why it didn't work for me.

 

If there is no cancelURL in the URL at the final page, but still Cancel button is working, that may be just a coincidence... if you invoke that event and try to cancel the event, it may not lead  you back to the original page.

Ben0034Ben0034

One additional note on this...  If the parameter value contains unsafe characters such as & or #, the page may not be redirected with all the parameters specified.  Example, if the paramter value is an account name of 'Detroit Auto & Bicycle', the '&' character causes issues.

 

To correct this, you can use the EncodingUtil.UrlEncode function, such as below...

 

      for(String s : keys)
      { 
        if(strMap.containsKey(s))
          param += s + '=' + EncodingUtil.urlEncode(strMap.get(s),'UTF-8') + '&'; 
      } 
ThomasTTThomasTT

Ben0034,

 

That is very true. I always forget about encoding...

 

ThomasTT

goabhigogoabhigo

How to get the exact parameters? I mean, in strMap we have the exact parameters. But in param we have only 'RecordType', 'retURL', 'cancelURL'.

goabhigogoabhigo

 

Please suggest. I have done the same, but with different custom object.
My URL after clicking standard 'New' button is:
Where LeadSMS is a visualforce page.
I have checked without overriding, and the URL is:
The only difference I can spot is the arrangement of the arguments.
My question is why its not showing the name in the lookup text field?

 

Keith987Keith987
michaellee.ampfmichaellee.ampf

This is great, and it works well if a particular profile has multiple RecordTypes available to it, but it turns out that it does NOT seem to work if you have a profile with only one accessible record type -- in that case the record type doesn't seem to be on the query string.  

 

I'm at this point to figure out the best way to determine what the default record type is for the profile in this situation, because then I could determine what record type is being selected -- and then follow the same logic to determine if I go to the standard new page layout, or my custom VisualForce page.

 

 

rubixtious76rubixtious76

You could possibly use Describe methods as follows:

 

Schema.DescribeSObjectResult R = Account.SObjectType.getDescribe(); List<Schema.RecordTypeInfo> RT = R.getRecordTypeInfos();

if(rt.isDefaultRecordTypeMapping())

//do something

bkk130bkk130

Can someone post this same exact code, but with the actual object values that they are using? I am trying to accomplish same exact thing here, but I am not a developer, and don't know exactly what I need to add to make this work.

 

Thanks!

Gon3dGon3d

Hi ThomasTT,

I´m trying to do exactly what you are doing with opportunities, but mi point is to open a visualforce page for Edit a certain kind of record Type.

When I try to use your code i´m redirecting to the Standart salesforce Record type and I cannot manage to redirect the user to a page called IPOpp_New for that record type.

I would really apreciate some help with this, its a mayor issue for my developing.

Thanks from the heart for your help!

Best regards,