Find your content:

Search form

You are here

How to treat $ObjectType.{sobject}.name as a string in a merge field?

 
Share

I have a VF Page that can be used with multiple SObject types (e.g., Account, Case, Contact). It uses a custom controller that determines the SObject type and exposes it as a property named recordType. This allows VF code in the page (or in components on the page) to dynamically show or hide content, for example:

<apex:outputText rendered="{!recordType == 'Account'}" value="..." />

This all works fine. However, instead of inline string values (e.g., 'Account'), we tried to change the code to this:

<apex:outputText rendered="{!recordType == $ObjectType.Account.name}" value="..." />

This doesn't work, and I could not find documentation of $ObjectType. properties, return types, etc., only example usage. Building some tests into the VF Page proved this:

//sample output
$ObjectType.Account.Name: Account
$ObjectType.Account.Name == 'Account': false

So $ObjectType.Account.Name can't even be compared with a literal string, but outputting it on the page ( {!ObjectType.Account.Name} ) produces a stringified result. This attempt:

<apex:outputText rendered="!recordType == TEXT($ObjectType.Account.name)" value="..." />

produced an error while saving the page that TEXT() expects a number, percent, etc, not an Object. So $ObjectType.Account.name returns an object, but attempts to add .toString() and .toString don't work (as expected on a merge property).

So, is there any way to test against $ObjectType.Account.Name? We came up with one - stashing the value in an apex variable like so:

<apex:variable var="AcctRecType" value="{!$ObjectType.Account.Name}" />

puts the string value 'Account' into the variable, allowing it to be tested. However, we use this pattern in a number of custom components, so we will need to add this variable to each one, perhaps several (the page supports multiple record types), e.g.,

<apex:variable var="AccountRecType" value="{!$ObjectType.Account.Name}" />
<apex:variable var="CaseRecType" value="{!$ObjectType.Case.Name}" />
<apex:variable var="ContactRecType" value="{!$ObjectType.Contact.Name}" />

We could also expose these names as properties on the custom controller, but that starts to feel cumbersome. Which leads me back to my original question: Is there any way to treat $ObjectType.{sobject}.name as a string for comparison within a VF mergefield?


Attribution to: Jason Clark

Possible Suggestion/Solution #1

As long as your Name and Label are the same, you should be able to use the Label attribute, which returns a String

{!$ObjectType.Account.Label == 'Account'}

evaluates to true


Attribution to: techtrekker

Possible Suggestion/Solution #2

Do you have to compare a field of the object? If not you could compare the object type itself.

<apex:outputText rendered="{!recordType == $ObjectType.Account}" value="..." />

where recordType would need to be the Id key prefix, e.g for account the value is '001', case the value is '500'

I think this approach is safer than using label, because the label could change at any time and break the code.


Attribution to: Daniel Blackhall

Possible Suggestion/Solution #3

Have you considered going with dynamic visualforce (VF generated from Apex)?

The level of flexibility that you seem to need could perhaps be well served by moving the logic of what to build on the page into code, as opposed to the Visualforce markup?

As far as reusability goes, you could also write this into a library of apex code that could then be easily plugged into many different pages/components.

You will also have a lot more fine grained control over logic.

Downside is that it is clunkier than just writing visualforce. But in your case you might find it worth the extra effort.


Attribution to: pchittum

Possible Suggestion/Solution #4

I think this is a Salesforce defect.

According to the $ObjectType documentation, $ObjectType.Lead.name should return a string, but as you can see if you try something like

{!$ObjectType.Lead.name + ''}

you get an error

Incorrect parameter type for operator '+'. Expected Text, received Object

showing that it is returning an object.

The same issue exists for field schema details, e.g.

{!$ObjectType.Lead.Fields.Phone.name + ''}

but works ok for

{!$ObjectType.Lead.Fields.Phone.localName + ''}

despite both Data Types being defined as strings.


Attribution to: James

Possible Suggestion/Solution #5

I think that best solution is to utilize map syntax of VisualForce rendered="{!$ObjectType[recordType].Name == ($ObjectType.CampaignMember.Name)}"


Attribution to: pklochkov
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/2280

My Block Status

My Block Content