primefaces: TabView: validation failures not handled correctly with AJAX and skipChildren="false"
When you have a <p:tabView> with an <p:ajax skipChildren="false">, validation of all components inside the tabView will happen. If validation fails, model is not updated and listeners/setters are not called. so far, this is expected behavior. However, the active tab on client-side (in the browser) changes and thus client and server are not in sync regarding activeIndex, which is probably a bug!
Due to the tab-change in browser, validation-failure messages might be overlooked by the user, as they are likely to be shown in an inactive tab.
1) Environment
- PrimeFaces version: 6.2
2) Expected behavior
On validation failures, tab-switch should not happen at all (neither server nor client).
3) Actual behavior
Server state stays correct, but browser-state of widget changes.
4) Steps to reproduce
Run demo and change tabs without entering any values in the input fields. First change from tab “One” to “Two” will trigger validation failure but validation message won’t be shown as tab “Two” will be shown to the user.
5) Sample XHTML
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"><h:head>
<title>PrimeFaces Test</title>
</h:head>
<h:body>
<h:form id="theForm">
<p:tabView id="myTabs" widgetVar="myTabs"
activeIndex="#{testViewCdi.activeIndex}"
dynamic="true" cache="false">
<p:ajax event="tabChange" skipChildren="false"
listener="#{testViewCdi.tabChangedListener}"
oncomplete="console.log('activeIndex=' + PF('myTabs').getActiveIndex())" />
<p:tab id="tabOne" title="One">
<div>This is Tab 1!</div>
<h:inputText id="in1" required="true" requiredMessage="in1 required!"/>
<p:message for="in1"/>
</p:tab>
<p:tab id="tabTwo" title="Two">
<div>This is Tab 2!</div>
<h:inputText id="in2" required="true" requiredMessage="in2 required!"/>
<p:message for="in2"/>
</p:tab>
</p:tabView>
</h:form>
</h:body>
</html>
6) Sample bean
@Named
@ViewScoped
public class TestViewCdi implements java.io.Serializable {
private int activeIndex;
@PostConstruct
public void init() {
activeIndex = 0;
}
public void tabChangedListener(TabChangeEvent event) {
System.out.println("Tab changed to " + event.getTab().getId());
}
public int getActiveIndex() {
return activeIndex;
}
public void setActiveIndex(int idx) {
System.out.println("setting activeIndex to " + idx);
this.activeIndex = idx;
}
}
About this issue
- Original URL
- State: open
- Created 5 years ago
- Comments: 17 (17 by maintainers)
@matinh I am using the showcase and to me its working exactly as I would expect.
If you enter data and switch tabs you should NOT be notified as you have not submitted the form. So because those two fields are required in your scenario you would NEVER be able to switch off the first tab until the fields are filled out properly. That would be unexpected behavior.
So to be clear are you saying in the Showcase example if you were to just go to the page and switch to tab 2 you would expect both fields to show “Required” validation and the tab to not change?