function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
EMHDevEMHDev 

pageBlockSectionItem still not aligning outputLabel/ selectOption fields

I read on the board that the solution to aligning fields using outputLabel and selectOption is to put them inside a pageBlockSectionItem.  However, my code already is inside a pageBlockSectionItem, but is rendering left aligned and with the labels not bold.  I'm using an outputPanel as well, as I'm wondering if that is the problem?

 

Here is version 1 of the code:

 

<apex:page standardController="Call_Meeting_Report__c" extensions="ReportSearchController" showHeader="true" sidebar="true" action="{!loadDefaults}">
<apex:form >
<apex:pageBlock title="Call/Meeting Report" mode="edit" id="thePageBlock">
<apex:pageMessages />
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}"/>
<apex:commandButton value="Cancel" action="{!cancel}" immediate="true"/>
</apex:pageBlockButtons>
<apex:pageBlockSection columns="2">
<apex:inputField value="{!Call_Meeting_Report__c.Account__c}" >
<apex:actionSupport event="onChange" action="{!getDetails}" rerender="Choose" />
<apex:actionSupport event="onkeyup" action="{!getDetails}" rerender="Choose"/>
<apex:actionSupport event="onclick" action="{!getDetails}" rerender="Choose"/>
</apex:inputField>
<apex:inputField value="{!Call_Meeting_Report__c.Date__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Type__c}"/>
<apex:pageBlockSectionItem >
<apex:outputPanel id="Choose">
<apex:outputLabel value="Choose Opportunity "/>
<apex:selectList value="{!Call_Meeting_Report__c.Opportunity__c}" id="opps" size="1">
<apex:selectOptions value="{!Opps}"/>
</apex:selectList>
<p/>
<apex:outputLabel value="Choose Contact "/>
<apex:selectList value="{!Call_Meeting_Report__c.Primary_Contact__c}" id="conts" size="1">
<apex:selectOptions value="{!Conts}"/>
</apex:selectList>
<p/>
</apex:outputPanel>
</apex:pageBlockSectionItem>
<apex:inputField value="{!Call_Meeting_Report__c.Purpose__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Other_people_present__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Discussion__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Next_actions__c}"/>
<apex:pageBlockSectionItem />
</apex:pageBlockSection>
</apex:pageBlock>

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

(Sorry about the tabbing, looks fine in eclipse).

 

I tried putting the outputPanel outside of the pageBlockSectionItems in version 2:

 

 

<apex:page standardController="Call_Meeting_Report__c" extensions="ReportSearchController" showHeader="true" sidebar="true" action="{!loadDefaults}">
<apex:form >
<apex:pageBlock title="Call/Meeting Report" mode="edit" id="thePageBlock">
<apex:pageMessages />
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}"/>
<apex:commandButton value="Cancel" action="{!cancel}" immediate="true"/>
</apex:pageBlockButtons>
<apex:pageBlockSection columns="2">
<apex:inputField value="{!Call_Meeting_Report__c.Account__c}" >
<apex:actionSupport event="onChange" action="{!getDetails}" rerender="Choose" />
<apex:actionSupport event="onkeyup" action="{!getDetails}" rerender="Choose"/>
<apex:actionSupport event="onclick" action="{!getDetails}" rerender="Choose"/>
</apex:inputField>
<apex:outputPanel id="Choose">
<apex:pageBlockSectionItem>
<apex:outputLabel value="Opportunity "/>
<apex:selectList value="{!Call_Meeting_Report__c.Opportunity__c}" id="opps" size="1">
<apex:selectOptions value="{!Opps}"/>
</apex:selectList>
</apex:pageBlockSectionItem>
<p/>
<apex:pageBlockSectionItem>
<apex:outputLabel value="Contact "/>
<apex:selectList value="{!Call_Meeting_Report__c.Primary_Contact__c}" id="conts" size="1">
<apex:selectOptions value="{!Conts}"/>
</apex:selectList>
</apex:pageBlockSectionItem>
<p/>
</apex:outputPanel>
<apex:inputField value="{!Call_Meeting_Report__c.Date__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Type__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Purpose__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Other_people_present__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Discussion__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Next_actions__c}"/>
<apex:pageBlockSectionItem />
</apex:pageBlockSection>
</apex:pageBlock>

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

 but got the same result.  I must be missing something - can anyone advise?

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
WesNolte__cWesNolte__c

