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. – Boris Bachovski Oct 14 '13 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 Oct 14 '13 at 4:16
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. – Ralph Callaway Jan 31 '14 at 21:19

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.