0

Is that possible to bind the sObject field in the visualforce page?

I'm getting the below error but not sure its helping me but I'm sure it has to do with mySobject that I have in the inputField

I have complete code below.

Here are my Page: error:

Error: java.lang.NullPointerException
Error Error: null

<apex:inputField value="{!mySobject.field_1__c}"/>
<apex:inputField value="{!mySobject.field_2__c}"/>

my ApexClass:

public class dynamicApexController 
{
    public SObject mySobject {get; set;}
    public Id sObjectId {get;set;}
    public String objectName {get;set;} 

    public dynamicApexController()
    { 
        sObjectId = ApexPages.currentPage().getParameters().get('id');  

        //building object and fields:

        objectName = sObjectId.getSObjectType().getDescribe().getName(); 
        Set<String> setFields = new Set<String>();        
        DescribeSObjectResult objSchema = sObjectId.getSObjectType().getDescribe();
        Map<String, Schema.SObjectField> fieldMap = objSchema.fields.getMap();
        for (String fieldName : fieldMap.keySet())
        {
            SObjectField sfield = fieldMap.get(fieldName);
            schema.describefieldresult dfield = sfield.getDescribe();
            String field = dfield.getName(); 
            setFields.add(field);
        }
        String soqlQuery ='SELECT ';
        for(String sReqField : setFields) {            
            soqlQuery +=  sReqField + ','; 
        }
        soqlQuery = soqlQuery.removeEnd(',');
        soqlQuery += '  FROM ' + objectName + ' WHERE Id =  \''+sObjectId+'\''; 

        mySobject = Database.query(soqlQuery);

    }
}
  • Why are you not simply using the standard controller? Also you have introduced an injection vulnerability the way you merge sObjectId into your query. – Adrian Larson May 3 '17 at 23:04
  • I thought I wrote it but I guess not, the reason I'm not using is because I have same fields in more than few objects so when the user click on the record based on which page the user is I'm redirecting to this VFP and showing those fields and I'm trying to avoid hard-coding object name in the code and hope this make sense – Nick Kahn May 3 '17 at 23:07
5

As for the title of your question, yes it is possible to reference fields from a dynamic object. Use square brackets ([]):

<apex:inputField value="{!record['Some_Field__c']}" />

Not sure if that will solve your NullPointerException...

Note also that you have introduced an injection vulnerability by trusting the id parameter. Never trust user input. You must always call String.escapeSingleQuotes when merging in the input as a string, or simply reference the bind variable:

'... WHERE Id = \'' + String.escapeSingleQuotes(sObjectId) + '\'';
// OR
'... WHERE Id = :sObjectId'
0

I tried to modify your code using this blog post. And it is working for me. I added comments for most of the lines for easy understanding. I have also taken Adrian Larson's suggestion regarding SOQL injection. Hope this helps.

VF Page

<apex:page controller="dynamicApexController" >
    <apex:form>
        <apex:inputField value="{!mySobject['Test_Number__c']}"/>
        <apex:inputField value="{!mySobject['Country__c']}"/>  
        <apex:inputField value="{!mySobject['Rich_Text__c']}"/>  
    </apex:form>
</apex:page>

Controller

public class dynamicApexController {
    //Hold record of object
    public SObject mySobject {get; set;}
    //Hold the Id of the record
    public String sObjectId {get;set;}
    //Hold object name
    public String objectName {get;set;} 
    public dynamicApexController(){
        sObjectId = 'a0Ii000000pf0w2'; // I have hardcoded it here, you can make it dynamic by fetching from URL parameter as per your requirement                   
        //Hold all objects in schema 
        Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
        //Hold the query string
        String soqlQuery ='';         
        //Hold the object api name
        Set<String> keyPrefixSet = gd.keySet();
        //Finding the Object by keyPrefix
        for(String sObj : keyPrefixSet){
            //hold particualr description of a object
            Schema.DescribeSObjectResult r =  gd.get(sObj).getDescribe();
            //Hold the keyPrifix of present Objet. This is three digit key
            String tempPrefix = r.getKeyPrefix();
            //Compare the keyPrefix of present obj and
            // the record's object which is in argument if match then store
            if(sObjectId.subString(0,3) == tempPrefix){
                Map<String, Schema.SObjectField> FsMap = r.fields.getMap();
                //Get the Object name
                objectName = r.getName();
                //Create the dynamic Query
                soqlQuery ='SELECT ';
                for(String sReqField : FsMap.keySet()) {
                    soqlQuery +=  sReqField + ','; 
                }
                soqlQuery = soqlQuery.removeEnd(',');
                //You must always call String.escapeSingleQuotes when merging in the input as a string
                soqlQuery += '  FROM ' + objectName + ' WHERE Id =  \''+ String.escapeSingleQuotes(sObjectId) +'\''; 
                break;
            }
        }
        try{ 
            System.debug('@@'+soqlQuery);
            //making the instance of that record by fetching data by dynamic query
            mySobject= Database.query(soqlQuery);
        }catch(Exception e){
            System.debug('@@'+e.getMessage());
        }           
    }
}
  • Where you getting the value of Test_Number__c'? – Nick Kahn May 4 '17 at 11:37
  • If you check the SOQL Query it takes all the fields, so in VF page any field will work. If you want, you can also restrict the fields in the loop. – Saroj Bera May 4 '17 at 12:10
  • I'm not sure if you understand what I'm trying to do, I just reply to Adrian please read that comment – Nick Kahn May 4 '17 at 12:35

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.