function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
LloydSLloydS 

Render different page based upon user profile

Just starting to learn this stuff so I appreciate people bearing with me : ) I'm going through some of the virtualforce tutorials and other documentation. I created a tabbed version of the contact page. Simple to do and understand.

 

Now I have a couple of people who prefer the old, non-tabbed version. I'm assuming that I can accomodate their request by modifying the virtualforce page based upon profile (I'll create a profile such as "standard user - notabbed"). And I'm guessing I need to create a custom controller but I haven't quite gotten to that point in the learning plan yet. But I'm pretty much lost from there, and perhaps that's not even the right way of doing it.

 

Here's the code for the tabbed contact page:

 

<apex:page standardController="Contact" showHeader="true"
      tabStyle="Contact" >
   <style>
      .activeTab {background-color: #236FBD; color:white;
         background-image:none}
      .inactiveTab { background-color: lightgrey; color:black;
         background-image:none}
   </style>
   <apex:tabPanel switchType="client" selectedTab="tabdetails"
                  id="ContactTabPanel" tabClass="activeTab"
                  inactiveTabClass="inactiveTab">  
      <apex:tab label="Details" name="ContactDetails" id="tabdetails">
         <apex:detail relatedList="false" title="true"/>
      </apex:tab>
      <apex:tab label="Open Activities" name="OpenActivities"
                id="tabOpenAct">
         <apex:relatedList subject="{!contact}"
                           list="OpenActivities" />
      </apex:tab>
      <apex:tab label="Activity History" name="ActivityHistory"
                id="actHistory">
         <apex:relatedList subject="{!contact}"
                           list="ActivityHistories" />
      </apex:tab>
      <apex:tab label="Opportunities" name="Opportunities"
                id="tabOpp">
         <apex:relatedList subject="{!contact}"
                           list="opportunities" />
      </apex:tab>
      <apex:tab label="Requests" name="Cases"
                id="tabCases">
         <apex:relatedList subject="{!contact}"
                           list="Cases" />
      </apex:tab>
      <apex:tab label="Campaigns"
                name="Campaigns" id="campaigns">
         <apex:relatedList subject="{!contact}"
                           list="CampaignMembers" />
      </apex:tab>
      <apex:tab label="HTML Email Statuses"
                name="EmailStatuses" id="tabEmailStatuses">
         <apex:relatedList subject="{!contact}"
                           list="EmailStatuses" />
      </apex:tab>
      <apex:tab label="Notes and Attachments"
                name="NotesAndAttachments" id="tabNoteAtt">
         <apex:relatedList subject="{!contact}"
                           list="NotesAndAttachments" />
      </apex:tab>
   </apex:tabPanel>
</apex:page>

Best Answer chosen by Admin (Salesforce Developers) 
CTU007CTU007

If you just want some user to view the tabbed version, and others to view the standard pagelayout, IMO, this is a very easy one, no custom controller needed.

 

Create a custom field on user "tabbed contact", and use a "rendered=" in your code:

<apex:smileytongue:age standardController="Contact" showHeader="true"
tabStyle="Contact" >
<style>
.activeTab {background-color: #236FBD; color:white;
background-image:none}
.inactiveTab { background-color: lightgrey; color:black;
background-image:none}
</style>
<apex:tabPanel switchType="client" selectedTab="tabdetails"
id="ContactTabPanel" tabClass="activeTab"
inactiveTabClass="inactiveTab" rendered="{!$User.tabbedcontact__c='Yes'}">
<apex:tab label="Details" name="ContactDetails" id="tabdetails">
<apex:detail relatedList="false" title="true"/>
</apex:tab>
<apex:tab label="Open Activities" name="OpenActivities"
id="tabOpenAct">
<apex:relatedList subject="{!contact}"
list="OpenActivities" />
</apex:tab>
<apex:tab label="Activity History" name="ActivityHistory"
id="actHistory">
<apex:relatedList subject="{!contact}"
list="ActivityHistories" />
</apex:tab>
<apex:tab label="Opportunities" name="Opportunities"
id="tabOpp">
<apex:relatedList subject="{!contact}"
list="opportunities" />
</apex:tab>
<apex:tab label="Requests" name="Cases"
id="tabCases">
<apex:relatedList subject="{!contact}"
list="Cases" />
</apex:tab>
<apex:tab label="Campaigns"
name="Campaigns" id="campaigns">
<apex:relatedList subject="{!contact}"
list="CampaignMembers" />
</apex:tab>
<apex:tab label="HTML Email Statuses"
name="EmailStatuses" id="tabEmailStatuses">
<apex:relatedList subject="{!contact}"
list="EmailStatuses" />
</apex:tab>
<apex:tab label="Notes and Attachments"
name="NotesAndAttachments" id="tabNoteAtt">
<apex:relatedList subject="{!contact}"
list="NotesAndAttachments" />
</apex:tab>
</apex:tabPanel>

<apex:detail rendered="{!$User.tabbedcontact__c='No'}" />

</apex:smileytongue:age>

 

This works for me.

All Answers

ShikibuShikibu

I have a system like this working.

 

The VF:

 


<apex:page standardController="Account"
extensions="TabbedAccountControllerExtension"
showHeader="true"
tabStyle="account"
standardStylesheets="true"
action="{!routePage}"
title="OEM Services Account Detail (beta)">

 

 

 

In the controller:


// Figure out whether to display custom page or standard salesforce page

public PageReference routePage() {
if (oemUsers.contains(UserInfo.getUserId())) {
return null;
}

// Users who do not have an OEM role get the standard page
return new PageReference( '/' + acct.id + '?nooverride=1');
}

 


 
 
ShikibuShikibu

PS: Please use the "insert code" feature to avoid having your code mangled (turned into smiley faces). It looks like a clipboard with a "C" overlaid.

 

Sadly, it is broken in Safari, and perhaps other browsers as well. I usually switch to Firefox to paste code, but tonight Firefox is insisting, in an endless loop, that it does not like the ssl certificate. 

ShikibuShikibu

Just read your post more carefully and realized you might like more of the controller.

 

 


public with sharing class TabbedAccountControllerExtension {
private final Account acct;
static Set oemUsers = new Set{};

static {
setUsers();
}


// Choose who gets this page; all other users get the standard salesforce account detail page
static void setUsers() {
for (User u : [SELECT Id from User where UserRole.Name like 'OEM%' ]) {
oemUsers.add(u.id);
}
}


// The extension constructor initializes the private member
// variable acct by using the getRecord method from the standard
// controller.

public TabbedAccountControllerExtension(ApexPages.StandardController stdController) {
this.acct = (Account)stdController.getRecord();
}


// Figure out whether to display custom page or standard salesforce page

public PageReference routePage() {
if (oemUsers.contains(UserInfo.getUserId())) {
return null;
}

// Users who do not have an OEM role get the standard page
return new PageReference( '/' + acct.id + '?nooverride=1');
}
}




 

 

 

Message Edited by Shikibu on 01-25-2010 09:47 PM
LloydSLloydS

Thanks so much. This is exactly what I was looking for.

 

One issue however. When I try to save the controller extension in Develop>Apex Classes I get the following error:

 

Error: Compile Error: expecting a left angle bracket, found 'oemUsers' at line 3 column 15

 

(I will obviously be altering your code to work for mine but used your code verbatim to make sure I wasn't creating an issue with my edits)

ShikibuShikibu
Whoops, typos crept in while I was wrestling with the broken wysiwyg editor in Safari. This line should work (I confirmed that the code compiles for me with this line).

static Set<Id> oemUsers = new Set<Id>();

 

 
 
 
LloydSLloydS

Deployment failed. Looks like I'm hitting the apex governor limit. Or at least that's what I think the problem is:

 

Failure Message: "System.Exception: i:Too many query rows: 501", Failure Stack Trace: "(i) External entry point"

SteveBowerSteveBower

You might be making this too hard.  If you use an Action attribute on the <apex:Page> tag, you should be able to handle the redirect right there.

 

 

<apex:page action="{!if(contains($UserRole.Name,'OEM'),'', '{!URLFOR($Action.Account.Edit,Account.Id,[retURL=URLFOR($Action.Account.View,Account.Id)],true)')}">

So, if the users Role contains OEM, you have no action so you stay on this page and continue.  Otherwise you're redirected to the generated URL.  The last "true" parameter says "no override".

 

Check out the force.com cookbook that's kicking around somewhere... I seem to recall getting this from there, or some other SFDC doc (or perhaps one of the blogs?).

 

Best, Steve.


 

ShikibuShikibu
Good point. My routepage had some additional logic, which I removed before posting here.

Implementing your logic in VF rather than in the controller has the distinct benefit that you can edit it directly (even in production), without needing to use eclipse to deploy.
LloydSLloydS

Thank you both. It's been a good learning experience.

 

I made the change to the VF code per Shikibu's suggestion, altering it for my case where I'm looking up the Profile and not the role, and seeing if it contains the word "tabless".

 

I received an error : Illegal view ID #{URLFOR($Action.Account.Edit,Account.Id,[retURL=URLFOR($Action.Account.View,Account.Id)],true). The ID must begin with /

 

Here's the code (by the way, how do I input this specifically as code for proper formatting? is it an html tag?):

 

<apex:page standardController="Account" action="{!if(contains($Profile.Name,'tabless'),'',
                    '{!URLFOR($Action.Account.Edit,Account.Id,[retURL=URLFOR($Action.Account.View,Account.Id)],true)')}" showHeader="true"
      tabStyle="account" > 

ShikibuShikibu

There's a clipboard icon in the rich text editor toolbar, to the right of the font tools (bold, italic, etc). It has a "C" for "Code". It actually inserts the <pre> tag.

 

Sadly, it is broken in Safari and Chrome. It works in Firefox (but Firefox is complaining about the sfdc invalid certificate). I'm using Safari, and after I paste code, I preview it (observing that the forum has stripped out all newlines). Then press "Edit as html" and manually repair the html.

 

Painful. I've asked salesforce to fix it, and I've filed cases, and posted ideas, and I know that they are aware of the problem. But the problem persists.

 

 

LloydSLloydS

Decided instead of using a profile to just create a simple custom checkbox in User called Tabbed_Detail_Page. So I need to change the code to see if that box if true or false. If true, then load the VF tabbed detail page. If false, then load the standard Account Page.

 

And I also need to figure out the error:  Illegal view ID
#{URLFOR($Action.Account.Edit,Account.Id,[retURL=URLFOR($Action.Account.View,Account.Id)],true).

The ID must begin with /

 

 

<apex:page action="{!if(contains($UserRole.Name,'OEM'),'',
'{!URLFOR($Action.Account.Edit,Account.Id,[retURL=URLFOR($Action.Account.View,Account.Id)],true)')}">

 


 

 

 



LloydSLloydS

can anyone suggest why I'm getting the illegal view ID error? I've been going over the code and still don't see anything jumping out at me but my skills are quite weak in this area.

 

Thanks

ShikibuShikibu

LLoyd,

 

Would you post the actual url it's trying to open? 

LloydSLloydS
Sure thing. It is https://c.na7.visual.force.com/apex/tabbedAccount?id=001A0000004s2bA&sfdc.override=1. It's the same URL I reach successfully if I'm not using "action".
SteveBowerSteveBower

Just looking quickly, and late at night, but it seems odd to me that the URL you've provided doesn't seem to have a "&retURL=somthing" parameter on it. 

 

So, I think something else must be going on.  Perhaps posting the controller code and VF would help.  Or, I could just be tired.  :-)

 

Best, Steve

CTU007CTU007

If you just want some user to view the tabbed version, and others to view the standard pagelayout, IMO, this is a very easy one, no custom controller needed.

 

Create a custom field on user "tabbed contact", and use a "rendered=" in your code:

<apex:smileytongue:age standardController="Contact" showHeader="true"
tabStyle="Contact" >
<style>
.activeTab {background-color: #236FBD; color:white;
background-image:none}
.inactiveTab { background-color: lightgrey; color:black;
background-image:none}
</style>
<apex:tabPanel switchType="client" selectedTab="tabdetails"
id="ContactTabPanel" tabClass="activeTab"
inactiveTabClass="inactiveTab" rendered="{!$User.tabbedcontact__c='Yes'}">
<apex:tab label="Details" name="ContactDetails" id="tabdetails">
<apex:detail relatedList="false" title="true"/>
</apex:tab>
<apex:tab label="Open Activities" name="OpenActivities"
id="tabOpenAct">
<apex:relatedList subject="{!contact}"
list="OpenActivities" />
</apex:tab>
<apex:tab label="Activity History" name="ActivityHistory"
id="actHistory">
<apex:relatedList subject="{!contact}"
list="ActivityHistories" />
</apex:tab>
<apex:tab label="Opportunities" name="Opportunities"
id="tabOpp">
<apex:relatedList subject="{!contact}"
list="opportunities" />
</apex:tab>
<apex:tab label="Requests" name="Cases"
id="tabCases">
<apex:relatedList subject="{!contact}"
list="Cases" />
</apex:tab>
<apex:tab label="Campaigns"
name="Campaigns" id="campaigns">
<apex:relatedList subject="{!contact}"
list="CampaignMembers" />
</apex:tab>
<apex:tab label="HTML Email Statuses"
name="EmailStatuses" id="tabEmailStatuses">
<apex:relatedList subject="{!contact}"
list="EmailStatuses" />
</apex:tab>
<apex:tab label="Notes and Attachments"
name="NotesAndAttachments" id="tabNoteAtt">
<apex:relatedList subject="{!contact}"
list="NotesAndAttachments" />
</apex:tab>
</apex:tabPanel>

<apex:detail rendered="{!$User.tabbedcontact__c='No'}" />

</apex:smileytongue:age>

 

This works for me.
This was selected as the best answer
LloydSLloydS

Thanks CTU007. That worked perfectly. I created a custom checkbox field with the rendered function. Simple solution. Thanks to everyone else as well. Good learning experience.

 

Final code attached.

<apex:page standardController="Contact" showHeader="true" tabStyle="Contact" > <style> .activeTab {background-color: #236FBD; color:white; background-image:none} .inactiveTab { background-color: lightgrey; color:black; background-image:none} </style> <apex:tabPanel switchType="client" selectedTab="tabdetails" id="ContactTabPanel" tabClass="activeTab" inactiveTabClass="inactiveTab" rendered="{!$User.tabbedcontact__c=true}"> <apex:tab label="Details" name="ContactDetails" id="tabdetails"> <apex:detail relatedList="false" title="true"/> </apex:tab> <apex:tab label="Open Activities" name="OpenActivities" id="tabOpenAct"> <apex:relatedList subject="{!contact}" list="OpenActivities" /> </apex:tab> <apex:tab label="Activity History" name="ActivityHistory" id="actHistory"> <apex:relatedList subject="{!contact}" list="ActivityHistories" /> </apex:tab> <apex:tab label="Opportunities" name="Opportunities" id="tabOpp"> <apex:relatedList subject="{!contact}" list="opportunities" /> </apex:tab> <apex:tab label="Requests" name="Cases" id="tabCases"> <apex:relatedList subject="{!contact}" list="Cases" /> </apex:tab> <apex:tab label="Campaigns" name="Campaigns" id="campaigns"> <apex:relatedList subject="{!contact}" list="CampaignMembers" /> </apex:tab> <apex:tab label="HTML Email Statuses" name="EmailStatuses" id="tabEmailStatuses"> <apex:relatedList subject="{!contact}" list="EmailStatuses" /> </apex:tab> <apex:tab label="Notes and Attachments" name="NotesAndAttachments" id="tabNoteAtt"> <apex:relatedList subject="{!contact}" list="NotesAndAttachments" /> </apex:tab> </apex:tabPanel> <apex:detail rendered="{!$User.tabbedcontact__c=false}" /> </apex:page>

 


 

LloydSLloydS

Another modification . . . How do handle multiple Record Types so that only those tabs related to the specific Record Type are displayed?

 

Do I modify the rendered function with some type of AND statement?

 

 

CTU007CTU007

Yes, you can use && to to rendered function

 

 

rendered="{!$user.tabbedcontact__c && contact.recordtype.name='xxxxxx'}

 

 and you can also use or ( || ) in your condition.