ICEfaces
  1. ICEfaces
  2. ICE-6888

The value of an ACE checkbox button inside a tab is not remembered when changing tabs

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.0, EE-2.0.0.GA, 2.0.2
    • Fix Version/s: 3.0
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      Any
    • Assignee Priority:
      P1

      Description

      If we have a checkbox button inside a tab and we set it to true, and then we change tabs, when returning to the tab that contains the checkbox button, it will always be set to false, regardless of what is the default value in the bean. The test app used was /repo/qa/trunk/Regression-Icefaces2/Sparkle/Nightly/CheckboxBttn. Although the bean used in this app has the annotation @ViewScoped, the same problem occurred when changing it to @SessionScoped.

        Issue Links

          Activity

          Hide
          Mark Collette added a comment -

          TabSet doesn't override UIComponent.visitTree, but I pasted it in to debug what's happening, and I can see that state saving and state restoring are happening. There's a lot of extraneous state restoration from dynamically added components, possibly due to specifics of the showcase application. Again, the submittedValue is in the inputText all the way through the first lifecycle, and is always missing in the second lifecycle where we tab back. One would expect it to be initially null, and then appear during state restoration.

          Show
          Mark Collette added a comment - TabSet doesn't override UIComponent.visitTree, but I pasted it in to debug what's happening, and I can see that state saving and state restoring are happening. There's a lot of extraneous state restoration from dynamically added components, possibly due to specifics of the showcase application. Again, the submittedValue is in the inputText all the way through the first lifecycle, and is always missing in the second lifecycle where we tab back. One would expect it to be initially null, and then appear during state restoration.
          Hide
          Mark Collette added a comment -

          Added an inputText outside of the tabSet, and while it appeared to retain its value, it actually lost it from state saving, and only regained it because it was re-submitted sice the component had remained rendered in the view. So, while it appears to the casual observer that tabSet behaves differently, this actually proves it's behaving the same.

          I'm going to do further testing to see if it's related to the form.

          Show
          Mark Collette added a comment - Added an inputText outside of the tabSet, and while it appeared to retain its value, it actually lost it from state saving, and only regained it because it was re-submitted sice the component had remained rendered in the view. So, while it appears to the casual observer that tabSet behaves differently, this actually proves it's behaving the same. I'm going to do further testing to see if it's related to the form.
          Hide
          Mark Collette added a comment -

          So, the phase execution is now corrected in TabSet, it just has to be committed, but this is the analysis of the continuance of the bad symptoms even after the code fix.

          I modified the basic application to use this view definition:

          <f:phaseListener
          type="org.icefaces.demo.basic.InputPhaseListener"/>
          <h:form id="myform">
          <h:inputText id="myinput" value="#

          {basic.input}

          "/>
          <h:commandButton id="mybutton" immediate="true" actionListener="#

          {basic.actionListener}

          "/>
          <h:panelGroup id="mygroup">
          <h:messages id="mymessages"/>
          </h:panelGroup>
          </h:form>

          and this bean code:

          public void actionListener(ActionEvent event)

          { System.out.println("Basic.actionListener " + FacesContext.getCurrentInstance().getCurrentPhaseId()); }

          public void setInput(String input)

          { System.out.println("Basic.setInput " + FacesContext.getCurrentInstance().getCurrentPhaseId() + " old: " + this.input + " new: " + input); this.input = input; }

          public String getInput()

          { System.out.println("Basic.getInput " + input); return input; }

          private String input;

          and this InputPhaseListener:

          public class InputPhaseListener implements PhaseListener {
          public void afterPhase(PhaseEvent phaseEvent)

          { FacesContext context = FacesContext.getCurrentInstance(); System.out.println("recursivelyPrintInputs() " + context.getCurrentPhaseId() + " AFTER"); recursivelyPrintInputs(context.getViewRoot()); }

          public void beforePhase(PhaseEvent phaseEvent)

          { FacesContext context = FacesContext.getCurrentInstance(); System.out.println("recursivelyPrintInputs() " + context.getCurrentPhaseId() + " BEFORE"); recursivelyPrintInputs(context.getViewRoot()); }

          public PhaseId getPhaseId()

          { return PhaseId.ANY_PHASE; }

          private static void recursivelyPrintInputs(UIComponent comp) {
          if (comp == null)

          { System.out.println("recursivelyPrintInputs() comp is null"); return; }

          if (comp instanceof javax.faces.component.UIInput)

          { printInputs((javax.faces.component.UIInput)comp); }

          for (Iterator<UIComponent> it = comp.getFacetsAndChildren(); it.hasNext()

          { UIComponent kid = it.next(); recursivelyPrintInputs(kid); }

          }

          private static void printInputs(javax.faces.component.UIInput comp)

          { System.out.println("printInputs() clientId: " + comp.getClientId()); System.out.println("printInputs() submittedValue: " + comp.getSubmittedValue()); System.out.println("printInputs() localValueSet: " + comp.isLocalValueSet()); System.out.println("printInputs() localValue: " + comp.getLocalValue()); System.out.println("printInputs() value: " + comp.getValue()); }

          }

          With all that, I tested the icefaces page and non-icefaces page, and the non-icefaces page with icefaces removed for a pure stock JSF scenario. In all of them, the phase listener showed that the inputText loses it's submittedValue in-between lifecycles. Auditing UIInput source shows that submittedValue is treated differently than all other fields, where is it specifically excluded from the StateHelper state saving mechanism.

          So the conclusion is that it's not tabSet's fault, when an input component loses it's submittedValue, when it does a renderResponse() after decode, which happens when immediate="true" and cancelOnInvalid="true".

          Show
          Mark Collette added a comment - So, the phase execution is now corrected in TabSet, it just has to be committed, but this is the analysis of the continuance of the bad symptoms even after the code fix. I modified the basic application to use this view definition: <f:phaseListener type="org.icefaces.demo.basic.InputPhaseListener"/> <h:form id="myform"> <h:inputText id="myinput" value="# {basic.input} "/> <h:commandButton id="mybutton" immediate="true" actionListener="# {basic.actionListener} "/> <h:panelGroup id="mygroup"> <h:messages id="mymessages"/> </h:panelGroup> </h:form> and this bean code: public void actionListener(ActionEvent event) { System.out.println("Basic.actionListener " + FacesContext.getCurrentInstance().getCurrentPhaseId()); } public void setInput(String input) { System.out.println("Basic.setInput " + FacesContext.getCurrentInstance().getCurrentPhaseId() + " old: " + this.input + " new: " + input); this.input = input; } public String getInput() { System.out.println("Basic.getInput " + input); return input; } private String input; and this InputPhaseListener: public class InputPhaseListener implements PhaseListener { public void afterPhase(PhaseEvent phaseEvent) { FacesContext context = FacesContext.getCurrentInstance(); System.out.println("recursivelyPrintInputs() " + context.getCurrentPhaseId() + " AFTER"); recursivelyPrintInputs(context.getViewRoot()); } public void beforePhase(PhaseEvent phaseEvent) { FacesContext context = FacesContext.getCurrentInstance(); System.out.println("recursivelyPrintInputs() " + context.getCurrentPhaseId() + " BEFORE"); recursivelyPrintInputs(context.getViewRoot()); } public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; } private static void recursivelyPrintInputs(UIComponent comp) { if (comp == null) { System.out.println("recursivelyPrintInputs() comp is null"); return; } if (comp instanceof javax.faces.component.UIInput) { printInputs((javax.faces.component.UIInput)comp); } for (Iterator<UIComponent> it = comp.getFacetsAndChildren(); it.hasNext() { UIComponent kid = it.next(); recursivelyPrintInputs(kid); } } private static void printInputs(javax.faces.component.UIInput comp) { System.out.println("printInputs() clientId: " + comp.getClientId()); System.out.println("printInputs() submittedValue: " + comp.getSubmittedValue()); System.out.println("printInputs() localValueSet: " + comp.isLocalValueSet()); System.out.println("printInputs() localValue: " + comp.getLocalValue()); System.out.println("printInputs() value: " + comp.getValue()); } } With all that, I tested the icefaces page and non-icefaces page, and the non-icefaces page with icefaces removed for a pure stock JSF scenario. In all of them, the phase listener showed that the inputText loses it's submittedValue in-between lifecycles. Auditing UIInput source shows that submittedValue is treated differently than all other fields, where is it specifically excluded from the StateHelper state saving mechanism. So the conclusion is that it's not tabSet's fault, when an input component loses it's submittedValue, when it does a renderResponse() after decode, which happens when immediate="true" and cancelOnInvalid="true".
          Hide
          Mark Collette added a comment -

          Committed the phase execution changes.

          icefaces 3 trunk
          Subversion 27179

          Show
          Mark Collette added a comment - Committed the phase execution changes. icefaces 3 trunk Subversion 27179
          Hide
          Carmen Cristurean added a comment - - edited

          Fix verified in IE8, FF6, Chrome15, using Icefaces3 revision # 27279, and test from /repo/qa/trunk/Regression-Icefaces2/Sparkle/Nightly/CheckboxBttn.

          Show
          Carmen Cristurean added a comment - - edited Fix verified in IE8, FF6, Chrome15, using Icefaces3 revision # 27279, and test from /repo/qa/trunk/Regression-Icefaces2/Sparkle/Nightly/CheckboxBttn.

            People

            • Assignee:
              Mark Collette
              Reporter:
              Arturo Zambrano
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: