5

In my controller, I have some SObjectType property:

public SObjectType myProperty { get; private set; }

I want to get the label (or better yet the entire describe) of this object in Visualforce without modifying my Apex to add any additional properties. Is it possible?

In my current use case, this property is surfaced as part of a larger feature and can't be easily modified or extended.


Attempt 1:

{!myProperty.describe.label}

Error 1:

Unknown property 'SObjectTypeToken.describe'


Attempt 2:

{!$ObjectType[myProperty].label}

Error 2:

Incorrect parameter type for subscript. Expected Text, received SObjectType


Attempt 3:

{!TEXT(myProperty)}

Error 3:

Incorrect parameter type for function 'TEXT()'. Expected DateTime, received SObjectType


Attempt 4:

{!myProperty.label}

Error 4:

Unknown property 'SObjectTypeToken.label'

  • Great timing on your question. I'm working on something where I've been struggling with the similar issues! +1 @Ronnie answer is the kind of solution that I came up with which ultimately worked for me. Great addition with Eric's comments that I'll find helpful as I continue. – crmprogdev Sep 2 '17 at 13:37
5
+100

Controller:

public class Test{
    public Schema.SObjectType myProperty { get; private set; }


    public Test(){
        myProperty = Schema.getGlobalDescribe().get( 'Account' );
    }
}    

<apex:page controller="Test">
      <apex:variable value="{!myProperty}" var="prop" />
      <apex:variable value="{!prop[ 'describe' ]}" var="field" />
      {!field}
</apex:page>

Above is an output of the describe result which will get the properties that you will want to see - you can use this to pull back the items you need by their keys ['label'], ['name']...

Display the object type result on the page

<apex:page controller="Test">
  <apex:variable value="{!myProperty}" var="prop" />
  <apex:variable value="{!prop[ 'describe' ]}" var="field" />
  {!field['localName']}
</apex:page>

Here you will see that you can output the value by its key in the describe map

Display the propertys by their Keys in the describe map

Eric Added

Also you can do away with the variables and just do {!prop['describe']['localName']}

  • Edited this response to use just the SObjectType in your controller - i set to account for example purposes - try it out – Ronnie Sep 2 '17 at 3:18
  • 3
    @AdrianLarson Well all be d&mned.....Never would have thought that an SObjectType token would have a key of describe that could be pulled into a VF page. NICE ONE – Eric Sep 2 '17 at 3:35
  • 1
    Nice answer guys! I nearly posted a similar question earlier this week. – crmprogdev Sep 2 '17 at 13:37
  • 1
    this merits making a documentation suggestion to the VF doc team – cropredy Sep 2 '17 at 19:31
  • 1
    I didn't even see this answer (nor bounty) get added. I was busy climbing some mountains and didn't have any internet access for a few days. When I got back, didn't see any notifications. What a pleasant surprise! This one is a game changer for me. Thanks! – Adrian Larson Sep 22 '17 at 2:27
2

Just to throw this out there as an option, even though you desire to not modify your Apex - since the $ObjectType global variable requires a string for its key:

public SObjectType myProperty { get; private set; }

public String getObjectName() {
    // check for null & stuff
    return myProperty.getDescribe().getName();
}

and then in VF

<apex:outputText value="{!$ObjectType[objectName].label}"/>
  • It's a collection though, so this particular approach doesn't work great for me. Right now I've got a shadow Map<SObjectType, DescribeSObjectResult> property, but I'm trying to find a way to get rid of that. :( – Adrian Larson Aug 31 '17 at 19:51
1

You can use $ObjectType, but you do need to modify your code:

public SObjectType myProperty { get; private set; }
public String myPropertySObjectType { get { return myproperty+''; } }

{!$ObjectType[myPropertySObjectType].label}
  • Essentially the same as what Mark proposes. Same pitfall for my needs. It's a collection. – Adrian Larson Aug 31 '17 at 19:57
  • @AdrianLarson You need to have a String, ultimately, if you want to skip the describe in Apex Code. Without seeing more code, I'm not sure that we'll be able to give you much more than variants of the same. – sfdcfox Aug 31 '17 at 20:03
1

See Ronnie's answer

A bit heavy Handed but using JS you can get the label from the REST API then you could use JS to put the label where you need it....and it requires no change to your Apex code

<apex:page controller="[YOUR CONTROLLER}">
<apex:includeScript value="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"/>
<script>
    var t = '{!objectName}';

jQuery(document).ready(function($) {
      $.ajax('/services/data/v40.0/sobjects/' + t + '/describe/',
        {
          beforeSend: function(xhr) {
            // Set the OAuth header from the session ID
            xhr.setRequestHeader('Authorization', 'Bearer {!$Api.Session_ID}');
          },
          success: function(response) {
              console.log('The Label is: ' + response.label);
          },
          error: function(jqXHR, textStatus, errorThrown) {
            // Oops - what went wrong?
            alert(jqXHR.status + ': ' + errorThrown);
          }
        }
      );
    });

</script>

</apex:page>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.