I use OmniFaces' <o:validateAll> validator to validate a number of input components. This works fine as long as I do not put it into a RichFaces <rich:tabPanel>. When I do this and leave fields blank, validation fails (as expected), but the active tab is changed, regardless of the failed validation. Other validators I tried prevent the tabPanel from switching to another tab, whenever validation fails.
What could be the reason for this?
I'm currently using OmniFaces 2.1 and RichFaces 4.5.17.Final with Mojarra 2.2.12 on Wildfly 9.0.2.
Here is the XHTML code to reproduce the problem:
<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:o="http://omnifaces.org/ui"
xmlns:rich="http://richfaces.org/rich">
<h:form id="form">
<rich:messages />
<rich:tabPanel id="tabPanel">
<rich:tab id="tab1" header="Tab 1">
<h:inputText id="myDouble" value="#{someDoubleVal}">
<f:validateDoubleRange minimum="1.0" maximum="2.0"/>
</h:inputText>
<o:validateAll id="allValid" components="myDouble" message="Missing value!" />
</rich:tab>
<rich:tab id="tab2" header="Tab 2">
Just another tab to switch.
</rich:tab>
</rich:tabPanel>
</h:form>
</ui:composition>
Enter a value outside 1.0 and 2.0 and try switching to Tab 2 to see expected behavior, triggered by <f:validateDoubleRange>: a faces-message is displayed and the first tab is still active.
Leave input blank and try switching to Tab 2 to see behavior of <o:validateAll>: validation seems to fail (a faces-message is displayed), but Tab 2 is activated.
Update: The described behavior applies with switchType="ajax" (the default) as well as with switchType="server". In both cases, the tab-panel performs a submit of the included inputs, so from a users point of view, a tab-switch seems to be the same as a <h:commandButton> submit (technically there might be differences, I don't know the implementation details of the tab-panel).
If I perform the tab-switch via a regular <h:commandButton> with a <f:setPropertyActionListener>, the <o:validateAll> behaves the same way as the other validators, i.e. the tab-switch is not performed due to the validation error.
<rich:tabPanel id="tabPanel" activeItem="#{bb.activeTab}">
...
<rich:tab id="tab1" name="tab1" header="Tab 1">
...
<h:commandButton value="submit">
<f:setPropertyActionListener value="tab2" target="#{bb.activeTab}" />
</h:commandButton>
...
</rich:tab>
</rich:tabPanel>
Note: This is just a minimalistic example showing the problematic behavior. In my real code I have not just a single component validated by <o:validateAll> and I do actually associate the input values with a backing-bean. The observed behavior is exactly the same.
<o:validateAll>tag in the XHTML code changes the behavior! Put it before the components that should actually be validated and it works as expected. Is this desired behavior or a bug in OmniFaces? The documentation doesn't mention this effect. Any ideas? - Martin Höller<p:tabView>behaves completely different to RichFaces.<rich:tabPanel>submits all inputs inside the active tab when switching to another tab (of course, when in ajax-mode which is the default). When using<p:tabView>the input values do not get processed on server, until you add explicit<p:ajax>to the inputs. So IMHO a direct comparison is not possible here. - Martin Höller