function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Uzair Ahmadani 4Uzair Ahmadani 4 

dynamic bound field on vf page

Hi,

I Have got a customer object by the name ExecuteContext. It has fields:
  1. ID - AutoNumber 
  2. Object Name - Text(250)
  3. Field Name - Text(250)
  4. Field Value - longtext
I would override the new and edit button to show my VF page ExecuteContext in it i would
  1. Dispaly list of all editable objects in a picklist that exists in my org.
  2. On selection of an object  display related fields in the picklist
  3. On selection of Field display the respective input field which is displayed based on the type of field (checkbox, picklist, multipicklist, lookup, date, datetime etc)
  4. After selecting/entering value in input field click save.
  5. On Save pick entered value in input field.
  6. Save the ExecuteContext Record
I have done steps 1 - 4 having issue in step 5.i.e. 
string sFieldinputVal = (String)inputObj.get(sFieldsVal);
i have set the input field as: 
<apex:inputField value="{!inputObj[sFieldsVal]}"/>
where
InputObj is Sobject and is set when getting the fields
sFieldsVal is selected field api name.

I am providing the complete code below as well:

VF PAGE
<apex:page standardController="ExecuteContext__c" extensions="ExecuteContextController">
  <apex:outputpanel >
    <apex:actionstatus id="actStatusId">
      <apex:facet name="start">
        <div class="waitingSearchDiv" id="el_loading" style="background-color: #DCD6D6;
                       height: 100%;opacity:0.65;width:100%;"> 
          <div class="waitingHolder" style="top: 74.2px; width: 91px;">
            <img class="waitingImage" src="/img/loading.gif" title="Please Wait..." />
            <span class="waitingDescription">Loading...</span>
          </div>
        </div>
      </apex:facet>
    </apex:actionstatus>
  </apex:outputpanel>
 <apex:form id="frmExecuteContextController">
  <apex:pageBlock>  
   <apex:pageBlockButtons >
    <apex:commandButton value="Save" action="{!save}"/>
    <apex:commandButton value="Cancel" action="{!cancel}"/>
   </apex:pageBlockButtons>  
   <apex:pageBlockSection title="Select details" columns="2">
    <apex:pageBlockSectionItem >
     <apex:SelectList value="{!sObjectsVal}" size="1">
      <apex:selectOptions value="{!ObjectNames}"></apex:selectOptions>
      <apex:actionSupport rerender="Fields,frmExecuteContextController" event="onchange" status="actStatusId"/>
     </apex:SelectList> 
    </apex:pageBlockSectionItem>  
    <apex:pageBlockSectionItem >
     <apex:outputPanel id="Fields">
      <!--<apex:outputLabel value="Selected Object" for="ObjectVal"/>-->
      <apex:outputText id="ObjectVal" value="{!sObjectsVal}"/>
      <apex:SelectList value="{!sFieldsVal}" size="1">
       <apex:selectOptions value="{!FieldNames}"></apex:selectOptions>
       <apex:actionSupport rerender="frmExecuteContextController" event="onchange" status="actStatusId"/>
      </apex:SelectList>
     </apex:outputPanel>
    </apex:pageBlockSectionItem>    
    <apex:pageBlockSectionItem id="pbsItemVis">
     <apex:outputPanel id="FieldInputdisplay" rendered="{!bFieldrerendered}">
      <!--<apex:outputText value="visible"></apex:outputText>-->
      <!--<apex:dynamicComponent componentValue="{!SelectedField}"/>-->
      <apex:inputField value="{!inputObj[sFieldsVal]}"/>
     </apex:outputPanel>
    </apex:pageBlockSectionItem>  
   </apex:pageBlockSection>
  </apex:pageBlock>
 </apex:form>
</apex:page>

Controller
public class ExecuteContextController {
    public ExecuteContextController(ApexPages.StandardController controller) {
        //mfields = new Map<string,Schema.DescribeFieldResult>();
    }
    public SObject inputObj {get; set;}
    public String sObjectsVal {get;set;}
    public String sFieldsVal {get;set;}
    public Boolean test {get;set;}
    Schema.DescribeSObjectResult r;
    //public Map<string,Schema.DescribeFieldResult> mfields;
    
    public List<SelectOption> getObjectNames()
    {
        sFieldsVal = null;
        inputObj = null;
      List<Schema.SObjectType> gd = Schema.getGlobalDescribe().Values();     
      List<SelectOption> options = new List<SelectOption>();
      
      for(Schema.SObjectType f : gd)
      {   
        if(f.getDescribe().isCreateable())
        {
           //Schema.SObjectType sobjType = Schema.getGlobalDescribe().get(sObjectsVal);  
           //if(sobjType != null){
            options.add(new SelectOption(f.getDescribe().getName(),f.getDescribe().getLabel()));
           //} 
        }  
        
      }
      return options;
    }

