+ Start a Discussion
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student 

Visualforce Record Type Selection

Hey there,

I have a tabbed account Visualforce page. One of the tabs of this page is transactions (which is a child object of Account). Transactions has multiple record types with specific stages and fields for each record type. There is a link to a create New transaction page on the tab which leads to the create New Transaction VF page I have created as I need to extend the functionality so i can re-direct back to my accounts tabbed VF page, etc. 

My questions are:

Is it possible to still allow the user to select the record type through this method?

If so, how would I go about doing ?

Thank you so mcuh in advance for your time
Best Answer chosen by Developer.mikie.Apex.Student
Marty C.Marty C.

Hello, mikie, I think the general steps to allowing users to select a record type and then being taken to a custom Visualforce page are:

  1. Present a native Record Type picklist to the user
  2. Allow the user to click an apex:commandButton or apex:commandLink to go to the edit page
  3. Construct a PageReference[1] to the custom Visualforce edit page
  4. Add the selected Record Type ID as a parameter to the PageReference
  5. Return the PageReference, including the Record Type ID parameter
  6. Read the parameter on the receiving page and do what you need there


Here are two sample pages, SelectTransactionRecordType[2] and EditTransaction[3] with a simple controller[4] behind them demonstrating this concept.

[1]: PageReference (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_system_pagereference.htm)
[2]: SelectTransactionRecordType (http://pastebin.com/x2H4AH0v)
[3]: EditTransaction (http://pastebin.com/Uk6HsecN)
[4]: a simple controller (http://pastebin.com/zZp64BDH)

All Answers

Marty C.Marty C.

Hello, mikie, you can create a custom picklist for the user to select a record type by using the Schema.DescribeSObjectResult.getRecordTypeInfosByName()[1] method, or one of its relatives. The general idea would be:

  1. Use getRecordTypeInfosByName() to grab a map of record type information
  2. Loop through the record type information to compile a list of SelectOption[2] objects
  3. Use the apex:select component on your Vf page to let the user pick a record type

[1]: Schema.DescribeSObjectResult.getRecordTypeInfosByName() (http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#CSHID=apex_dynamic_describe_objects_understanding.htm|StartTopic=Content%2Fapex_dynamic_describe_objects_understanding.htm|SkinName=webhelp)
[2]: SelectOption (http://www.salesforce.com/us/developer/docs/pages/Content/apex_pages_selectoption.htm)
 

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Thank you for the speedy reply Marty. Can I attempt this and get back to you if I have troubles? I am not sure I understand what to do. Do I add the getRecordType.... into my visualforce page?
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Would you possibly be able to provide steps on how I may accomplish this?
Marty C.Marty C.

Hello, mikie, I think the general steps to allowing users to select a record type and then being taken to a custom Visualforce page are:

  1. Present a native Record Type picklist to the user
  2. Allow the user to click an apex:commandButton or apex:commandLink to go to the edit page
  3. Construct a PageReference[1] to the custom Visualforce edit page
  4. Add the selected Record Type ID as a parameter to the PageReference
  5. Return the PageReference, including the Record Type ID parameter
  6. Read the parameter on the receiving page and do what you need there


Here are two sample pages, SelectTransactionRecordType[2] and EditTransaction[3] with a simple controller[4] behind them demonstrating this concept.

[1]: PageReference (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_system_pagereference.htm)
[2]: SelectTransactionRecordType (http://pastebin.com/x2H4AH0v)
[3]: EditTransaction (http://pastebin.com/Uk6HsecN)
[4]: a simple controller (http://pastebin.com/zZp64BDH)

This was selected as the best answer
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Hi Marty,

I have gotten the Record select page, the controller and the New page which will show the selected recordID...But I cannot figure out how to chance the RecordType based on Record Selection. This is what I have so far, I feel like i am close:


/*
* Controller supporting the TransactionRecordTypeDemo page that demonstrates
* how to allow a user to select a Transaction record type from a dynamically
* generated list.
*
* @version 0.2
* @see     https://developer.salesforce.com/forums/ForumsMain?id=906F00000009F1M
* @author  Marty Chang (Slalom Consulting)
*/
public class TransactionSiteController {

    /*
     * A Transaction record template to facilitate Salesforce-native user input.
     */
    public Transaction__c proxy { get; set; }
    public Account acc {get;set;}

    /*
     * Default constructor that initializes member variables
     */
    public TransactionSiteController(ApexPages.StandardController controller) {
        this.proxy = (Transaction__c)controller.getRecord();
    }
  
    /*
     * @return The custom edit page for Transactions, with the specified
     *         record type ID
     */
    public PageReference editWithRecordType() {
        PageReference nextPage = new PageReference('/apex/DestinyTransactionsNew');
        nextPage.getParameters().put('RecordType', proxy.RecordTypeId);
        return nextPage;
    }
}   // public class TransactionSiteController


/////////////////////////////////////New Record page\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

<apex:page standardController="Transaction__c" extensions="extSaveTraButton">

<apex:sectionHeader title="Transaction Edit" subtitle="{!Transaction__c.name}"/>
<apex:form >

<apex:pageBlock title="Transaction Edit" mode="edit">
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="Save" action="{!SaveDestinyTransaction}"/>
<apex:commandButton value="Save&New" action="{!saveNewTransaction}"/>
<apex:commandButton value="Cancel" immediate="true" action="{!cancelDestinyTransaction}"/>
<apex:commandButton value="Cancel1" immediate="true" action="{!cancel}"/>
</apex:pageBlockButtons>
<apex:pageBlockSection title="Transaction Information" columns="2">

       
                       <apex:repeat value="{!$ObjectType.Transaction__c.FieldSets.TransactionsFieldSet}" var="f"> 
                <apex:inputfield value="{!Transaction__c[f]}" >
               
            </apex:inputfield>
           
            <apex:outputPanel rendered="{!Transaction__c.RecordTypeId == '01290000000kbhD'}" id="ServTran" >
           
<apex:inputField value="{!Transaction__c.Destiny_Service_No__c}"/>
</apex:outputPanel>
<apex:outputPanel rendered="{!Transaction__c.RecordTypeId == '01290000000kYvl'}" id="ProdTran" >
           
<apex:inputField value="{!Transaction__c.Destiny_Products_No__c}"/>
</apex:outputPanel>
     

           
            </apex:repeat>
          
          </apex:pageBlockSection>
           

 
                  
</apex:pageBlock>
    </apex:form>
   
    </apex:page>

////////////////////////////////////////////////////////////////////////Select Record Page\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

<apex:page Standardcontroller="Transaction__c" Extensions="TransactionSiteController">
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockButtons location="bottom">
                <apex:commandButton value="Continue" action="{!editWithRecordType}"/>
            </apex:pageBlockButtons>
           
            <apex:pageBlockSection collapsible="false" columns="1">
                <apex:inputField value="{!Transaction__c.RecordTypeId}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
    </apex:page>


Thank you for your help Marty


Marty C.Marty C.
Hello, mikie, what do you mean by "changing the record type based on the record selection?" I thought you wanted to emulate the standard functionality where a user picks a record type before editing details for the new record. Can you explain or provide additional visual details on what you want to create?
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Sure thing, I will explain as best I can. 

I have a tabbed Account VF page, each one of the tabs is a child to Account (shown below). One of these children 'transactions' has multiple record types(Service, product, etc Transaction). The only differences between the record types are that they have different picklist options (it was also different lookup fields, but I put in a conditional rendering into my VF page that will render based on the record type).

On the transactions tab there is a commandlink which re-directs to a new transaction record (Look below):

User-added image


The command link URL is: /a0H/e?CF00N90000006CdMG={!Account.name}&CF00N90000006CdMG_lkid= {!Account.id}

As the link is designed to auto-fill the Account field.

The goal is to have that link allow the user to select the record type and still autofill the account field. 

Thank you so much for your help Marty, I am very appreciative.
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
I hope I explained well
Marty C.Marty C.

Hello, mikie, I'm sure there's got to be a better way to handle the situation you described, but hopefully the workaround demonstrated in the updated TransactionSiteController[1] sample will move you along.

The key here is that an apex:commandLink can specify an action that returns a PageReference, and you can construct that PageReference to have whatever parameters you want. In this way, you can pre-fill not only an Account Name but also a record type.

[1]: TransactionSiteController (http://pastebin.com/SUY0uNfm)

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
I added the sample to my extension, when I tested it out by overriding new transaction with SelectRecord, the continue button would not navigate away from itslef. It would just reload. What do you think the problem could be?

Marty C.Marty C.

Hello, mikie, when you say "overriding new transaction", do you mean setting up a Visualforce override for the standard New button on the Transaction object? Or do you mean changing the action attribute on your apex:commandLink component?

Your apex:commandLInk should look something the following:

<apex:commandLink value="New Transaction" action="{!editWithRecordType}"/>

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
My commandlink led to the new transaction record page originally, with the account autofilled. This worked when i had my visualforce new record for transactions, but I needed to be able to set record type. It has now been over-written to lead to the record select page which you left for me as an example.
Marty C.Marty C.

Hello, mikie, I think you misunderstood the purpose of my providing sample code. I didn't intend for you to use it directly in your business process. I provided the sample code hoping that you would analyze it, adapt it and incorporate the concepts into your own Visualforce page.

Concept: Record Type Picklist with New Transaction Link

You should only make changes to your org that you understand and can support down the road. The reason for this recommendation is that the Discussion Forums is not an appropriate real-time, support channel for production orgs.

I feel that you could benefit from a one-on-one meetup with an experienced developer to discuss and review the sample code and its concepts. Where are you located? There may be a develoepr user group[1] nearby that you can join and engage.

[1]: developer user group (https://success.salesforce.com/userGroups)

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Hey Marty, I figured it out. I think there was just a midunderstanding between us. 

The solution was one of the two following:

1. RecordType in the URL hacking was case sensitive

2. RecordType had to be put before the customFields in the URL hacking. 

Thank you so much for your help, I will now borrow your sampe code so that I can make the New transaction button more user friendly. 
Marty C.Marty C.

I'm glad to hear that, mikie. Thank you for the note, and good luck with your updates.

P.S. I'm going to go out on a limb and say that URL parameters are case-sensitive in all development contexts. The case-sensitivity probably affects all languages, including but not limited to JavaScript, Ruby and PHP. Interestingly enough, it looks like the W3C is still working on the URL specification[1], which has not yet been fully defined.

[1]: URL specification (http://www.w3.org/TR/url/)