2

I am looking for a way where I can use to have two individual, independent columns for fields of a custom object. I am aware has a column attribute, but there is no control over field placement.

I have tried to use various combinations of inline/inline-block on the divs/form/pageBlockSections/etc...

Here is the current code I have, although I have gone through many iterations to try to get Column 1 next to Column 2 in an inline fashion. Currently the first fieldset has lets say 10 fields, and the second fieldset has another 5. I need to conditionally show the second fieldset next to the first if condition X is met:

<apex:form>
            <div style="display: inline;">
                <apex:pageBlock>
                    <apex:pageBlockSection columns="1"> 
                        <apex:inputField value="{!Product__c.Opportunity__c}" />
                        <apex:repeat value="{!$ObjectType.Product__c.FieldSets.FieldSet1}" var="f">
                             <apex:pageBlockSectionItem>
                                <apex:outputLabel style="display: inline;" value="{!f.label}" />
                                <apex:inputField value="{!Product__c[f]}"/>
                            </apex:pageBlockSectionItem>
                        </apex:repeat>
                    </apex:pageBlockSection>
                </apex:pageBlock>
            </div>

            <div style="display: inline;">
                <apex:pageBlock>
                    <apex:pageBlockSection columns="1">  
                        <apex:repeat value="{!$ObjectType.Product__c.FieldSets.FieldSet2}" var="f">
                             <apex:pageBlockSectionItem>
                                <apex:outputLabel style="display: inline;" value="{!f.label}" />
                                <apex:inputField value="{!Product__c[f]}"/>
                            </apex:pageBlockSectionItem>
                        </apex:repeat>
                    </apex:pageBlockSection>
                </apex:pageBlock>
            </div>

</apex:form>

I would like my end result to be some semblance of this but still being able to control what is in column 1 and column 2 exclusively:

enter image description here

3

Unfortunately you can't specify columns that way with apex:pageblocksection, it's always left-to-right.

You could just use one field set and just training people to put them into the field set in the desired left to right ordering.

If that's not practical with apex you can take to field sets and combine them into a single array with the left-to-right ordering required by apex:pageblocksection. I've put together an example which should accomplish what you want, although there is likely more you'd need to do to have this production ready (i.e. set the required attribute based on the field requirement and it's whether it's marked as required in the field s).

Controller

public with sharing class SFSX_237209 {

    public String[] ltrFieldNames { get; set; }

    public SFSX_237209(ApexPages.StandardController controller) {
        ltrFieldNames = new String[0];
        String[] fieldNames = new String[0];
        Schema.FieldSetMember[] col1 = SObjectType.Product2.FieldSets.FieldSet1.getFields();
        Schema.FieldSetMember[] col2 = SObjectType.Product2.FieldSets.FieldSet2.getFields();
        for (Integer i = 0; i < Math.max(col1.size(), col2.size()); i++) {
            if (col1.size() > i) {
                ltrFieldNames.add(col1[i].getFieldPath());
                if (!fieldNames.contains(col1[i].getFieldPath())) {
                    fieldNames.add(col1[i].getFieldPath());
                }
            } else {
                ltrFieldNames.add('SKIP');
            }
            if (col2.size() > i) {
                ltrFieldNames.add(col2[i].getFieldPath());
                if (!fieldNames.contains(col2[i].getFieldPath())) {
                    fieldNames.add(col2[i].getFieldPath());
                }
            } else {
                ltrFieldNames.add('SKIP');
            }
        }
        controller.addFields(fieldNames);
    }
}

Visualforce Page

<apex:page standardController="Product2" extensions="SFSX_237209">

    <apex:form>
        <apex:pageBlock>
            <apex:pageBlockSection columns="2">
                <apex:repeat value="{!ltrFieldNames}" var="fieldName">
                    <apex:inputField value="{!Product2[fieldName]}" rendered="{!fieldName <> 'SKIP'}"/>
                    <!-- implement blank space with empty string -->
                    <apex:outputText value=" " rendered="{!fieldName = 'SKIP'}"/>
                </apex:repeat>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>

</apex:page>
  • 1
    Thanks so much Ralph, this was of great help! The initial reason for 2 fieldsets is because 2 profiles needed visibility into their own group of fields, so the wish was to render the 2nd column visible when Profile X viewed it and not render when Profile Y was viewing it. As much as I wanted to stray from using Apex for the sake of ease of use, your way is nice and succinct :) – Stas Christiansen Oct 25 '18 at 20:37

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.