Initially hold_mode
value is set to 0
, after commandButton
click, it changed to 1 through JavaScript onclick event...but in PhaseListener beforePhase() method, the value is 0
. I did not understand why the value is still 0
.
Can anyone please explain me on this.?
<h:form id="userForm">
<h:inputHidden id="hold_mode" value="0" />
<h:commandButton id="hold" style="width: 60px;" value="#{myForm.holdbtntitle}" disabled="#{myForm.holdbtn}" action="#{myForm.hold}" actionListener="#{convo.holdListener}" onclick="return send(true,'3');" rendered="#{myForm.holdpanelflg}"/>
function send(confirmFlg,msgFlg) {
isClicked = true;
if(confirmFlg) {
msg = 'From Hold';
if(confirm(msg) == false) {
isClicked = false;
event.returnValue = false;
return false;
}
}
if(isClicked) {
if(msgFlg == '3') {
document.all.item('myForm:hold_mode').value='1';
}
pep_OpenWaitDirect('../../../html/common/printwait.xhtml');
return true;
} else {
return false;
}
}
public class RemoveValidateListener implements PhaseListener {
private static final long serialVersionUID = 3556867423746720962L;
private FacesContext old = null;
public void beforePhase(PhaseEvent e) {
System.out.println("Before "+e.getPhaseId());
if(e.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) {
UIComponent comp = FacesContext.getCurrentInstance().getViewRoot();
if(findHoldMode(comp)){
old = FacesContext.getCurrentInstance();
removeValidatorsForComponentTree(comp);
}
}
}
public void afterPhase(PhaseEvent e) {
System.out.println("After "+e.getPhaseId());
if(e.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) {
FacesContext context = FacesContext.getCurrentInstance();
UIComponent comp = FacesContext.getCurrentInstance().getViewRoot();
if(findHoldMode(comp)){
StateManager stateManager = (StateManager)context.getApplication().getStateManager();
stateManager.restoreView(old,old.getViewRoot().getViewId(),old.getViewRoot().getRenderKitId());
}
}
}
private boolean findHoldMode(UIComponent comp){
boolean rtnFlg = false;
List list = comp.getChildren();
for (int i = 0; i < list.size(); i++) {
UIComponent temp = (UIComponent) list.get(i);
if (!(temp instanceof HtmlBody)) {
continue;
} else {
List<UIComponent> childList = temp.getChildren();
for (int j = 0; j < childList.size(); j++) {
UIComponent childTemp = (UIComponent) childList.get(j);
if (!(childTemp instanceof HtmlPanelGrid)) {
continue;
} else {
List<UIComponent> child2List = childTemp.getChildren();
for (int k = 0; k < child2List.size(); k++) {
UIComponent child2Temp = (UIComponent) child2List.get(k);
if (!(child2Temp instanceof HtmlForm)) {
continue;
}
UIComponent hold = child2Temp.findComponent(JsfBase.HOLD_MODE_COMPNAME);
if (hold == null) {
continue;
}
if (!(hold instanceof UIInput)) {
continue;
}
Object mode = ((UIInput) hold).getValue();
if (mode == null || !(mode.toString().equals(JsfBase.HOLD_MODE_ON))) {
continue;
} else {
rtnFlg = true;
((UIInput) hold).setValue("0");
break;
}
}
}
}
}
}
return rtnFlg;
}
private void removeValidatorsForComponentTree(UIComponent comp){
removeValidators(comp);
List complist = comp.getChildren();
if (complist.size()>0){
for(int i = 0; i < complist.size(); i++) {
UIComponent uicom = (UIComponent) complist.get(i);
removeValidatorsForComponentTree(uicom);
}
}
}
private void removeValidators(UIComponent comp){
if(comp instanceof UIInput){
removeValidator((UIInput)comp);
}
}
public void removeValidator(UIInput comp){
Validator[] validator = comp.getValidators();
for(int i=0;i < validator.length;i++){
comp.removeValidator(validator[i]);
}
if(comp.isRequired()){
comp.setRequired(false);
}
}
}
I tried this <h:inputHidden id="hold_mode" value="0" immediate="true" />
and it works for the current screen but the problem is when I click the commandButton
in other screens, the following exception occured
java.lang.IllegalStateException: FacesContext already released
Issue got fixed after modified PhaseListener
Why I got IllegalStateException
is as I have declared FacesContext
object old
globally. In that case, I had declared it inside befoerPhase
method as we don't declare FacesContext
globally..
Before code modification, what we did is we removed validators in beforePhase
and we are restoring the view state in afterPhase
, but it did not worked properly. So now I am saving the view state before validators removal in beforePhase
instead of restoring it in afterPhase
..
public class RemoveValidateListener implements PhaseListener {
private static final long serialVersionUID = 3556867423746720962L;
public void beforePhase(PhaseEvent e) {
if (e.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) {
FacesContext context = FacesContext.getCurrentInstance();
UIComponent comp = context.getViewRoot();
StateManager stateManager = (StateManager) context.getApplication().getStateManager();
stateManager.saveView(context);
if (findHoryuMode(comp)) {
removeValidatorsForComponentTree(comp);
}
}
}
public void afterPhase(PhaseEvent e) {
}
}