In dynamic mode, only the tabs that have been accessed are updated, so if you want to change from tab 1 to tab 2, you can save the first time, but the second time, tab 1 does not have the data since it was not accessed after saving.
When starting the page it needs to pick the first active tab. If needed, in getActiveTabs, you can initialize activeTabs and configure the fields outside the tabView.
The init method will initialize the lastActiveTab fetching the fields from getActiveTabs and adding the first tab that is initialized.
The save button will only process the getActiveTabs fields by searching the getSaveProcess method. Every time it switches to a new tab it will add a new active tab and increase the amount of tabs it needs to process. After saving it cleans the active tabs and inserts the mandatory fields in getActiveTabs and inserts the last active tab, always repeating the same process
private Set<String> activeTabs;
private String lastActiveTab = "form:tabview:tab1";
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
getAbasAtiva().add("form:tabView:tab1");
}
}
public void onChange(TabChangeEvent event) {
tabIndex = ((TabView) event.getSource()).getActiveIndex();
lastActiveTab = event.getTab().getClientId();
if (getProcess().containsKey(lastActiveTab)) {
getActiveTabs().add(getProcess().get(lastActiveTab));
} else {
getActiveTabs().add(lastActiveTab);
}
}
private Map<String, String> getProcess() {
Map<String, String> process = new HashMap<>();
process.put("form:tabview:tab2", "form:tabview:childTab2");
return process;
}
public Set<String> getActiveTabs() {
if (abasAtiva == null) {
abasAtiva = new HashSet<>();
abasAtiva.add("form:otherRequiredFields");
}
return abasAtiva;
}
public void setActiveTabs(Set<String> activeTabs) {
this.activeTabs = activeTabs;
}
private void save(){
//...
setActiveTabs(null);
if (getProcess().containsKey(lastActiveTab)) {
getActiveTabs().add(getProcess().get(lastActiveTab));
} else {
getActiveTabs().add(lastActiveTab);
}
}
public String getSaveProcess() {
return String.join(", ", getActiveTabs().stream().filter(Objects::nonNull).collect(Collectors.toList());
}
<p:form id="form>
<f:event type="preRenderView" listener="#{controller.init()}" />
<p:tabView id="tabView" dynamic="true" tabindex="#{controller.tabIndex}" >
<p:ajax event="tabChange" update="form:save" listener="#{controller.onChange}" />
<p:tab id="tab1" title="Tab1" ></p:tab>
<p:tab id="tab2" title="Tab2" ></p:tab>
<p:tab id="tab3" title="Tab3" ></p:tab>
</p:tabView>
<p:commandButton id="save" value="Save" process="@this,#{controller.saveProcess}" update="form" />
</p:form>