Custom selectItems - jsf

i want to customize selectItems
to display an image conditionally beside each checkbox
so first i tried to display the image for all checkboxes
but it gets displayed only once, here's what i tried:
<h:selectManyCheckbox value="#{myBean.checkboxesArry}" layout="pageDirection">
<f:selectItems value="#{myBean.mapOfCheckBoxes}" var="entry">
<label>
<ice:graphicImage url="/resources/images/myImage.bmp"/>
<b>#{entry.value}</b>
</label>
</f:selectItems>
</h:selectManyCheckbox>
please advise how to accomplish that ?

You cannot nest UI compnents in <f:selectItems> that way. I however see that you're using ICEfaces, you should then be able to use <ice:selectManyCheckbox layout="spread"> in combination with <ice:checkbox> instead.
<ice:selectManyCheckbox id="foo" value="#{myBean.checkboxesArry}" layout="spread">
<f:selectItems value="#{myBean.mapOfCheckBoxes}" />
</ice:selectManyCheckbox>
<c:forEach items="#{myBean.mapOfCheckBoxes}" var="entry" varStatus="loop">
<ice:checkbox for="foo" index="#{loop.index}" />
<ice:graphicImage url="/resources/images/myImage.bmp" />
<b>#{entry.value}</b>
</c:forEach>
(untested as I don't use ICEfaces, but the above construct works for Tomahawk, from which ICEfaces has basically copied the implementation; you can also use <ui:repeat> but it only supports Map since JSF 2.1)
See also:
Radio buttons in different parts of the page

Related

How to collapse or expand all RichFaces collapsiblePanel elements on the page?

I'm using RichFaces with JSF to develop a simple app. One page of this app contains several collapsiblePanel elements. Some of the collapsiblePanel elements are nested, but never more than a second layer.
I would like to provide links or buttons on the page to expand all and collapse all collapsiblePanel elements on the page. How can I do that?
The elements currently use the switchType="client" attribute to let the client handle the expanding and collapsing. I suspect that using a type of ajax instead may help, but I'm not sure nor do I know how I would take advantage of it.
Update: My question may be easier to understand if I include an example of what I'm trying to do:
<h:form>
<a4j:commandButton actionListener="#{bean.setDefaultExpanded(true)}"
render="reportPanel" value="Expand all" />
<a4j:commandButton actionListener="#{bean.setDefaultExpanded(false)}"
render="reportPanel" value="Collapse all" />
<h:panelGrid id="reportPanel">
<ui:repeat var="account" value="#{bean.results.entrySet().toArray()}">
<rich:collapsiblePanel expanded="#{bean.defaultExpanded}">
<ui:repeat var="chargeGroup" value="#{account.value.entrySet().toArray()}">
<rich:collapsiblePanel expanded="#{bean.defaultExpanded}">
<h:outputText value="content: #{chargeGroup.value}" />
</rich:collapsiblePanel>
</ui:repeat>
</rich:collapsiblePanel>
</ui:repeat>
</h:panelGrid>
</h:form>
The <rich:collapsiblePanel> has the expanded attribute, you can bind it to bean property and control the expansion from there. Something like this
<rich:collapsiblePanel id="panel1" expanded="#{bean.expanded}" …>
<a4j:commandButton actionListener="#{bean.togglePanels()}"
… render="panel1, panel2, …"/>
The switchType controls where the content is pulled from, not how you expand/collapse the panel.
I had the same problem when click individual panels and then expand/collapse all. This work for me (richfaces 4.2.3):
<h:commandButton immediate="true" action="#{controllerBean.toggleMin}" value="collapse all" >
<a4j:ajax render="panel1 panel2"></a4j:ajax>
</h:commandButton>
<h:commandButton immediate="true" action="#{controllerBean.toggleMax}" value="expand all">
<a4j:ajax render="panel1 panel2"></a4j:ajax>
</h:commandButton>
...
<rich:collapsiblePanel id="panel1" immediate="true" expanded="#{modelBean.expanded}" header="Title text" switchType="client">
...
</rich:collapsiblePanel>
...

p:selectBooleanCheckbox and the label attached to it

The natural behaviour for a label attached to a checkbox button is to change the state of the button when it (the label) is clicked.
This works in JSF and Richfaces.
Is there a way to make it work in Primefaces(3.5) without involving javascript ?
Is this a bug ?
<p:outputLabel for="checkbox" value="Select it:" />
<p:selectBooleanCheckbox id="checkbox" label="My label" value="#{bean.value}" />
It doesn't work out-of-the-box in plain JSF but in PrimeFaces the itemLabel attribute should do it:
<p:selectBooleanCheckbox id="checkbox" itemLabel="My label" ... />
This bug has been fixed since PrimeFaces 4, so you can use p:outputLabel with recent versions of PrimeFaces. Good thing of the p:outputLabel is that it allows you to add body content to it. So you can add images, icons, a link to terms and conditions, etc.
<p:selectBooleanCheckbox value="#{bean.value}"/>
<p:outputLabel for="#previous">
Label to <strong>click</strong>
</p:outputLabel>

How display something near h:selectOneRadio item?

I have some list of elements, that generates my <h:selectOneRadio> items:
<h:selectOneRadio id="list#{cand.id}" value="#{mybean.value}" layout="pageDirection">
<c:forEach items="#{mybean.list}" var="c">
<f:selectItem id="first#{c.id}" itemlabel="#{c.surname}" itemValue="#{c.name}" />
</c:forEach>
</h:selectOneRadio>
I want next each element display <h:outputText> with value #{c.id}, so that at each row will be my radioButton element and next it some textbox. How can I do it ?
I tried something like that:
<h:selectOneRadio id="candidates1#{cand.id}" value="#{candidates.selectedCandidate1}" layout="pageDirection">
<c:forEach items="#{candidates.c1}" var="cand">
<td>
<f:selectItem id="first#{cand.id}" itemlabel="#{cand.surname}" itemValue="#{cand.name}">
<h:outputText id="c1ShortName#{cand.id}" value="#{cand.id}" />
</f:selectItem>
</td>
<td>
<h:outputText id="c1ShortName#{cand.id}" value="#{cand.id}" />
</td>
</c:forEach>
</h:selectOneRadio>
But it deisplays all radioButtons after last outputText.
I want something like the below screenshot. When right part is for example IDs, then it can be encrypted and decrypted.
Just put it in the item label.
itemlabel="#{c.id} #{c.surname}"
Or the other way round, you was not clear on that.
itemlabel="#{c.surname} #{c.id}"
You can if necessary use HTML like so, you should only beware of XSS attack hole in the surname.
itemlabel="#{c.surname} <strong>#{c.id}<strong>" itemEscaped="false"
Or, if you actually want to have them outside the generated <label>, then use a 3rd party component library. This is namely not supported by <h:selectOneRadio>. For example, Tomahawk's <t:selectOneRadio> has a layout="spread" attribute for that.
See also:
Radio buttons in different parts of the page
<h:selectOneRadio> renders table element, how to avoid this?
Unrelated to the concrete problem, you don't need that <c:forEach>. That's plain clumsy. Just use <f:selectItems var>. This is new since JSF 2.0, perhaps you were focusing too much on ancient JSF 1.x targeted resources.
<h:selectOneRadio ...>
<f:selectItems value="#{mybean.list}" var="c"
itemlabel="#{c.id} #{c.surname}" itemValue="#{c.name}" />
</h:selectOneRadio>
See also:
Our selectOneMenu wiki page

noSelectionLabel in jsf?

There are many situations when we want to tell the user to select an option from a selectOneMenu component. In Seam this is easily solved using noSelectionLabel.
<h:selectOneMenu value="#{seasonHome.id}">
<s:selectItems value="#{seasonListQuery.resultList}"
var="season"
label="xxxSeason #{season.startYear}"
noSelectionLabel="Select Season"
hideNoSelectionLabel="true" />
<s:convertEntity />
</h:selectOneMenu>
Can you please tell me if there is something similar in JSF 1.2?
I'm using icefaces with a list for selectItems like:
<ice:selectOneMenu
id="#{id}"
required="#{required}"
styleClass="#{styleClass} #{not required ? 'graNotRequired':''}"
style="width: #{width};font-size: #{fontSize};"
partialSubmit="#{partialSubmit}"
disabled="#{disabled}"
value="#{fieldOneDataHolder[fieldTwo]}">
<f:selectItems value="#{selectableItems}" />
<f:validator validatorId="#{validatorId}" />
</ice:selectOneMenu>
(please ignore parameters, this is a custom component I made).
I can introduce a new <f:selectItem itemLabel="Please select" itemValue=""/> above f:selectItems but this is difficult (I have to find a way to hide it in some cases etc)...
Do you know other work-around?
Thanks.
<f:selectItem itemLabel="Please select" itemValue="" itemDisabled="true" rendered="#{isShown}" />
The itemDisabled will make it shown but not selectable.
The boolean in rendered will decide whether the item is shown or not.

Correct layout of h:outputLabel and rich:combobox components on same line

With richfaces, how can I get my h:outputLabel and rich:combobox components to display directly adjacent to each other on the same line?
Here are the two approaches I've tried.
#1 rich:Layout
I first tried using rich:layout & rich:layoutPanel, but the components appear on separate lines. Here's the code:
<rich:layout>
<rich:layoutPanel position="left" width="100%">
<h:outputLabel for="timeSpanUnitsCombo2" value="Time Span " />
<rich:comboBox id="timeSpanUnitsCombo2" value="#{bean.timeSpanUnitsLabel}" enableManualInput="false">
<f:selectItems value="#{bean.timeSpanUnitsList}" />
</rich:comboBox>
</rich:layoutPanel>
</rich:layout>
And here's the rendered output:
#2 h:panelGrid
Next I tried using a h:panelGrid, but again no success - the components are evenly spaced over the available area, instead of being directly adjacent and left-aligned as I intended. Here's the code:
<h:panelGrid columns="2">
<h:outputLabel for="timeSpanUnitsCombo3" value="Time Span " />
<rich:comboBox id="timeSpanUnitsCombo3" value="#{bean.timeSpanUnitsLabel}" enableManualInput="false">
<f:selectItems value="#{bean.timeSpanUnitsList}" />
</rich:comboBox>
</h:panelGrid>
And here's the rendered output:
Component layout with richfaces is proving to be thoroughly frustrating. I'll give second prize to anyone who has some good references on layout with richfaces. :)
This can be done by many ways. One of them is to use fragment
<s:fragment>
<h:outputText value="Time Span" />
<rich:comboBox id="timeSpanUnitsCombo2" value="#{bean.timeSpanUnitsLabel}" enableManualInput="false">
<f:selectItems value="#{bean.timeSpanUnitsList}" />
</rich:comboBox>
</s:fragment>
Or you can use a div instead of fragment. <div> your code...</div>
If you are using seam, you can wrap it in <s:decorate> and use <s:label>
From Seam in Action
....<s:label> and <s:message>. The benefit of using the Seam tags is
that they are automatically correlated with the adjacent input component, a feature
of <s:decorate>

Resources