1

I have a requirement to make a picklist which contains all the objects and based on the selected objects the corresponding fields will come in second picklist which is a multiSelect picklist. This should be in a pageBlockTable and wrapper class will be used so that I can have add Row functionality. A wrapper class will do the job but I am facing a problem.

I am following this approach:

Code

public class objectController
{
    public List<wrap> wrapList{get;set;}
    public objectController()
    {
        wrapList = new List<wrap>{ new wrap() };
    }

    public class wrap{
        public Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        public String selectedObject{get;set;}
        public list<selectOption> selectedFields{get;set;}
        Public wrap()
        {   
            selectedObject = 'account';
        }

        public List<SelectOption> getObjectNames() 
        {
            List<SelectOption> objNames = new List<SelectOption>();
            List<String> entities = new List<String>(schemaMap.keySet());
            entities.sort();
            for(String name : entities)
            {
                objNames.add(new SelectOption(name,name));
            }
            return objNames;
        }   


        public List<SelectOption> getObjectFields() 
        {
            Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
            Schema.SObjectType ObjectSchema = schemaMap.get(selectedObject);
            Map<String, Schema.SObjectField> fieldMap = ObjectSchema.getDescribe().fields.getMap();
            List<SelectOption> fieldNames = new List<SelectOption>();
            for (String fieldName: fieldMap.keySet()) 
            {  
                fieldNames.add(new SelectOption(fieldName,fieldName));
            }
            return fieldNames;
        }
    }
}

Markup

<apex:page controller="objectController">
    <apex:form >
       <apex:pageblock >
           <apex:pageBlockSection >
         -----{!wrapList}
             <apex:pageBlockTable var="row" value="{!wrapList}"> 
                 <apex:outputLabel value="Select Object  :  ">
                     <apex:selectList value="{!row.selectedObject}" size="1" >
                         <apex:selectOptions value="{!row.ObjectNames}">
                         </apex:selectOptions>
                     </apex:selectList>
                 </apex:outputLabel>
             </apex:pageBlockTable>
         </apex:pageBlockSection>

       </apex:pageblock> 
    </apex:form>
</apex:page>
  • 1
    So what is not working for you? – Tushar Sharma Mar 10 '16 at 12:32
  • actually I want a grid in which I can add as many rows as user wants...every row have a picklist to select an object then comes the MultiSelectPicklist in which a user can select fields and lastly Remove button to remove the row – Anzar Mar 10 '16 at 16:41
2
+50

This is a working example of what you are trying to do. I've included the add row and delete options as well and used only APEX and Visualforce to accomplish this. You could accomplish a faster page using javascript or another front-end framework, but I believe you were looking for a Visualforce tag solution

Visualforce Page

<apex:page controller="ObjectPageController">
  <apex:sectionHeader title="Object Field Selector" />
  <apex:form > 
    <apex:pageBlock>
        <apex:pageBlockButtons location="top">
            <apex:commandButton value="Add Row" action="{!addRow}" />
        </apex:pageBlockButtons>
      <apex:pageBlockTable value="{!displayedObjects}" var="obj" id="objectTable">
          <apex:column headerValue="Action">
            <apex:commandButton value="Delete" action="{!deleteRow}" rerender="objectTable">
               <apex:param name="indexToDelete" value="{!obj.identifier}" assignTo="{!idToDelete}"/> 
            </apex:commandButton>
         </apex:column>
          <apex:column headerValue="SObject">
            <apex:selectList value="{!obj.selectedObject}" size="1" multiselect="false">
              <apex:selectOptions value="{!obj.objects}"/>
              <apex:actionSupport event="onchange" rerender="fieldsList"/>
            </apex:selectList>
          </apex:column>
          <apex:column headerValue="Fields" id="fieldsList">
            <apex:selectList value="{!obj.selectedFields}" size="5" multiselect="true">
              <apex:selectOptions value="{!obj.objectFields}"/>
            </apex:selectList>
          </apex:column>
      </apex:pageBlockTable>
    </apex:pageBlock>
  </apex:form>
</apex:page>

APEX Controller

public class QuestionPageController {
    public List<ObjectWrapper> displayedObjects { get; set; }
    public static Integer idToDelete            { get; set; }
    private Integer rowIndentifier = 0;

    public QuestionPageController() {
        displayedObjects = new List<ObjectWrapper>();
        addRow();
    }

    public void addRow() {
        displayedObjects.add(new ObjectWrapper('account', rowIndentifier));
        rowIndentifier++;
    }

    public void deleteRow() {
        for (Integer i = 0; i < displayedObjects.size(); i++) {
            if (displayedObjects[i].identifier == idToDelete) {
                displayedObjects.remove(i);
                break;
            }
        }
    }

