p:selectBooleanCheckbox and the label attached to it - jsf

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>

Related

Primeface Tooltip should look like rowEditor Tooltip

I am using a primeface dataTable and the primeface rowEditor. As tooltip for the deleteLink I use a primeface tooltip.
The primeface tooltip doesn´t look like the rowEditor tooltip. Is there a possibility that they look same?
<p:column style="width:32px">
<p:rowEditor editTitle="Bearbeiten" saveTitle="Speichern" cancelTitle="Abbrechen" />
</p:column>
<p:column style="width:32px">
<p:commandLink id="deleteLink" styleClass="ui-icon ui-icon-trash" action="#{SFKBean.deleteStrasse(str)}" update="strList, :sdform:msgs" />
<p:tooltip id="deleteLinkTT" for="deleteLink" value="Straße entfernen" position="bottom" />
</p:column>
That's how it looks
rowEditor '...title' tooltips are browser tooltips. p:tooltip generates non-browser tooltips that (can by design) are not easily made to look like browser tooltips (different for each browser) and are meant for components that doe not support browser based tooltips. If you want a 'normal' tooltip, use the title attribute on the p:commandLink
<p:commandLink id="deleteLink" styleClass="ui-icon ui-icon-trash" action="#{SFKBean.deleteStrasse(str)}" update="strList, :sdform:msgs" title="Straße entfernen" />
If you do want to style the p:tooltip like browser native ones, add a styleClass attribute to it and make selectors that are specific for browsers (might require some javascript)

Custom selectItems

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

ValueChangeListener problem

While calling the ValueChangeListener in JSF based on value change in dropdown, it is calling all the ValueChangeListner that are on that page.
There are two valueChangeListener in DataTable, while changing value in one dropdwon the 2nd one also executing.
<t:column id="avlId" styleClass="coltextcenteralign">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="#{bundle['travelLocalAccommodation.title.availability']}" />
<h:outputText value="*" style="color:red" />
</h:panelGroup>
</f:facet>
<t:selectOneMenu value="#{accomDtls.availability}" immediate="true"
valueChangeListener="#{TravelProcessingBB.localAccommodationBB.setAvailableFlag}" forceid="true" id="avl"
onchange="return availabilityAlert('#{accomDtls.prepopulatedFlag}','avl[#{table_count}]')"
styleClass="dropDownStyle" style="width:50">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
</t:selectOneMenu>
</t:column>
The value change alone won't automatically call the valueChangeListener. You need to submit the form as well. A commonly used "hack" is to call form.submit() using JavaScript during the onchange event. This will however submit the entire form. Truly the valueChangeListener will be triggered for all changed fields of the form.
To fix this in JSF 1.x, you need to hassle somewhat with the immediate attribute to skip all other form components from validating and with component binding so that you can properly get/set the other component's value. Long story short, I ever wrote an article about that: populate child menus in JSF 1.2.
In JSF 2.0, this is however easier to achieve with help of <f:ajax> tag. If you're really using JSF 2.0 (your current question doesn't indicate that), then let me know if you need an example.

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>

Attach rich:toggleControl to radio buttons or select items

Has anyone had any success attaching a rich:toggleControl component to a radio button component (h:selectOneRadio) or alternatively any of its children select items (in this case s:enumItem).
Basic code example:
<h:selectOneRadio value="#{backingValue}">
<s:enumItem enumValue="VAL_1" itemLabel="Value One" />
<s:enumItem enumValue="VAL_2" itemLabel="Value Two" />
<s:convertEnum />
</h:selectOneRadio>
The ideal thing would be to attach the toggle control to the s:enumItems so I could have it switch to a particular state. However at this point I'd be happy if the toggle control can just be attached to the h:selectOneRadio. I've tried the toggle control as a child of the h:selectOneRadio and s:enumItems; neither works. I've also tried wrapping the toggleControl around the h:selectOneRadio, the toggle control works in this case but the radio buttons don't.
Just tie your rich:togglePanel to the same value on your backing bean, and use an a4j support tag to update the value and re-render the panel.
One thing to keep in mind is that the rich:togglePanel #value attribute must resolve to a String, so you'll probably need to bind to #{backingValue.name()} (don't use toString() since somone might override it on you later...)
something like this should work:
<h:selectOneRadio id="radioButtons" value="#{backingValue}">
<a4j:support event="onclick"
ajaxSingle="true"
reRender="radioButtons, togglePanel"/>
<s:enumItem enumValue="VAL_1" itemLabel="Value One" />
<s:enumItem enumValue="VAL_2" itemLabel="Value Two" />
<s:convertEnum />
</h:selectOneRadio>
<rich:togglePanel id="togglePanel"
switchType="ajax"
value="#{backingValue.name()}" >
<f:facet name="VAL_1">
<h:outputText value="Selected enum value 1"/>
</f:facet>
<f:facet name="VAL_2">
<h:outputText value="Selected enum value 2"/>
</f:facet>
</rich:togglePanel>
You might have to play with the ajax support event binding as well. I've found that the "onchange" and "onselect" events with radio buttons can be a little bit spotty where AJAX4JSF is concerned. I've done this with Strings, where an action in my backing bean changes the toggle panel state by setting the value - but it SHOULD Work with enum's as well.
This isn't strictly an answer to my above question but it's a work around I'm using for now until I figure out how to do it 'better' re- above.
Anyway the workaround: add an onclick event to the h:selectOneRadio which calls the rich:togglePanel's javascript API:
onclick="TogglePanelManager.toggleOnClient('TOGGLE_PANEL_ID_HERE',null);"
Still I would like to do this 'properly' using the rich:toggleControl component if possible ...

Resources