We are starting to develop with PrimeFaces 3.4, JSF 2.0 and Tomcat 7.0. We are facing the problem that when we make a form page, we can navigate with the tab button on all the PrimeFaces input components, expect of <p:selectBooleanButton>. For example,
<h:form id="formId">
<p:inputText id="inputId1" />
<p:inputText id="inputId2" />
<p:selectBooleanButton id="buttonId" onLabel="Yes" offLabel="No" />
<p:inputText id="inputId3" />
<p:inputText id="inputId4" />
</h:form>
Pressing tab in inputId2 goes directly to inputId3. Is this the expected behaviour? Is there any workaround?
It’s because of the way how the checkbox representing the state of
<p:selectBooleanButton>was actually rendered by PrimeFacesSelectBooleanButtonRenderer:The checkbox is completely hidden by the CSS
display:noneproperty in.ui-helper-hiddenclass and can thus never receive focus.If we look at the checkbox counterpart
<p:selectBooleanCheckbox>, which also replaces the checkbox by a visually more appealing widget which is actually focusable, then we see that the checkbox isn’t completely hidden by CSS, but just made invisible by being wrapped in a<div>which is absolutely positioned by CSSposition:absolutein.ui-helper-hidden-accessibleclass and is thus just overlayed by the checkbox widget:I wouldn’t consider the
<p:selectBooleanButton>being unfocusable “expected” or “intuitive” behaviour and if I were you, I’d surely report this UX matter to PrimeFaces.In the meanwhile, your best bet to workaround this is to create a custom renderer which overrides the
encodeMarkup()method of the PrimeFacesSelectBooleanButtonRendereras follows in order to remove theclass="ui-helper-hidden"from the checkbox and wrap it in a<div class="ui-helper-hidden-accessible>, exactly as<p:selectBooleanCheckbox>is doing:(look at the
//inputsection, I have added<--comments to explain which lines I’ve added/removed to the original source code which is been copypasted)To get it to run, register it as follows in
faces-config.xml:(the
component-familyandrenderer-typevalues are extracted fromSelectBooleanButtoncomponent)This works for me, well, kind of. The
<p:selectBooleanButton>gets focus and you can use the spacebar to toggle the boolean state. However, the focus isn’t visually visible in any way. This needs to be solved in the JavaScript side. The<div class="ui-button">representing the button should get an.ui-state-focusclass when the hidden checkbox gets focus. The following piece of jQuery achieves that:Now it totally works for me.
In real PrimeFaces source code this should be solved in
init()function of thePrimeFaces.widget.SelectBooleanButtonfunction of theforms.jsfile.