+ Start a Discussion
Brianna BollettieriBrianna Bollettieri 

Opportunity Screen Modifications based on Stage using Field Sets and Visualforce Pages

Currently I am working on changing our opportunity screen to change the way it is being filled out. This way it follows our sales process. A simple way to put it is that I have created 5 sections on the opportunity screen each representing a different stage. Now what I want to happen is that each time a stage is selected, I would like that section to become available for editing. All new opportunities should begin in the opportunity section, therefore I would like that section to be available for editing, but I want the other sections to be visible but locked from being edited. Then once the next stage is selected, the next section becomes available for editing and the remainder remain visible but locked, etc.

So far I tried testing this with just the opportunity stage. What I did was I created a field set including all the fields in the opportunity section. Then I created a visualforce page. My current issue with this is that it is doing the opposite of what I want. It is blocking the opportunity section (and it is not even visible) until after I save the record. Once the record is saved the opportunity section appears but the entire screen is available for editing. This is my current visualforce page criteria.

<apex:page standardController="Opportunity"> 
    <apex:form >
            <apex:pageblock > 
                    <apex:pageBlockSection title="Opportunity"> 
                         <apex:repeatvalue="{$ObjectType.Opportunity.fieldsets.opportunityFieldSet}"var="fieldValue">                    
                                 <apex:Inputfield value="{!Opportunity[fieldValue]}"/> 
                          </apex:repeat>
                    </apex:pageBlockSection> 
             </apex:pageblock>
         </apex:form> 
  </apex:page>

Any assistance would be greatly appreciated. Thanks!
Best Answer chosen by Brianna Bollettieri
RaidanRaidan
I am missing the "!" in the first rendered condition.
<apex:pageBlockSection title="Opportunity">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.opportunityFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Needs & Requirements">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity'}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Proposal & Sell">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.psFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements'}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Closed Won || Closed Lost">
<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.cwclFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell'}" />
</apex:repeat>
</apex:pageBlockSection>

 

All Answers

RaidanRaidan
Hi Brianna,

You can use the rendered attribute to display/hide an element. In your case here, you can do something like this:
<apex:pageBlockSection title="Opportunity"> 
	<apex:repeat value="{$ObjectType.Opportunity.fieldsets.opportunityFieldSet}"var="fieldValue">                
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName='New'}" /> 
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName!='New'}" /> 
    </apex:repeat>
</apex:pageBlockSection>
As you can see, based on the StageName = 'New' (you can change it with the real stage name) we display the inputField and hide the outputField. When the StageName is not 'New' anymore, then the outputField will display. Let me know if you need further details.


 
Brianna BollettieriBrianna Bollettieri
Hi Raldan,

It is still blocking the Opportunity section from being viewed and edited when I create a new opportunity. It only appears on the screen after I save the opportunity. And it is allowing all sections on the opportunity screen to be edited as I had previously.
RaidanRaidan
Ah, when you create a new opportunity, the StageName is still NULL. Perhaps you want to add that condition to the rendered attribute.
You are creating a separate section and a separate fieldset for each StageName, right? Say you have 2 stages, then the code will look like:
<apex:pageBlockSection title="Opportunity Stage 1"> 
	<apex:repeat value="{$ObjectType.Opportunity.fieldsets.opportunityFieldSet1}"var="fieldValue">                
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Stage 1'}" /> 
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!!ISBLANK(Opportunity.StageName) && Opportunity.StageName!='Stage 1'}" /> 
    </apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Opportunity Stage 2"> 
	<apex:repeat value="{$ObjectType.Opportunity.fieldsets.opportunityFieldSet2}"var="fieldValue">                
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName='Stage 2'}" /> 
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!!ISBLANK(Opportunity.StageName) && Opportunity.StageName!='Stage 2'}" /> 
    </apex:repeat>
</apex:pageBlockSection>
I am not sure if you want to display section 2 during creation. If you do, then just remove the !ISBLANK(Opportunity.StageName).
 
Brianna BollettieriBrianna Bollettieri
Hi Raldan,

Now it is not displaying either section upon creation, only once the record is created. Once the record is created it is working with edit access for each section based on the stage on the screen itself. But when I select the edit button the sections are no longer visible again. This is the current code that's being used.

<apex:page standardController="Opportunity">
    <apex:form >
            <apex:pageblock >
            <apex:pageBlockSection title="Opportunity">
                    <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.opportunityFieldSet}" var="fieldValue">
                            <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity'}" /> 
                            <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!!ISBLANK(Opportunity.StageName) && Opportunity.StageName!='Opportunity'}" />
                                 </apex:repeat>
                             </apex:pageBlockSection>
                             <apex:pageBlockSection title="Needs & Requirements">
                                     <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
                                             <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName='Needs & Requirements'}" />
                                             <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!!ISBLANK(Opportunity.StageName) && Opportunity.StageName!='Needs & Reuirements'}" />
                                       </apex:repeat>
                                    </apex:pageBlockSection>
                            </apex:pageblock>
                         </apex:form>
                  </apex:page>