    public class ObjectWrapper {
        public List<SelectOption> fields       { get; set; }
        public String selectedObject           { get; set; }
        public List<String> selectedFields     { get; set; }
        public Integer identifier              { get; set; }
        private Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();

        public ObjectWrapper(String objectName, Integer iden) {
            selectedObject = objectName;
            identifier = iden;
        }

        public List<SelectOption> getObjects() {
            List<SelectOption> objectNames = new List<SelectOption>();
            List<String> entities = new List<String>(schemaMap.keySet());
            entities.sort();
            for(String name : entities) {
                objectNames.add(new SelectOption(name, name));
            }
            return objectNames;
        }

        /*
         * This is the method that is called to update the table data
         */
        public List<SelectOption> getObjectFields() {
            List<SelectOption> fields = new List<SelectOption>();

            if (String.isNotBlank(selectedObject)) {
                Schema.SObjectType ObjectSchema = schemaMap.get(selectedObject);
                Map<String, Schema.SObjectField> fieldMap = ObjectSchema.getDescribe().fields.getMap();
                for (String fieldName: fieldMap.keySet()) {  
                    fields.add(new SelectOption(fieldName,fieldName));
                }
            }

            return fields;            
        }
    }
}
  • yeah I was looking for this only...Thanks man..Its working....:) – Anzar Mar 20 '16 at 15:30
  • My pleasure @Anzar. If this answers your question, would you mind marking it as the accepted answer? – Dominic Baker Mar 20 '16 at 17:29
  • yeah sure...Moreover you will get bounty..;) – Anzar Mar 21 '16 at 7:15
1

actually I want a grid in which I can add as many rows as user wants...

If all you want is to create a table that can have new rows added in and/or removed you could try using a standard HTML table and modify that using jQuery/JavaScript - here's a good reference for adding rows and for deleting

Sample fiddle: https://jsfiddle.net/h13cqfgu/

0

I just copy pasted the code that is provided (There are some errors in formatting the question and the VF page code is half visible.) and i was not able to save it.

I will provide some recommendations..

  • Creating a page block table and iterating over wrapList is not required.
  • Defining all methods inside WRAP class. It is not required.
  • Before getting the schema details, please please check if the schema contains the object.

VF Page:

<apex:page controller="objectController" readOnly="true" >
    <apex:form > 
        <apex:pageBlock >
            <apex:pageBlockSection columns="3">

                <apex:pageBlockSectionItem >
                    <apex:outputlabel value="Select Object :"/> 
                    <apex:actionRegion >      
                        <apex:selectList value="{!selectedObject}" size="1">
                            <apex:selectOptions value="{!ObjectNames}"/>
                            <apex:actionSupport event="onchange" rerender="myFields"/>
                        </apex:selectList>
                    </apex:actionRegion>                         
                </apex:pageBlockSectionItem>

                <apex:pageBlockSectionItem >
                    <apex:outputlabel value="Field Names :"/>   
                    <apex:outputPanel id="myFields">   
                        <apex:actionRegion >  
                            <apex:selectList value="{!selectedField}" size="1">
                                <apex:selectOptions value="{!ObjectFields}"/>
                            </apex:selectList>
                        </apex:actionRegion>      
                    </apex:outputPanel>
                </apex:pageBlockSectionItem>

            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Controller:

public class objectController  
{  
    public Map <String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public String selectedObject {get; set;}
    public String selectedField {get; set;} 

    public objectController(){
        selectedObject = 'Account';
    }

    public List<SelectOption> getObjectNames() 
    {
        List<SelectOption> objNames = new List<SelectOption>();
        List<String> entities = new List<String>(schemaMap.keySet());
        entities.sort();
        for(String name : entities)
        {
            objNames.add(new SelectOption(name,name));
        }
        return objNames;

    }   

    public List<SelectOption> getObjectFields() 
    {
        Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        Schema.SObjectType ObjectSchema = schemaMap.get(selectedObject);
        Map<String, Schema.SObjectField> fieldMap = ObjectSchema.getDescribe().fields.getMap();
        List<SelectOption> fieldNames = new List<SelectOption>();
        for (String fieldName: fieldMap.keySet()) 
        {  
            fieldNames.add(new SelectOption(fieldName,fieldName));
            //fieldMap.get(fieldName).getDescribe().getLabel();//It provides to get the object fields label.
        }
        return fieldNames;
    }
}
  • I have made wrapper class to add the "add row" functionality...without wrapper class I wont be able to achieve it... – Anzar Mar 10 '16 at 17:16

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.