0

Page :

<apex:page id="ContactDetails" extensions="ContactsController" standardController="Case">

    <script>

        function showFieldsOnClickAction() {
            showFieldsAction();
        }

    </script>

    <apex:form>
        <button name="showFields" onclick="showFieldsOnClickAction(); return false;">ShowFields</button>
        <apex:actionFunction name="showFieldsAction" action="{!fecthListAPINamesFromCase}" reRender="showFields"/>
        <apex:outputPanel id="showFields">
        <apex:pageBlock title="Case Fields" mode="edit">
            <apex:pageBlockSection title="Case Section" columns="2">
                <apex:repeat value="{!lstCaseAPIName}" var="eachApiName">
                <apex:pageBlockSectionItem>
                        <apex:inputField value="{!Case[eachApiName]}"/>
                </apex:pageBlockSectionItem>
                </apex:repeat>
            </apex:pageBlockSection>
        </apex:pageBlock>
        </apex:outputPanel>
    </apex:form>
</apex:page>

and controller is as :

public with sharing class ContactsController {

    public List<String> lstCaseAPIName {get ; set;}


    public ContactsController(ApexPages.StandardController controller){

    }

    public void fecthListAPINamesFromCase (){
        String sObjectName = 'Case';
        if(sObjectName != null && sObjectName != '' ) {
            lstCaseAPIName = new List<String>();
            Schema.SObjectType gd = Schema.getGlobalDescribe().get(sObjectName);
            Schema.DescribeSobjectResult a11 = gd.getDescribe();
            Map<String, Schema.SObjectField> M = a11.fields.getMap();
            for (Schema.SObjectField s1 : m.values()) {
                Schema.DescribeFieldResult f = M.get(s1.getDescribe().getName()).getDescribe();
                if(f.getName() == 'Reason' || f.getName() == 'Description' || f.getName() == 'ContactId' || f.getName() == 'Status') {
                    lstCaseAPIName.add(f.getName());
                }
            }
        }
    }
}

We have a custom requirement where we need to show text fields in full tr and rest of the fields in as described in columns in pageBlockSection.

But if I put columns as 2 in pageBlockSection it starts displaying as <td>

actual :

enter image description here

expected :

enter image description here

This would be possible I think if pageblockSectionItem also has column in it so that it can decide it should be in same tr or another tr. Is this possible?

2

Basically, no, it's not going to work this way. You'd have to use multiple apex:pageBlockSection elements to determine if you want to show 1 or 2 columns, then display the fields within. The markup looks like this:

<apex:repeat value="{!sections}" var="section">
  <apex:pageBlockSection columns="{!section.columns}">
    <apex:repeat value="{!section.fields}" var="field">
      <apex:pageBlockSectionItem>
        <apex:inputField value="{!Case[field]}" />
      </apex:pageBlockSectionItem>
    </apex:repeat>
  </apex:pageBlockSection>
</apex:repeat>

The section class looks like this:

public class Section {
  public Integer columns { get; set; }
  public String[] fields { get; set; }
}

I leave it as an exercise to the reader to modify the Apex code to use this new wrapper design.

  • the issue in this one is it creates a different div for each field and the each div has a table element inside it, so the expected scenario cannot be achieved. – Nagendra Singh Apr 20 at 3:45
  • @NagendraSingh Yes, that's the only way you can. Page Block Sections do not simultaneously support one and two column layouts. Otherwise, you're just going to have to write your own HTML instead. – sfdcfox Apr 20 at 5:37
0
let seen = [];
$(this).find("tr").each(function () {
    $(this).find('td').each(function () {
        let objClassSelector = $(this).children().attr('class');
        if (objClassSelector) {
            if (seen.includes(objClassSelector)) {
                $(this).children().remove();
                $(this).prev('th').remove();
                $(this).siblings().each(function () {
                    if ($(this).hasClass('labelCol')) {
                        $(this).attr('colspan', '1');
                    } else {
                        $(this).removeAttr('style');
                        $(this).attr('style', 'width: 75%;');
                        $(this).attr('colspan', '4');
                    }
                });
                $(this).remove();
            } else {
                seen.push(objClassSelector);
            }
        }
    });
});

Final Answer

<!--
 - Created by Nagendra on 13-04-2019.
 -->

<apex:page id="ContactDetails" extensions="ContactsController" standardController="Case">
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>

    <style>
        textarea {
            width: inherit;
        }

        select {
            width: inherit;
        }
    </style>
    <script>

        function showFieldsOnClickAction() {
            showFieldsAction();
        }

        function fireOnComplete() {
            let seen = [];
            $('.case-section').each(function () {
                $(this).find("tr").each(function () {
                    $(this).find('td').each(function () {
                        let objClassSelector = $(this).children().attr('class');
                        if (objClassSelector) {
                            if (seen.includes(objClassSelector)) {
                                $(this).children().remove();
                                $(this).prev('th').remove();
                                $(this).siblings().each(function () {
                                    if ($(this).hasClass('labelCol')) {
                                        $(this).attr('colspan', '1');
                                    } else {
                                        $(this).removeAttr('style');
                                        $(this).attr('style', 'width: 75%;');
                                        $(this).attr('colspan', '4');
                                    }
                                });
                                $(this).remove();
                            } else {
                                seen.push(objClassSelector);
                            }
                        }
                    });
                });
            });

        }
    </script>

    <apex:form>
        <button name="showFields" onclick="showFieldsOnClickAction(); return false;">ShowFields</button>
        <apex:actionFunction name="showFieldsAction" action="{!fecthListAPINamesFromCase}" reRender="showFields" onComplete="fireOnComplete()"/>
        <apex:outputPanel id="showFields">
            <div class="case-section">
            <apex:pageBlock title="Case Fields" mode="edit">
                <apex:pageBlockSection title="Case Section" columns="2">
                    <apex:repeat value="{!finalLstCaseAPIName}" var="eachApiName">
                            <apex:inputField value="{!Case[eachApiName]}" styleClass="{!eachApiName}"/>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:pageBlock>
            </div>
        </apex:outputPanel>

    </apex:form>
</apex:page>

Controller :

public with sharing class ContactsController {

    public List<String> lstCaseAPIName;
    public List<String> finalLstCaseAPIName {get ; set;}


    public ContactsController(ApexPages.StandardController controller){

    }

    public void fecthListAPINamesFromCase (){
        String sObjectName = 'Case';
        if(sObjectName != null && sObjectName != '' ) {
            lstCaseAPIName = new List<String>();
            Schema.SObjectType gd = Schema.getGlobalDescribe().get(sObjectName);
            Schema.DescribeSobjectResult a11 = gd.getDescribe();
            Map<String, Schema.SObjectField> M = a11.fields.getMap();
            for (Schema.SObjectField s1 : m.values()) {
                Schema.DescribeFieldResult f = M.get(s1.getDescribe().getName()).getDescribe();
                if(f.getName() == 'Reason' || f.getName() == 'Description' || f.getName() == 'ContactId' || f.getName() == 'Status' || f.getName() == 'Origin') {
                    lstCaseAPIName.add(f.getName());
                }
            }
            finalLstCaseAPIName = new List<String>();
            for (String apiName : lstCaseAPIName){
                if(apiName == 'Description'){
                    finalLstCaseAPIName.add('Description');
                    finalLstCaseAPIName.add('Description');
                } else {
                    finalLstCaseAPIName.add(apiName);
                }
            }
        }
    }
}

I found a way to do it, If we want to show any field with full colspan, the I created duplicate entries in list for that particular field, Then added the api name to the class attribute of the fields. Then finally removing the td and tr created for the duplicate entries and then expanding the width and colspan of the siblings.

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.