RaidanRaidan
Did you override the New and Edit buttons of the Opportunity object with this Visualforce page?
Brianna BollettieriBrianna Bollettieri
I didn't! How can I override them?
RaidanRaidan
You can do it from the Setup -> Customize -> Opportunities -> Button, Links, Actions. Click Edit on the New button, then override it with your Visualforce page. You probably also want to do the same with the Edit button later.
Brianna BollettieriBrianna Bollettieri
Awesome that worked! 2 more hopefully quick questions.

1. I know you mentioned earlier in order to display section 2 during creation. To just remove the !ISBLANK(Opportunity.StageName). Where would I remove that from? Each time it appears?
2. Is there a way to override standard fields? I have the fields in the field sets so they are still on the screen, but it won't allow me to remove it from the page layout so I was wondering if there was some way to override that.

Thanks for all your help so far, you have been extremely helpful!
Brianna BollettieriBrianna Bollettieri
One more question, once the stage is changed and it moves onto the next section, it locks the previous section from being edited. Is there a way to leave the previous section available for editing?
RaidanRaidan
Glad that it worked!

1. ISBLANK({!Opportunity.StageName}) is one way of telling us that the Opportunity is brand new. You can use in the section where you want to show/hide your field (not the section). If you want to make the field read-only, display the outputField. And to make the field editable, display the inputField. Hopefully this is pretty clear. If it is not, I can go into details with you.
2. If the field is required, I don't think you can remove it from the layout. Some standard fields, like Name, are required.
3. If you want to leave the previous section to be editable, it will be a little tricky because you will have to add all previous stages in the condition. Something like {!Opportunity.StageName="Stage 1" || Opportunity.StageName="Stage 2"}. However, if your stage starts with a number (e.g.: 1 - Stage 1, 2 - Stage 2), it will be much easier to write the conditions.

Please don't forget to mark my answer if you find it useful. It will help others who are having the same questions. Thanks!
Brianna BollettieriBrianna Bollettieri
So I tried the below code and it didn't make a difference in being able to edit the previous section. I'm assuming I'm missing something.

<apex:page standardController="Opportunity">
    <apex:form >
            <apex:pageblock >
            <apex:pageBlockSection title="Opportunity">
                    <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.opportunityFieldSet}" var="fieldValue">
                            <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity'}" /> 
                            <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!!ISBLANK(Opportunity.StageName) && Opportunity.StageName!='Opportunity'}" />
                                 </apex:repeat>
                             </apex:pageBlockSection>
                             <apex:pageBlockSection title="Needs & Requirements">
                                     <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
                                             <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{Opportunity.StageName='Opportunity' || !Opportunity.StageName='Needs & Requirements'}" />
                                             <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{Opportunity.StageName!='Opportunity' || Opportunity.StageName!='Needs & Reuirements'}" />
                                       </apex:repeat>
                                    </apex:pageBlockSection>
                            </apex:pageblock>
                         </apex:form>
                  </apex:page>
Brianna BollettieriBrianna Bollettieri
Also when I select edit on the opportunity screen there is no longer a save option. Also because I selected override the edit and new button for this visualforce page, it now effects all record types.
RaidanRaidan
There are 2 issues with the second section logic. The first one is the "!" in the second part of the first rendered condition. And the second on is the "||" in the second rendered condition. Here is the fix:
<apex:pageBlockSection title="Needs & Requirements">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
 		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements'}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{Opportunity.StageName!='Opportunity' && Opportunity.StageName!='Needs & Requirements'}" />
	</apex:repeat>
</apex:pageBlockSection>
If you override the standard button with a Visualforce, you will also have to implement the "Save" and "Cancel" buttons. But that is super easy because you are using a StandardController, so the actions are already written for you. Just add an apex command button, and set the action to "save".
<apex:commandButton action="{!save}" value="Save" />


 
Brianna BollettieriBrianna Bollettieri
With that code the next section is now completely blank. Also it is only allowing me to add one command button which is the Save button. It won't allow me to add both save and cancel.
Brianna BollettieriBrianna Bollettieri
Never mind, I got the cancel button and edit button to work! Still having the other issue.
RaidanRaidan
Is it blank during creation or edit? I think I missed the "!" at the beginning of the rendered condition. Sorry. Let's try that again.
<apex:pageBlockSection title="Needs & Requirements">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
 		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements'}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName!='Opportunity' && Opportunity.StageName!='Needs & Requirements'}" />
	</apex:repeat>