    public List<SelectOption> getFieldNames()   
    {  
        sFieldsVal = null;
        r = null;
        List<SelectOption> fields = new List<SelectOption>(); 

        //code to set the input field dynamically seting the Sobject
        Schema.SObjectType targetType = Schema.GetGlobalDescribe().Get(sObjectsVal);

        if(targetType != null)
        {
           inputObj = targetType.NewSObject();
        }
        //End of Code
        Schema.SObjectType sobjType = Schema.getGlobalDescribe().get(sObjectsVal);  
        if (sobjType != null) {
            r = sobjType.getDescribe();
            //mfields.putAll(ExecuteContextHelper.getFieldMetaData(r,r.fields.getMap().keyset()));
            Map<String,Schema.SObjectField> M = r.fields.getMap();  
            for(String fieldName : M.keyset())  
            {  
                Schema.SObjectField field = M.get(fieldName);
                Schema.DescribeFieldResult fieldDesc = field.getDescribe();  
                if(fieldDesc.isUpdateable())
                {
                    //mfields.put(fieldName, fieldDesc);
                    //inputObj.put(fieldName, null);
                    fields.add(new SelectOption(fieldDesc.getName(),fieldDesc.getLabel())); 
                }
            }  
        }
        return fields;  
    }
    public Boolean getbFieldrerendered()
    {
        if(sObjectsVal == null || sFieldsVal == null)
        {
            test = false;
            return false;
        }
        else
        {
            test = true;
            return true;
        }
    }
    public  PageReference Save()
    {
        try
        {
            system.debug(inputObj);
            
            string sFieldinputVal = (String)inputObj.get(sFieldsVal);
            ExecuteContext__c oExecuteContext = new ExecuteContext__c(Object_Name__c=sObjectsVal,Field_Name__c=sFieldsVal,Field_Value__c=sFieldinputVal);
            insert oExecuteContext;
            PageReference opfNewPage = new ApexPages.StandardController(oExecuteContext).view();
            opfNewPage.setRedirect(true);
            return opfNewPage;

        }
        catch(Exception e)
        {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, e.getMessage()));
            PageReference pageRef = new PageReference(ApexPages.currentPage().getUrl());
            //pageRef.setRedirect(true);
            return pageRef;
        }
    }
}

 
Keyur  ModiKeyur Modi
Hi,
For second option you can use this code

 Map<String, Schema.SObjectField> fieldMap = schemaMap.get(SobjectApiName).getDescribe().fields.getMap();
where in place of SobjectApiName you need to pass the selected object, from this map you can get the list of fields related to particular selected object.
fieldMap.keyset() will be the list of field which are related to selected object.
you can put this value in selectOption list and display it as picklist value.

For Third option you need to use repeat (for list of fields)  and there you can define your input field concept.

For Fifth option you need to do some complex codding.
once you done with fifth option you can easily do sixth option.

Thanks,
Keyur Modi
Uzair Ahmadani 4Uzair Ahmadani 4
Thanks Keyur for showing intrest in my question. I am done till step 4 and need help in step 5 and actually am intrested in the complex coding part you reffered can you please provide some suggestion.

Thanks
 
Keyur  ModiKeyur Modi
Hi,
Please refer belove code , it will help you to fufill your requirement.

you can define wrapper class like this.

 public class Wrapperclass{
     public string text{get;set;} // value related to it.
     public string fieldName{get;set;}  //fieldName
}
and for the same wrapper class you need to define the wrapper list just like this
public list<Wrapperclass> lstwrapper{get;set;}
lstwrapper=new list<Wrapperclass>();
so this wrapper class will give you the mapping of fieldName and value opposite that field.

selectedObject dummyObj = new selectedObject(); // this one will be same as account acc = new account(); account replace with whatever object you will select,
now will use list of wrapper class will help to set the field and the value.

for(Wrapperclass w:lstwrapper){
dummyObj.w.fieldName=w.text;
}


and same wraper class you can use in the VF page to store mapped value jsut like this

<apex:dataTable value="{!lstwrapper}" var="eachField">
            <apex:column value="{!eachField.fieldName}" id="fieldname"/>
             <apex:column ><apex:inputText value="{!eachField.text}" >
             </apex:inputText>
            </apex:column>
        </apex:dataTable><br/>

please let me know if this will help,

Thanks,
Keyur Modi
Uzair Ahmadani 4Uzair Ahmadani 4
If you see in step 3 i have used <inputfield> which automatically renders the control as per data type of field, by using your approach i would loose this flexiblity which i really don't want to.
Keyur  ModiKeyur Modi
Hi,
"one more suggestion is you can try the same code and in place of inputText you can user inputField. i am not sure about this aproach but still you can try this. this will work as per your requirment number 3."

This will not work just now i checked... either you need to do this with javascript or jQuery.

Thanks,
Keyur Modi