I'm trying to create a dependent picklist of objects and fields. I present a list of objects to the user, and depending on the object they select, I show the object's String fields in the second picklist.
I have an actionSupport with an onchange event for the object picklist. This rerenders the fields part and calls the getter.
I am an admin and have access to the object I select. To demonstrate this, in getFieldOptions()
if I specifically set objectSelected = 'Contact'
, the initial page load correctly shows all Contact fields in the fields picklist. But if I select Contact from the objects drop-down, it fails with an "Insufficient Privileges" error. I don't know why it would work on page load and not on rerender. I have access to the VF page/Class in question.
VF:
<div id="importManualObjects">
<apex:selectList size="1" value="{!objectSelected}">
<apex:selectOptions value="{!objectOptions}"/>
<apex:actionSupport event="onchange" reRender="fields"/>
</apex:selectList>
<apex:outputPanel id="fields">
<apex:selectList size="1" value="{!fieldSelected}">
<apex:selectOptions value="{!fieldOptions}"/>
</apex:selectList>
</apex:outputPanel>
</div>
Apex snippet:
public String objectSelected {get;set;}
public String fieldSelected {get;set;}
public Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
public List<SelectOption> getObjectOptions(){
List<SelectOption> objects = new List<SelectOption>();
objects.add(new SelectOption('--None--', '--None--'));
for(Schema.Sobjecttype obj: gd.values()){
Schema.DescribeSObjectResult s = obj.getDescribe();
if(s.isAccessible() && s.isQueryable()){
SelectOption so = new SelectOption(s.getLabel(), s.getName());
objects.add(so);
}
}
return objects;
}
public List<SelectOption> getFieldOptions(){
List<SelectOption> fields = new List<SelectOption>();
fields.add(new SelectOption('--None--', '--None--'));
System.debug('object selected is: '+objectSelected);
System.debug('gd is: '+gd.get(objectSelected));
if(objectSelected != null && gd != null && gd.get(objectSelected) != null){
Schema.Describesobjectresult s = gd.get(objectSelected).getDescribe();
if(s.isAccessible() && s.isQueryable()){
System.debug('is accessible and queryable');
Map<String, Schema.SObjectField> objectFields = s.fields.getMap();
for(Schema.Sobjectfield field: objectFields.values()){
Schema.Describefieldresult f = field.getDescribe();
//Only accept String types
if(f.isAccessible() && f.getType() == Schema.Displaytype.String){
SelectOption so = new SelectOption(f.getLabel(), f.getName());
fields.add(so);
System.debug('added '+so);
}
}
}
}
return fields;
}
EDIT: Interestingly, the code works if I copy and paste to a new page. Right now it's part of a big page. I'm not sure why that would make a difference though.
EDIT2: Console error is
ERROR: POST https://.na12.visual.force.com/apex/ 500 (Server Error)
at A4J.AJAX.XMLHttpRequest.send A4J.AJAX.SubmitQuery A4J.AJAX.Submit onchange