</apex:pageBlockSection>

 
Brianna BollettieriBrianna Bollettieri
Okay so now upon creation it is perfect. But once it is created it allows all sections to be edited. Then once the stage is changed from opportunity to the next stage, it locks the previous section. So it is doing the opposite. I want it to lock all upcoming sections and leave the previous one open to be edited as well.
RaidanRaidan
I don't know how many stages you have for the opportunity (I believe they are more than 2?). You will have to create one section for each to allow the page to work correctly. And is there a default stage when an opportunity is created?
Brianna BollettieriBrianna Bollettieri
Well I have 4 stages and they each have their own section. There isn't a default stage when an opportunity is created. I would like to default the stage to opportunity when a new opportunity is created but I can't seem to do so because stage is a standard field so it won't update that field on the visualforce page.
RaidanRaidan
So you have the complete Visualforce code with all 4 sections? If after creation all sections are editable, that means the new stage is not handled properly in the page. What was the stage after creation when you tested it?
Brianna BollettieriBrianna Bollettieri
Okay so this is the code I am currently using. When a new opportunity is being created it displays all sections but only allows the opportunity section to be edited as I wanted. So that part is great. But once I create the record all 4 sections become editable. Then once I move onto the next stage, it locks the previous section from being edited. Hope that makes sense. If you need me to explain it better, let me know.

<apex:page standardController="Opportunity">
    <apex:form >
        <apex:pageBlock title="Opportunity" mode="edit">
                <apex:pageBlockButtons >
                    <apex:commandButton action="{!save}" value="Save"/> <apex:commandButton action="{!cancel}" value="Cancel" immediate="true"/> <apex:commandButton value="edit" action="{!Edit}" immediate="true"/>
                 </apex:pageBlockButtons>
             <apex:pageBlockSection title="Opportunity">
                     <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.opportunityFieldSet}" var="fieldValue">
                             <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity'}" />
                            <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!!ISBLANK(Opportunity.StageName) && Opportunity.StageName!='Opportunity'}" />
                      </apex:repeat>
                  </apex:pageBlockSection>
                  <apex:pageBlockSection title="Needs & Requirements">
                          <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
                                  <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements'}" />
                                  <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName!='Opportunity' && Opportunity.StageName!='Needs & Requirements'}" />
                        </apex:repeat>
                    </apex:pageBlockSection>
                    <apex:pageBlockSection title="Proposal & Sell">
                            <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.psFieldSet}" var="fieldValue">
                                    <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell'}" />
                                    <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName!='Opportunity' && Opportunity.StageName!='Needs & Requirements' && Opportunity.StageName!='Proposal & Sell'}" />
                             </apex:repeat>
                      </apex:pageBlockSection>
                      <apex:pageBlockSection title="Closed Won || Closed Lost">
                              <apex:repeat value="{!$ObjectType.Opportunity.fieldsets.cwclFieldSet}" var="fieldValue">
                                      <apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell' || Opportunity.StageName='Closed Won' || Opportunity.StageName='Closed Lost'}" />
                              <apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!Opportunity.StageName!='Opportunity' && Opportunity.StageName!='Needs & Requirements' && Opportunity.StageName!='Proposal & Sell'&& Opportunity.StageName!='Closed Won' && Opportunity.StageName!='Closed Lost'}" />
                       </apex:repeat>
                   </apex:pageBlockSection>
            </apex:pageblock>
        </apex:form>
</apex:page>
RaidanRaidan
Ah! Now I can see the whole thing, I think I kinda understand what you are trying to do here. In this case, the first section will always be editable because you want to allow other stages to edit the previous sections. Try the code below, after I simplified the logic:
<apex:pageBlockSection title="Opportunity">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.opportunityFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Needs & Requirements">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity'}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Proposal & Sell">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.psFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements'}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Closed Won || Closed Lost">
<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.cwclFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell'}" />
</apex:repeat>
</apex:pageBlockSection>

 
Brianna BollettieriBrianna Bollettieri
Okay so now that code duplicated all the fields in each section and allows editing in each section during creation as well as once a record is created.
RaidanRaidan
I am missing the "!" in the first rendered condition.
<apex:pageBlockSection title="Opportunity">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.opportunityFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Needs & Requirements">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.nrFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity'}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Proposal & Sell">
	<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.psFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements'}" />
	</apex:repeat>
</apex:pageBlockSection>
<apex:pageBlockSection title="Closed Won || Closed Lost">
<apex:repeat value="{!$ObjectType.Opportunity.fieldsets.cwclFieldSet}" var="fieldValue">
		<apex:inputField value="{!Opportunity[fieldValue]}" rendered="{!!(ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell' )}" />
		<apex:outputField value="{!Opportunity[fieldValue]}" rendered="{!ISBLANK(Opportunity.StageName) || Opportunity.StageName='Opportunity' || Opportunity.StageName='Needs & Requirements' || Opportunity.StageName='Proposal & Sell'}" />
</apex:repeat>
</apex:pageBlockSection>

 
This was selected as the best answer
Brianna BollettieriBrianna Bollettieri
Now it's perfect!! Thank you so much!! Now I'm just trying to figure out a way for the visualforce page to recognize that the standard fields are being used on the visualforce page.
RaidanRaidan
Glad that it worked! Don't forget to mark my answer to help others with the same question. Thanks!
Brianna BollettieriBrianna Bollettieri
Hi Raldan,

I have a question about record types. There are 2 record types that I want this VF page to apply to as well as the button overrides (New, Edit, and View) to apply to. Do I have to create a separate VF page for this or is there a way to add it to this VF page? Either would work.

Thanks!