+ Start a Discussion
MukulMukul 

get the field names in a datatable from a dynamic query

Hi all,

 

I have a dynamic query which returns me some field names 

 

public List<leadStore> getStoredLeadVals() { String myId = getRuleSetId(); String limitClause = ApexPages.currentPage().getParameters().get('lt'); System.debug('LIMIT VAL: ' + limitClause); String query; query = 'select lead_id__c, score__c, map__c '+ ' from lead_store__c ' + ' where ruleSetId__c =\'' + myId + '\' order by lead_id__c limit ' +limitClause; System.debug('Query:' + query); List<lead_store__c> storedLeads = Database.Query(query); String AllIds = ''; String AllIds1 = ''; for (lead_store__c lsc : storedLeads) { AllIds += '\'' + lsc.lead_id__c + '\','; } AllIds1 = AllIds.substring(0, AllIds.length()-1); String allFldNames = ''; // TODO: Get me the fieldNames from the scoringRule List. // Store it in a Map so that we see only right values Map<String, String> ruleNamesMap = new Map<String, String>(); List<ScoringRule__c> scoringFlds = [select rulename__c, Id from ScoringRule__c where RuleSetId__c =: myId]; for(ScoringRule__c s : scoringFlds) { ruleNamesMap.put(s.ruleName__c, s.Id); } Set <String> s = ruleNamesMap.keyset(); for (string si : s) { allFldNames += si + ','; } String lstQry = 'select id, '+ allFldNames + ' name from lead where id in ('+ allIds1+ ')'; System.debug('Lead qry: ' + lstQry); List<Lead> ldSto = Database.Query(lstQry); for (Lead l : ldSto) { for (lead_store__c lsc : storedLeads) { if (lsc.lead_id__c == String.valueOf(l.Id)) { lSt.add(new leadStore(lsc,l)); } } } return lSt; }

 

I want to display the field names taht i get in this list on my visualforce page.

 

Any idea on how can i do that? Any help is much appreciated!!

 

 

Regards

Mukul

 

 

jkucerajkucera

Here's my controller that does just that.  getLSRFieldNames returns either Lead or CampaignMember fields based on what's selected in the "Type" field on my VF page

 

Controller:

 

public class LeadScoringRulesController { public Boolean campaignRendered { get; set;} private LeadScoringRule__c lsr; Map<String, Schema.SObjectField> rulesFields; public static String NONE_INDICATOR = '<Empty>'; public List<SObjectField> disputedFieldList {get; set;} private ApexPages.StandardController lsrController; public LeadScoringRulesController(ApexPages.StandardController controller) { lsrController = controller; lsr= (LeadScoringRule__c)controller.getRecord(); if(lsr.Type__c=='Campaign Member'){ campaignRendered =TRUE; } else { campaignRendered =FALSE; } } public List<selectOption> getLSRFieldNames(){ List<selectOption> options=new List<selectOption>(); Map<String, Schema.SObjectField> fieldMap=new Map<String, Schema.SObjectField>(); Boolean evaluateFields=false; if(lsr.Type__c=='Campaign Member'){ fieldMap=Schema.SObjectType.CampaignMember.fields.getMap(); evaluateFields=true; } else if(lsr.Type__c=='Lead'){ fieldMap=Schema.SObjectType.Lead.fields.getMap(); evaluateFields=true; } if (evaluateFields){ List<String> fieldNames=getFieldList(fieldMap); fieldNames.sort(); for (String fName:fieldNames){ options.add(new selectOption(fName,fName)); } } return options; } public List<String> getFieldList(Map<String, Schema.SObjectField> fieldMap) { //Make a comma-separated list of the fields List<String> fieldList =new List<String>(); for(String fieldName:fieldMap.keySet()) { Schema.DescribeFieldResult fieldDescribe = fieldMap.get(fieldName).getDescribe(); // if (fieldDescribe.getRelationshipName()!=null) { fieldList.add(fieldDescribe.getName()); // } } System.debug(fieldList); return fieldList; } //Determines whether the relationship pointed to by the input field is of the type specified. public Boolean isOfType(Schema.DescribeFieldResult fieldDescribe,Schema.Sobjecttype sObjectType) { List<sObjectType> references = fieldDescribe.getReferenceTo(); if (references.size()==1) { return (references[0] == sObjectType); } return false; } /** * Some objects have differently-named name fields. How annoying. We'll ignore Contact in here because that's a special case with 2 name fields (FirstName and LastName). */ public String getNameField(Schema.DescribeFieldResult fieldDescribe) { if (isOfType(fieldDescribe,Case.getSObjectType())) { return 'CaseNumber'; } return 'Name'; } }

 Relevant parts of the VF page:

 

<apex:page standardController="LeadScoringRule__c" extensions="LeadScoringRulesController"> <apex:form id="theForm"> <apex:pageBlock title="Lead Scoring Rule Detail" id="thePageBlock"> <apex:pageBlockSection > <apex:inputField value="{!LeadScoringRule__c.Type__c}" > <apex:actionSupport event="onchange" rerender="thePageBlock,FieldNames" /> </apex:inputField> <apex:pageBlockSection title="Rule Criteria" > <apex:panelGrid columns="3" cellspacing="10"> <apex:pageBlockSectionItem labelTitle="FieldName" ><b>Field Name</b></apex:pageBlockSectionItem> <apex:pageBlockSectionItem ><b>Operator</b></apex:pageBlockSectionItem> <apex:pageBlockSectionItem ><b>Value</b></apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:selectList id="FieldNames" value="{!LeadScoringRule__c.Field_Name__c}" size="1" title="Field Name List"> <apex:selectOptions value="{!LSRFieldNames}"></apex:selectOptions> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:inputField value="{!LeadScoringRule__c.Operator__c}" /> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:inputField value="{!LeadScoringRule__c.Value__c}" /> </apex:pageBlockSectionItem> </apex:panelgrid> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

 

 

 

 

MukulMukul

Hi there,

 

Thanks for the reply but this is not what i am looking for. I need to display the fields that i am getting from my List method on a visualforce page.

 

Any idea on how to do that?

 

Regards

Mukul 

jkucerajkucera
Ah-Sorry I mis-interpretted the question.

I haven't worked with lists on VF pages before - hopefully someone else can help.
harryZharryZ

Here goes my code, use lead as sample sobject

 

controller

public class popup { public List<String> labels{get;set;} String fields; public popup() { labels = new List<String>(); fields = ''; Map<String, Schema.SObjectField> fieldsMap = Lead.sObjectType.getDescribe().fields.getMap(); for(String field : fieldsMap.keySet()) { fields += field + ', '; labels.add(field); } fields = fields.substring(0, fields.length() - 2); } public List<List<object>> getRecords() { List<Lead> leads = Database.query('select ' + fields + ' from lead'); List<List<object>> results = new List<List<object>>(); for(Lead ld : leads) { List<object> result = new List<object>(); for(String lab : labels) { result.add(ld.get(lab)); } results.add(result); } return results; } }

vf page

 

<apex:page controller="popup"> <apex:form > <table> <tr> <apex:repeat value="{!labels}" var="lab"> <th> {!lab} </th> </apex:repeat> </tr> <apex:repeat value="{!records}" var="record"> <tr> <apex:repeat value="{!record}" var="field"> <td> {!field} </td> </apex:repeat> </tr> </apex:repeat> </table> </apex:form> </apex:page>

 

NaishadhNaishadh
Hope this will help!

Contact c = Database.query('select c.Id,c.name,c.email from contact c limit 1'); Map<String, Schema.SObjectField> M = c.getSObjectType().getDescribe().fields.getMap(); for(String s : M.keySet()) { try { System.debug(s + ' == ' + c.get(s)); } catch(System.Exception e) { //just ignore. field is not available in query. } }

 

AidenAiden

I love the example above.

 

However, if I try to do the same approach for a pageblock rather than plain HTML table, I get the following error;

 

 Error: <apex:column> may be a child of <apex:repeat> only for API version 20 or later

 

 

I'm on the Winter 11 release, so shouldn't this be API 20? 

 

 

<apex:page controller="popup">
    <apex:form >
                    <apex:pageBlock >
                    <apex:pageBlockTable value="{!records}" var="record" id="SearchTabResults">
                       <apex:repeat value="{!record}" var="field">
                                <apex:column value="{!field}" headervalue="test" />
                        </apex:repeat>
                    </apex:pageBlockTable>
                    </apex:pageBlock>    
    </apex:form>
</apex:page>

<apex:page controller="popup">    

<apex:form >                  

 <apex:pageBlock >                    

<apex:pageBlockTable value="{!records}" var="record" id="SearchTabResults">                      

<apex:repeat value="{!record}" var="field">                              

 <apex:column value="{!field}" headervalue="test" />                      

 </apex:repeat>                  

 </apex:pageBlockTable>                  

 </apex:pageBlock>        

</apex:form>

</apex:page>

 

NaishadhNaishadh

It's tricky. Check your page version. I guess, it still pointing to 19

AidenAiden

Thanks for the reply... but the funny thing is that the VisualForce pages list this as being API version 20 (API Version column). I wonder if this is a bug?

 

 










 

NaishadhNaishadh

and what is your controller popup class version?

AidenAiden

I'm using the one posted by 

 

Cory CowgillCory Cowgill

Sorry to bring up such an old thread, but no one posted a resolution to this and I have the same issue.

 

I am getting the same error:


Save error: <apex:column> may be a child of <apex:repeat> only for API version 20 or later

 

The metadata says this is API Version 20. Was this identified as a bug or not?

Cory CowgillCory Cowgill

After some more digging I found the answer:

 

"Unfortunately we couldn't get this to GA for Winter '11. We are making it avaialble selectively as a pilot feature, however. After the Winter '11 release, feel free to contact me and I'll see what I can do."

 

http://forums.sforce.com/t5/Visualforce-Development/Using-lt-apex-repeat-gt-to-create-dynamic-columns/m-p/190608

jkucerajkucera

I forgot to mention that Cory.  Sorry for the confusion.