6

I have a VisualForce / Apex form. There is a dropdown SelectList input field for object. I want to load the list of fields for the selected object in a second select list on the same form.

I've tried to use rerender but cannot get it to work so far. The Field select list starts empty and remains empty when changing the Object dropdown.

Page:

<apex:page controller="MyClass">
 <apex:form >
    <apex:pageBlock title="Create" mode="edit">
        <apex:messages />
        <apex:pageBlockButtons >
            <apex:commandButton action="{!step2}" value="Next"/>
        </apex:pageBlockButtons>
        <apex:pageBlockSection title="Select details" columns="2">
            <apex:pageBlockSectionItem >
                <apex:outputLabel for="Object" value="Object"/>
                <apex:selectList id="Object" value="{!myobj.Object__c}" size="1">
                  <apex:selectOptions value="{!ObjectNames}"/>
                  <apex:actionSupport event="onchange" reRender="Field"/>
                </apex:selectList>
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem>
                <apex:outputLabel for="Field" value="Field"/>
                <apex:selectList id="Field" value="{!myobj.Field__c}" size="1">
                  <apex:selectOptions value="{!SobjectFields}"/>
                </apex:selectList>
            </apex:pageBlockSectionItem> 
        </apex:pageBlockSection>
    </apex:pageBlock>
    </apex:form>
</apex:page>

Controller:

public List<SelectOption> getSobjectFields()   
{  
    List<SelectOption> fields = new List<SelectOption>(); 

    if (myobj.Object__c != null) {

    Map<String,Schema.SObjectType> gd = Schema.getGlobalDescribe();  
    Schema.SObjectType sobjType = gd.get(myobj.Object__c);  
    Schema.DescribeSObjectResult r = sobjType.getDescribe();  
    Map<String,Schema.SObjectField> M = r.fields.getMap();  

    for(String fieldName : M.keyset())  
        {  
            Schema.SObjectField field = M.get(fieldName);                                                      
            Schema.DescribeFieldResult fieldDesc = field.getDescribe();  
            fields.add(new SelectOption(fieldName.toLowerCase(),fieldName.toLowerCase())); 
        }  
    }

    return fields;  
}
2
  • Have you tried adding an ID to the pageBlockSection and re-render the whole section? I've noticed sometimes you need to re-render the parent element in order to get the new values for the components inside of it. Commented Oct 14, 2013 at 4:05
  • Yes, I tried adding an id to the block section and I tried wrapping the select list in an apex:outputPanel. I also tried wrapping the entire block section in an outputPanel and rerendering that. Nothing I've tried has worked.
    – wisemanIV
    Commented Oct 14, 2013 at 4:16

1 Answer 1

3

This appears to work depending on which objects are selected in the first list. My guess at this point is that there is some permissions issue where my user doesn't have access to the fields on all objects when accessed via -

Map<String,Schema.SObjectType> gd = Schema.getGlobalDescribe();  
Schema.SObjectType sobjType = gd.get(myobj.ObjectName);  

Updated with full solution:

I added a filter to my code that builds the Object list in the first dropdown. For each object type I try to describe it and if that returns null I don't add it as an option. Now whatever object I select the field dropdown is dynamically updated with the associated fields.

I think this solution will work for me. There may be a better answer to select the filtered list of objects using the describe methods?

public List<SelectOption> getSobjectFields()   
{  
    List<SelectOption> fields = new List<SelectOption>(); 

    Schema.SObjectType sobjType = gd.get(myobj.ObjectName);  
    if (sobjType != null) {
    Schema.DescribeSObjectResult r = sobjType.getDescribe();  
    Map<String,Schema.SObjectField> M = r.fields.getMap();  

    for(String fieldName : M.keyset())  
        {  
            Schema.SObjectField field = M.get(fieldName);                                                      
            Schema.DescribeFieldResult fieldDesc = field.getDescribe();  
            fields.add(new SelectOption(fieldName.toLowerCase(),fieldName.toLowerCase())); 
        }  
    }


    return fields;  
}      

public List<SelectOption> getObjectNames()
{
   List<Schema.SObjectType> gdo = Schema.getGlobalDescribe().Values(); 
   List<SelectOption> options = new List<SelectOption>();

   for(Schema.SObjectType f : gdo)
   {
       Schema.SObjectType sobjType = gd.get(f.getDescribe().getLabel());  
       if (sobjType != null) {
          options.add(new        SelectOption(f.getDescribe().getLabel(),f.getDescribe().getLabel()));
       }
   }
   return options;

}
1
  • from @user5623 (created as answer when it should be a comment), I am new to Visual Force/Apex. I have a similar requirement as mentioned above and wanted to try how the above code works, But I am getting couple of errors when I copy, pasted above code. (variable doesn't exists myobj.ObjectName), could you be kind to paste the complete working code. Thanks in advance. Commented Jan 31, 2014 at 21:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .