ICEfaces
  1. ICEfaces
  2. ICE-1343

An <ice:commandButton> with immediate="true" does not set the UIInput.setSubmittedValue(null) like the ProcessValidations phase does

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Duplicate
    • Affects Version/s: 1.5.3
    • Fix Version/s: None
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      Windows XP / Tomcat 5.5.17
    • Workaround Exists:
      Yes
    • Workaround Description:
      Hide
      The workaround is a hack. It involves putting an action listener on the Cancel button:

                <ice:commandButton actionListener="#{PortalUserList.rowPanelGroupCancelButtonListener}" immediate="true" styleClass="portlet-form-button" value="#{DataTableMsgs.keyValues['Cancel']}"/>

      Here is the listener:

          public void rowPanelGroupCancelButtonListener(ActionEvent actionEvent)
          {
              this.rowPanelGroupVisible = false;
              JSFUtils.clearSubmittedFormValues(JSFUtils.getForm(actionEvent.getComponent()));
          }

      And here is the clearSubmittedFormValues() static methods from my JSFUtils class:

          /**
           * This method (along with its private, recursive counterpart) is more or less a hack to try and fix a problem that
           * manifests itself with ICEfaces and <ice:commandButton> components with immediate="true". The folks at ICEsoft
           * need to make this be part of their partial-submit aspect of the JSF lifecycle.
           */
          public static void clearSubmittedFormValues(UIForm uiForm)
          {
              clearSubittedFormValuesRecurse(uiForm);
          }


          private static void clearSubittedFormValuesRecurse(UIComponent uiComponent)
          {
              if (uiComponent instanceof UIInput)
              {
                  UIInput uiInput = (UIInput) uiComponent;
                  uiInput.setSubmittedValue(null);
              }
              List childList = uiComponent.getChildren();
              if (childList != null)
              {
                  Iterator iterator = childList.iterator();
                  while (iterator.hasNext())
                  {
                      clearSubittedFormValuesRecurse((UIComponent) iterator.next());
                  }
              }
          }
      Show
      The workaround is a hack. It involves putting an action listener on the Cancel button:           <ice:commandButton actionListener="#{PortalUserList.rowPanelGroupCancelButtonListener}" immediate="true" styleClass="portlet-form-button" value="#{DataTableMsgs.keyValues['Cancel']}"/> Here is the listener:     public void rowPanelGroupCancelButtonListener(ActionEvent actionEvent)     {         this.rowPanelGroupVisible = false;         JSFUtils.clearSubmittedFormValues(JSFUtils.getForm(actionEvent.getComponent()));     } And here is the clearSubmittedFormValues() static methods from my JSFUtils class:     /**      * This method (along with its private, recursive counterpart) is more or less a hack to try and fix a problem that      * manifests itself with ICEfaces and <ice:commandButton> components with immediate="true". The folks at ICEsoft      * need to make this be part of their partial-submit aspect of the JSF lifecycle.      */     public static void clearSubmittedFormValues(UIForm uiForm)     {         clearSubittedFormValuesRecurse(uiForm);     }     private static void clearSubittedFormValuesRecurse(UIComponent uiComponent)     {         if (uiComponent instanceof UIInput)         {             UIInput uiInput = (UIInput) uiComponent;             uiInput.setSubmittedValue(null);         }         List childList = uiComponent.getChildren();         if (childList != null)         {             Iterator iterator = childList.iterator();             while (iterator.hasNext())             {                 clearSubittedFormValuesRecurse((UIComponent) iterator.next());             }         }     }

      Description

      An <ice:commandButton> with immediate="true" does not set the UIInput.setSubmittedValue(null) like the ProcessValidations phase does. This causes problems when you have two panelgroups (only one rendered at a time) with <ice:panelGroup rendered="#{Bean.isRendered}"> and <ice:panelGroup rendered="#{!Bean.isRendered}"> like we have in PortalUserList.jspx.

        Issue Links

          Activity

          Hide
          Sheng Gu added a comment -

          To Mark Collette: In our project, a user click on calendar schedule (MyFaces), then the calendar will pop up a popup panel with the clicked time. If the user click cancel button and click on another time, then the popup will get another the clicked time. However, if I set immediate=true, the popup always keep the first clicked time. Only after I set the immediate=false, then use can always get his clicked time on each click. But when setting immediate=false, the popup will validate each required field when use click Cancel, that is very bad. Thanks.

          Show
          Sheng Gu added a comment - To Mark Collette: In our project, a user click on calendar schedule (MyFaces), then the calendar will pop up a popup panel with the clicked time. If the user click cancel button and click on another time, then the popup will get another the clicked time. However, if I set immediate=true, the popup always keep the first clicked time. Only after I set the immediate=false, then use can always get his clicked time on each click. But when setting immediate=false, the popup will validate each required field when use click Cancel, that is very bad. Thanks.
          Hide
          Mark Collette added a comment -

          Sheng Gu: Ok, so do you have an ice:selectInputDate with renderAsPopup="true", or are you making your own popup panel display? Is the cancel button an actual commandButton, or the X button on the calendar popup? You're setting immediate="true" on this cancel commandButton, or on the selectInputDate?

          Show
          Mark Collette added a comment - Sheng Gu: Ok, so do you have an ice:selectInputDate with renderAsPopup="true", or are you making your own popup panel display? Is the cancel button an actual commandButton, or the X button on the calendar popup? You're setting immediate="true" on this cancel commandButton, or on the selectInputDate?
          Hide
          Sheng Gu added a comment -

          Hi Mark, we did not use ice:selectInputDate with renderAsPopup="true" as a popup in our schedule (seven week day columns) page. We have our own popup panel display which shows the clicked time (date and time) as schedule start time, schedule title and schedule interval. There are two ice:commandButton buttons on the popup panel: one is submit button, the other is cancel button. If I set cancel button immediate="true", the schedule start time will always keep the first clicked time, even click cancel then click another time. Only I set cancel button immediate=false, then the schedule time can get lastest clicked time. Thank you.

          Show
          Sheng Gu added a comment - Hi Mark, we did not use ice:selectInputDate with renderAsPopup="true" as a popup in our schedule (seven week day columns) page. We have our own popup panel display which shows the clicked time (date and time) as schedule start time, schedule title and schedule interval. There are two ice:commandButton buttons on the popup panel: one is submit button, the other is cancel button. If I set cancel button immediate="true", the schedule start time will always keep the first clicked time, even click cancel then click another time. Only I set cancel button immediate=false, then the schedule time can get lastest clicked time. Thank you.
          Hide
          Krashan Brahmanjara added a comment -

          For panelPopup users more suitable will be code below.
          Use this when inputs and Cancel button is on the same panelGrid.

          In my case I saw that original recurse function not work correct on panelPopup
          and gives this log :

          1. getForm uicomponent com.icesoft.faces.component.ext.HtmlCommandButton@1866417
          2. getForm uicomponent com.icesoft.faces.component.UIXhtmlComponent@1386211:tag=[div]
          3. getForm uicomponent com.icesoft.faces.component.ext.HtmlPanelGrid@ac2d3c
          4. getForm uicomponent com.icesoft.faces.component.panelpopup.PanelPopup@1cdc190
          5. getForm uicomponent com.icesoft.faces.component.ext.HtmlForm@15ede11
          6. clearSubittedFormValuesRecurse class com.icesoft.faces.component.ext.HtmlForm
          7. clearSubittedFormValuesRecurse class com.icesoft.faces.component.panelpopup.PanelPopup

          That means then ..PanelPopup don't get their childrens.
          So I change UIForm to UIPanel and getting childrens and clearing state work correct

          /**

          • @see clearSubmittedFormValues
          • @param uiComponent
            */
            private static void clearSubittedFormValuesRecurse(UIComponent uiComponent)
            {
            System.out.println("clearSubittedFormValuesRecurse "+uiComponent);
            if (uiComponent instanceof UIInput) { UIInput uiInput = (UIInput) uiComponent; uiInput.setSubmittedValue(null); System.out.println("clearSubittedFormValuesRecurse "+uiInput.getId()); }

            List<?> childList = uiComponent.getChildren();
            if (childList != null)

            Unknown macro: { Iterator<?> iterator = childList.iterator(); while (iterator.hasNext()) { clearSubittedFormValuesRecurse((UIComponent) iterator.next()); } }

            }

          /**

          • Util for clearSubmittedFormValues
          • @see clearSubmittedFormValues
          • @param uiComponent
          • @return
            */
            public static /UIForm/UIPanel getForm(UIComponent uiComponent)
            {
            while (uiComponent != null)
            Unknown macro: { System.out.println("getForm uicomponent"+ uiComponent); if (uiComponent instanceof UIPanel /*UIForm*/) { break; } uiComponent = uiComponent.getParent(); }

            return (/(UIForm)/ (UIPanel) uiComponent);
            }

          Show
          Krashan Brahmanjara added a comment - For panelPopup users more suitable will be code below. Use this when inputs and Cancel button is on the same panelGrid. In my case I saw that original recurse function not work correct on panelPopup and gives this log : getForm uicomponent com.icesoft.faces.component.ext.HtmlCommandButton@1866417 getForm uicomponent com.icesoft.faces.component.UIXhtmlComponent@1386211:tag= [div] getForm uicomponent com.icesoft.faces.component.ext.HtmlPanelGrid@ac2d3c getForm uicomponent com.icesoft.faces.component.panelpopup.PanelPopup@1cdc190 getForm uicomponent com.icesoft.faces.component.ext.HtmlForm@15ede11 clearSubittedFormValuesRecurse class com.icesoft.faces.component.ext.HtmlForm clearSubittedFormValuesRecurse class com.icesoft.faces.component.panelpopup.PanelPopup That means then ..PanelPopup don't get their childrens. So I change UIForm to UIPanel and getting childrens and clearing state work correct /** @see clearSubmittedFormValues @param uiComponent */ private static void clearSubittedFormValuesRecurse(UIComponent uiComponent) { System.out.println("clearSubittedFormValuesRecurse "+uiComponent); if (uiComponent instanceof UIInput) { UIInput uiInput = (UIInput) uiComponent; uiInput.setSubmittedValue(null); System.out.println("clearSubittedFormValuesRecurse "+uiInput.getId()); } List<?> childList = uiComponent.getChildren(); if (childList != null) Unknown macro: { Iterator<?> iterator = childList.iterator(); while (iterator.hasNext()) { clearSubittedFormValuesRecurse((UIComponent) iterator.next()); } } } /** Util for clearSubmittedFormValues @see clearSubmittedFormValues @param uiComponent @return */ public static / UIForm /UIPanel getForm(UIComponent uiComponent) { while (uiComponent != null) Unknown macro: { System.out.println("getForm uicomponent"+ uiComponent); if (uiComponent instanceof UIPanel /*UIForm*/) { break; } uiComponent = uiComponent.getParent(); } return (/ (UIForm) / (UIPanel) uiComponent); }
          Hide
          Ken Fyten added a comment -

          Duplicate of ICE-1741.

          Show
          Ken Fyten added a comment - Duplicate of ICE-1741 .

            People

            • Assignee:
              Unassigned
              Reporter:
              Neil Griffin
            • Votes:
              10 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: