I did a small test program to dynamically populate a set of fields onto a Visualforce page, which can enable users to enter data from the form.
Created a fieldset as below.
Then I did an Apex page to handle Form inputs.
<apex:pageBlockSection >
<apex:dynamicComponent componentValue="{!DynamicFields}" id="dynamic_pbs"/>
</apex:pageBlockSection>
<apex:pageblockButtons >
<apex:commandButton value="Submit" action="{!SaveData}" />
</apex:pageblockButtons>
</apex:pageBlock>
</apex:form>
My controller class as below.
public SObject FormObject{get;set;}
public FormGenController(){
obj_name = ApexPages.currentPage().getParameters().get('obj');
fieldSetName = ApexPages.currentPage().getParameters().get('fs');
...
}
Below method to generate dynamic object fields,
void Build_Dynamic_SObject(){
try{
String field_selection = 'SELECT ID,';
List<Schema.FieldSetMember> list_of_fields = getFieldsToDisplay();
for(Schema.FieldSetMember fld : list_of_fields){
field_selection = field_selection + fld.getFieldPath() +',';
}
field_selection = field_selection.substring(0,field_selection.length()-1);
if(String.isEmpty(id_str)){
field_selection = field_selection + ' FROM ' + obj_name + ' LIMIT 1 ';
}
else{
field_selection = field_selection + ' FROM ' + obj_name + ' WHERE ( id = :id_str ) LIMIT 1 ';
}
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, field_selection));
FormObject = Database.query(field_selection);
Generating the page block for apex page.
public Component.Apex.PageBlock getDynamicFields() {
System.debug('Get dynamic fields start: ' + FormObject);
try{
Component.Apex.PageBlock dynPageBlock = new Component.Apex.PageBlock();
List<Schema.FieldSetMember> list_of_fields = getFieldsToDisplay();
Component.Apex.PageBlockSection pbs = new Component.Apex.PageBlockSection();
pbs.columns = 1;
for(Schema.FieldSetMember fld : list_of_fields){
// Add label
//Component.Apex.OutputLabel display_label = new Component.Apex.OutputLabel();
//display_label.value = fld.getLabel() ;
//display_label.for = fld.getFieldPath();
//pbs.childComponents.add(display_label);
// input field
Component.Apex.InputField input_field = new Component.Apex.InputField();
input_field.expressions.value = '{!FormObject.' + fld.getFieldPath() +'}';
input_field.id = fld.getFieldPath();
pbs.childComponents.add(input_field);
}
dynPageBlock.childComponents.add(pbs);
There is no code in submit button, and I tested without assigning Action as well. When I click sumbit, it gives me below error which seems weird.
Unknown property 'SObject.Description' Error is in expression '{!FormObject.Description}' in component in page formgen_page
Notes:
- Seems Contact object retrieved via Database.Query() is being reset at some point.
- If I use Immediate="TRUE" in Apex command button mark up, Action method fires, but with no validations, data is not flushed to bound objects.
- It seems nothing to do with fieldsets as when I changed the field order, it prompts me with the top most (first entry in field set).
In Debug Log, it's logged as:
EXCEPTION_THROWN|[EXTERNAL]|System.VisualforceException: Read access denied for null, controller action methods may not execute