Hey

 

I think you want the selectOptions to refresh when <apex:inputField value="{!Call_Meeting_Report__c.Account__c}" > changes?  You can split your selection options up in this case:

 

 

<apex:pageBlockSectionItem id="opp">

<apex:outputLabel value="Choose Opportunity "/> <apex:selectList value="{!Call_Meeting_Report__c.Opportunity__c}" id="opps" size="1"> <apex:selectOptions value="{!Opps}"/> </apex:selectList> </apex:pageBlockSectionItem>

<apex:pageBlockSectionItem id="con"> 

 

<apex:outputLabel value="Choose Contact "/> <apex:selectList value="{!Call_Meeting_Report__c.Primary_Contact__c}" id="conts" size="1"> <apex:selectOptions value="{!Conts}"/> </apex:selectList> </apex:pageBlockSectionItem>

 

 And change your rerenders to:

 

rerender="opp, con" 

 

In addition to the rules Jill mentioned, if you want the styling to be applied the following element hierarchy needs to be strictly applied:

 

<apex:pageBlock>

 

<apex:pageBlockSection>

 

<apex:pageBlockSectionItem>

 <!--Stuff -->

</apex:pageBlockSectionItem> 

 

</apex:pageBlockSection> 

 

</apex:pageBlock> 

 

That is, these elements have these precise parent-child relationships in order to inherit the automatic styling. In your case the outputPanel is interfering with this tree model.

 

Cheers,

Wes 

 

Message Edited by weznolte on 02-01-2010 05:05 PM

All Answers

jwetzlerjwetzler

pageBlockSectionItem takes 0, 1 or 2 child components.  If there are two child components, it will put the first one in the "label" section and apply a style to it, and the second in the data section.  If you only supply one child component (e.g. outputPanel) it will make that component span both the label and data section.  This is all documented in the component reference, by the way.

 

So you can't use outputPanel and get the behavior you're looking for.

 

I'm not sure what kind of UI you're going for (you have two outputLabels and selectLists inside of one pageBlockSectionItem?  those are going to need to be separate if you want them to line up) but each pageBlockSectionItem should have a label component and an input component only, if you're intending for them to line up like the normal salesforce UI.

 

Why use the outputPanel at all?  You can specify a comma delimited list of ids to rerender, if you're only using it for rerender purposes.

EMHDevEMHDev
I'm using it because I'm using actionSupport and was under the impression I needed an outputPanel in order to get it to rerender.  In my case, I want it to refresh if an Account is changed or selected.  However, because I can't detect the search button refresh on Account, I'm not sure how useful this is. Currently it will refresh the list of Opportunities and Contacts if the Account is click in, once changed.
WesNolte__cWesNolte__c

Hey

 

I think you want the selectOptions to refresh when <apex:inputField value="{!Call_Meeting_Report__c.Account__c}" > changes?  You can split your selection options up in this case:

 

 

<apex:pageBlockSectionItem id="opp">

<apex:outputLabel value="Choose Opportunity "/> <apex:selectList value="{!Call_Meeting_Report__c.Opportunity__c}" id="opps" size="1"> <apex:selectOptions value="{!Opps}"/> </apex:selectList> </apex:pageBlockSectionItem>

<apex:pageBlockSectionItem id="con"> 

 

<apex:outputLabel value="Choose Contact "/> <apex:selectList value="{!Call_Meeting_Report__c.Primary_Contact__c}" id="conts" size="1"> <apex:selectOptions value="{!Conts}"/> </apex:selectList> </apex:pageBlockSectionItem>

 

 And change your rerenders to:

 

rerender="opp, con" 

 

In addition to the rules Jill mentioned, if you want the styling to be applied the following element hierarchy needs to be strictly applied:

 

<apex:pageBlock>

 

<apex:pageBlockSection>

 

<apex:pageBlockSectionItem>

 <!--Stuff -->

</apex:pageBlockSectionItem> 

 

</apex:pageBlockSection> 

 

</apex:pageBlock> 

 

That is, these elements have these precise parent-child relationships in order to inherit the automatic styling. In your case the outputPanel is interfering with this tree model.

 

Cheers,

Wes 

 

Message Edited by weznolte on 02-01-2010 05:05 PM
This was selected as the best answer
EMHDevEMHDev

Well, that aligns correctly but actionSupport doesn't rerender it.  Looking at the system log, the code is called but the picklists are not rerendered.  I believe I've read that outputPanel is needed for actionSupport.  Am I wrong?

jwetzlerjwetzler
outputPanel is often useful for rerendering because you can group entire sections of code that you want rerendered, but it's by no means necessary.  Can you post your new code?
EMHDevEMHDev

My head is whirling with this - I have read the docs, the boards and everything else, but until I get more experienced, I'm really grateful for the help.

 

Here is the latest code:

 

<apex:page standardController="Call_Meeting_Report__c" extensions="ReportSearchController" showHeader="true" sidebar="true" action="{!loadDefaults}"> <apex:form > <apex:pageBlock title="Call/Meeting Report" mode="edit" id="thePageBlock"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!save}"/> <apex:commandButton value="Cancel" action="{!cancel}" immediate="true"/> </apex:pageBlockButtons> <apex:pageBlockSection columns="2"> <apex:inputField value="{!Call_Meeting_Report__c.Account__c}" > <apex:actionSupport event="onChange" action="{!getDetails}" rerender="ChOpp, ChCon" /> <apex:actionSupport event="onkeyup" action="{!getDetails}" rerender="ChOpp, ChCon"/> <apex:actionSupport event="onclick" action="{!getDetails}" rerender="ChOpp, ChCon"/> </apex:inputField> <apex:pageBlockSectionItem id="ChOpp"> <apex:outputLabel value="Opportunity "/> <apex:selectList value="{!Call_Meeting_Report__c.Opportunity__c}" id="opps" size="1"> <apex:selectOptions value="{!Opps}"/> </apex:selectList> </apex:pageBlockSectionItem> <p/> <apex:pageBlockSectionItem id="ChCon"> <apex:outputLabel value="Contact "/> <apex:selectList value="{!Call_Meeting_Report__c.Primary_Contact__c}" id="conts" size="1"> <apex:selectOptions value="{!Conts}"/> </apex:selectList> </apex:pageBlockSectionItem> <p/> <apex:inputField value="{!Call_Meeting_Report__c.Date__c}"/> <apex:inputField value="{!Call_Meeting_Report__c.Type__c}"/> <apex:inputField value="{!Call_Meeting_Report__c.Purpose__c}"/> <apex:inputField value="{!Call_Meeting_Report__c.Other_people_present__c}"/> <apex:inputField value="{!Call_Meeting_Report__c.Discussion__c}"/> <apex:inputField value="{!Call_Meeting_Report__c.Next_actions__c}"/> <apex:pageBlockSectionItem /> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 I'm busy trying to extend the controller so that the page will work whether invoked from an account, opportunity or contact, so it is a work in progress, but the part relating to this discussion works.

 

 

