0

I was looking for an example of conditional rendering of fields: like the one here How to hide/show the fields based on Picklist value

My question is, how would you do this with the standard FieldSet and a Picklist value. Here is the code for getting the fields from the controller and then how they are iterated on the loop of the HTML to get the page to fields to render.

Controller method:

  public HB_BS_ChurchCardCont() {
        this.churchRecord= getChurch(); 
    }
public List<Schema.FieldSetMember> getFields(){
        return SObjectType.Contact_Details__c.FieldSets.HB_BS_ChurchCardFields.getFields();
        // return     Schema.SObjectType.Account.fieldSets.getMap().get(fieldNames).getFields();
    }
public  Contact_Details__c  getChurch(){
        String query = 'SELECT ';
        String contactId = [SELECT Id, ContactId FROM User WHERE ID =: UserInfo.getUserId()].ContactId;  
        Id recTypeId = getContDetailsRecType(); 
        for(Schema.FieldSetMember f : this.getFields()){
            query += f.getFieldPath() + ', '; 
        }
        query += 'Id FROM Contact_Details__c WHERE Contact__c =: contactId AND RecordTypeId =: recTypeId LIMIT 1'; 
        if(Database.query(query) == null || Database.query(query).size() == 0){
            churchRecord = new Contact_Details__c(
                RecordTypeId = recTypeId,
                Contact__c = contactId 
                );
         } else {
             churchRecord = Database.query(query); 
         }      
         return churchRecord; 
    }


HTML

 <apex:outputPanel id="editfields"  html-class="slds-hide">
            <apex:repeat value="{!fields}" var="f" >
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="text-input-id-53">{!f.label}</label>
                    <div class="slds-form-element__control slds-input-has-icon slds-input-has-icon_right">
                        <apex:inputField styleClass="slds-input" 
                            value="{!churchRecord[f.fieldPath]}" 
                            required="{!f.required}"
                        />
                    </div>
                </div>
            
            </apex:repeat>
3
  • 1
    Just curious, why are you still using Visualforce in 2022?
    – Adrian Larson
    Jan 4, 2022 at 18:20
  • Because the business doesn't want to go LWC.
    – thinker
    Jan 4, 2022 at 18:22
  • 1
    I'd push back on that. LWC is simpler honestly and investing in it makes way more sense.
    – Adrian Larson
    Jan 4, 2022 at 18:49

1 Answer 1

1

Speaking from experience here, I'd highly suggest filtering the fields to display in your controller rather than depending on the rendered attribute (especially inside of a repeating element like <apex:repeat>, <apex:pageBlockTable>, or <apex:dataTable>. Page performance becomes excessively poor with a sufficient number of items to repeat over.

You'll need a button press or something like <apex:actionSupport> to kick off the re-render anyways, so that should mean you'll have access to the selected picklist value in your controller/extension.

With that in mind, you could change your getFields() method to only return specific fields from the fieldset (or possibly choose one of several fieldsets).

Something like

private static Map<String, Set<String>> picklistValToReturnedFields = new Map<String, Set<String>>{
    'value1' => new Set<String>{'field2', 'field3', 'field5'},
    'value2 => new Set<String>{'field1', 'field2', 'field3'}
};

public List<Schema.FieldSetMember> getFields(){
    List<Schema.FieldSetMember> results = new List<Schema.FieldSetMember>();

    for(Schema.FieldSetMember> fsm :SObjectType.Contact_Details__c.FieldSets.HB_BS_ChurchCardFields.getFields()){
        if(MyExtension.picklistValToReturnedFields.get(myPicklistVal).contains(fsm.getFieldPath())){
            results.add(fsm);
        }
    }

    return results;
}

Looking at that example, a single fieldset isn't really a great option for choosing which fields to render based on other input. You'd need to either hard-code the fields to render (which makes the fieldset practically useless) or store the information in a Custom Metadata Type. We just don't have the ability to add the information we'd need into the fieldset itself to support what you're trying to do without taking one of the measures mentioned above.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .