I am currently working on a complex project that involves a large table and numerous relations. To manage this, my form includes multiple tabs, dialogs, and PrimeFaces commandButtons for CRUD operations using Ajax requests.
The structure of the xhtml file looks something like this:
<ui:define name="content">
<h:body>
<p:growl id="growl"/>
<h:form id="formCars" enctype="multipart/form-data">
<p:tabView id="formTabView" scrollable="true" >
<p:tab title="Tab1">
<ui:include src="tabOne/tabOne.xhtml" />
</p:tab>
<p:tab title="Tab2">...</p:tab>
...
<p:tab title="Tab8">...</p:tab>
</p:tabView>
<br />
<div align="center">
<p:commandButton id="cmdSave" value="Save"
action="#{controllerMB.save}" icon="ui-icon-disk"
update="@form :growl" process="@form @this" validateClient="true" />
</div>
</h:form>
<p:dialog header="Car Color" id="modalCarColor" widgetVar="modalCarColor" appendToBody="true" modal="true" height="500" width="700" dynamic="true" closeOnEscape="true" >
<p:ajax event="close" listener="#{controllerMB.closeModalCarColor}" update="@this,:formCarColor"/>
<h:form id="formCarColor">
<ui:include src="tabTwo/carColor/carColor.xhtml" />
</h:form>
</p:dialog>
<p:dialog header="Car Size" ...>
<p:ajax event="close" .../>
<h:form id="formCarColor">...</h:form>
</p:dialog>
</h:body>
</ui:define>
Everything works perfectly fine, however I have encountered an issue when attempting to reload the page. While I am able to maintain the main object in the flash using
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep(key)
in the @PostConstruct method of the @ViewScoped controller, if any Ajax request is triggered, the main object stored in the JSF Flash Scope gets lost, preventing me from reloading the page.
My current controller implementation is structured as follows:
@ManagedBean(name="controllerMB")
@ViewScoped
public class ControllerMB implements Serializable{
// PostConstruct method
@PostConstruct
public void init(){
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
}
if(car==null) {
redirect_back();
return;
}
// Initializing attributes and preparing form
}
// Other methods
}
Is there a solution or workaround available for this issue? Additionally, is it feasible to capture/handle the reload event from the browser with JavaScript to process the form data before the reload?
I am utilizing PrimeFaces 5.3, JSF 2, Maven, Tomcat 7 and Java 7 for this project. Any insights or suggestions would be greatly appreciated.
Edit 1: Upon implementing the solution provided by user NightEagle, although it almost worked, I encountered some issues. I made modifications to the code as follows:
<ui:composition ....>
<f:metadata>
<f:event type="preRenderView" listener="#{controllerMB.preRender}"/>
</f:metadata>
<ui:define name="title">...</ui:define>
<ui:define name="header">...</ui:define>
<ui:define name="content">...</ui:define>
</ui:composition>
and
public void preRender()
{
System.out.print("PRE-RENDER ");
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
System.out.println("KEEP");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
} else {
System.out.println("PUT");
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car",car);
}
}
After opening several dialogs, the application started displaying the JSF1095 error. Here is the output after interacting with the UI:
PRE-RENDER PUT
PRE-RENDER KEEP
PRE-RENDER KEEP
Jul 14, 2017 11:43:59 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:00 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:04 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
Your assistance in finding a suitable solution would be greatly appreciated. Thank you in advance.