public with sharing class ReportSearchController { //add an instance variable for the standard controller private ApexPages.StandardController controller {get; set;} // the actual call/meeting report private Call_Meeting_Report__c cmr {get; set;} private Id a, newa, OppThere, ContThere; public List <selectOption> Opps {get; set;} public List <selectOption> Conts {get; set;} // Initialise the controller public ReportSearchController(ApexPages.StandardController controller) { //initialise the standard controller this.controller = controller; cmr = (Call_Meeting_Report__c)controller.getRecord(); //this.a = (Account)controller.getRecord(); } // the results from the search public PageReference getDetails() { List <selectOption> NewOpps = new List<selectOption>(); List <selectOption> NewConts = new List<selectOption>(); newa = cmr.Account__c; system.debug('### Old Account is '+a+' New Account is '+newa); if ((newa != a)&&(newa != null)){ // Don't want to make SOQL call if we don't need to // use some dynamic soql to find the related opportunities by name try { List <Opportunity> opplist = [Select Id, Name from Opportunity Where AccountId = :newa Order By Name]; for (Opportunity o:opplist) { NewOpps.add(new selectOption(o.Id, o.Name)); system.debug('### NewOpps option added -'+o.Name); } List <Contact> contlist = [Select Id, Name from Contact Where AccountId = :newa Order By Name]; for (Contact c:contlist) { NewConts.add(new selectOption(c.Id, c.Name)); system.debug('### NewConts option added -'+c.Name); } } catch (Exception e) { System.debug('### error '+e); ApexPages.addMessages(e); } // Opps = NewOpps; Opps.clear(); Opps.addAll(NewOpps); Conts.clear(); Conts.addAll(NewConts); } else if (newa == null) { Opps.clear(); system.debug('### Emptied Opps & Conts lists'); Conts.clear(); } return null; } public void loadDefaults() { Opps = new List<selectOption>(); Conts = new List<selectOption>(); String Opp1, Cont1; a = cmr.Account__c; OppThere = cmr.Opportunity__c; ContThere = cmr.Primary_Contact__c; system.debug('### Account is '+a+' Opp is '+OppThere+' Contact is '+ContThere); // use some dynamic soql to find the related opportunities / contacts by account name try { if (OppThere == null){ List <Opportunity> opplist = [Select o.Id, o.Name from Opportunity o Where AccountId = :a Order By o.Name]; for (Opportunity o:opplist) { Opps.add(new selectOption(o.Id, o.Name)); system.debug('### Opp option added -'+o.Name); } } else { List <Call_Meeting_Report__c> cmrlist = [Select c.Opportunity__r.Name, c.Opportunity__c From Call_Meeting_Report__c c where c.Id =:cmr.Id]; //*** Opp1 = cmrlist[0]. system.debug('### Opp already there, adding '+cmr.Opportunity__r.Name); Opps.add(new selectOption(OppThere, cmr.Opportunity__r.Name)); } if (ContThere == null) { List <Contact> contlist = [Select Id, Name from Contact Where AccountId = :a Order By Name]; for (Contact c:contlist) { Conts.add(new selectOption(c.Id, c.Name)); system.debug('### Cont option added -'+c.Name); } } else { Conts.add(new selectOption(contThere, cmr.Primary_Contact__r.Name)); system.debug('### Contact already there, added '+ContThere); } } catch (Exception e) { System.debug('### error '+e); ApexPages.addMessages(e); } } }

 

 

 

 

 

jwetzlerjwetzler
rerender opps,conts instead.
EMHDevEMHDev

That's it.  Thank you so much.

 

Erica

SteveBowerSteveBower

Some random thoughts:

 

1. Do things work if you throw an <apex:actionRegion>   tag around the input field you're changing?  (I don't think they will, but you'd be sending back less).

 

2. If the goal of the getDetails call is to change the values that are in a select list, then why are you calling it for keyUp and onClick events.  After all, with size=1, the values in the Select list aren't relevent until the user navigates away from the input field and goes to try to select something.  So, an onChange event should be sufficient.

 

3. newa.Account__c is a lookup field to an Account.  So, the inputField that you're displaying is allowing you to enter a Account name letter by letter and you're calling your getDetails with each keystroke.  However, Let's assume I have an Account called "IBM".  I type in the "I", your getDetails is called, however since there is no Account called "I", the controller doesn't have an Id for you.  I presume it has a null, but I'm not really sure what value you'd get in there, certainly not a single valid Account Id for you to use in a query.  Either way, I don't think it's a useful call to make.   Or, to put it differently, perhaps not by using a Lookup field.  If you just use a straight Text field, I'd think that makes more sense to me if you must try to do lookahead.  (see #2)

 

:-)  Best, Steve.

dev401hasdev401has

Hi All

 

As mentioned by Jill earlier and also by Wez with an example that it is not necessary to have outputPanel to rerender and you can directly do it using Id of pageBlockSectionItem but when it comes to rendering a component which is also rerendered (example: to make components appear and hide using the 'rendered' attribute on base of a selected value in picklist)

 

You cannot simply re-render the component, as it was never rendered and so does not exist in the current context of the page. Either refresh the entire pageblocksection or use an ouput panel around the pageblocksectionItem to be shown and hidden, and by using the id of the output panel in the 'reRender' attribute of the action. (hope I am clear with my words)

I have a situation like that and I have used OutputPanel but that is not giving the styling as that of Salesforce.

 

can anyone provide solution without using OutputPanel or keep the styling same as Salesforce even using OutputPanel?