javascriptjsf-2phaselistener

values modified in javascript not getting updated in JSF PhaseListener


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.?

info.xhtml

<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}"/>

JavaScript

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;
    }
}

PhaseListener

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


Solution

  • Issue got fixed after modified PhaseListener

    1. 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..

    2. 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) {
      
          }
      

      }