ICEfaces
  1. ICEfaces
  2. ICE-5569

ICEfaces 2.0 singleSubmit causing full-page refresh

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-Alpha2
    • Fix Version/s: 2.0-Alpha3, 2.0.0
    • Component/s: Bridge
    • Labels:
      None
    • Environment:
      ICEfaces 2.0

      Description

      singleSubmit is causing a full-page refresh to occur.
      1. calendar4.xhtml
        3 kB
        Ted Goddard
      2. CalendarBean.java
        3 kB
        Ted Goddard

        Activity

        Hide
        Ted Goddard added a comment -

        Problem is reproducible with attached files added to auction demo.

        Show
        Ted Goddard added a comment - Problem is reproducible with attached files added to auction demo.
        Hide
        Ted Goddard added a comment -

        ViewState in JSF form hidden field and ice.configuration differ in the page:

        <script type='text/javascript'>ice.captureSubmit('j_idt6');</script><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="5256389288760608598:-3531654199962047715" autocomplete="off" />
        </form></span>
        <script id='j_id5' type="text/javascript">ice.configuration =

        {deltaSubmit: false}

        ;window.ice.window = 'evg7fbz54j';document.getElementById('j_id5').parentNode.javax_faces_ViewState='4881237712531586916:-1657428998648249768';</script><script type="text/javascript">ice.push.register(['4881237712531586916:-1657428998648249768'], ice.retrieveUpdate('4881237712531586916:-1657428998648249768'));ice.push.register(['evg7fbz54j:se'], ice.sessionExpired);</script></body>

        The singleSubmit POST is made using the ViewState stored by ice.configuration rather than the form hidden field:

        POST /auction/calendar4.jsf HTTP/1.1

        javax.faces.source=j_idt6%3A_t13&javax.faces.partial.event=change&javax.faces.partial.execute=j_idt6%3A_t13&javax.faces.partial.render=%40all&ice.window=evg7fbz54j&javax.faces.ViewState=4881237712531586916%3A-1657428998648249768&ice.event.target=j_idt6%3A_t13&ice.event.captured=j_idt6%3A_t13&ice.event.type=onchange&javax.faces.partial.ajax=trueHTTP/1.1 200 OK

        Show
        Ted Goddard added a comment - ViewState in JSF form hidden field and ice.configuration differ in the page: <script type='text/javascript'>ice.captureSubmit('j_idt6');</script><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="5256389288760608598:-3531654199962047715" autocomplete="off" /> </form></span> <script id='j_id5' type="text/javascript">ice.configuration = {deltaSubmit: false} ;window.ice.window = 'evg7fbz54j';document.getElementById('j_id5').parentNode.javax_faces_ViewState='4881237712531586916:-1657428998648249768';</script><script type="text/javascript">ice.push.register( ['4881237712531586916:-1657428998648249768'] , ice.retrieveUpdate('4881237712531586916:-1657428998648249768'));ice.push.register( ['evg7fbz54j:se'] , ice.sessionExpired);</script></body> The singleSubmit POST is made using the ViewState stored by ice.configuration rather than the form hidden field: POST /auction/calendar4.jsf HTTP/1.1 javax.faces.source=j_idt6%3A_t13&javax.faces.partial.event=change&javax.faces.partial.execute=j_idt6%3A_t13&javax.faces.partial.render=%40all&ice.window=evg7fbz54j&javax.faces.ViewState=4881237712531586916%3A-1657428998648249768&ice.event.target=j_idt6%3A_t13&ice.event.captured=j_idt6%3A_t13&ice.event.type=onchange&javax.faces.partial.ajax=trueHTTP/1.1 200 OK
        Hide
        Ted Goddard added a comment -

        This looks like the root of the problem is with obtaining the same ViewState as JSF associates with the page.

        Show
        Ted Goddard added a comment - This looks like the root of the problem is with obtaining the same ViewState as JSF associates with the page.
        Hide
        Mircea Toma added a comment - - edited

        It seems that every time StateManager.getViewState() is invoked the method will return a different key. The key will be associated with the saved state of the component tree at the moment of invocation.

        When the page loads the first time StateManager.getViewState is called once by com.sun.faces.application.view.WriteBehindStateWriter which generate one view state key (and associated state) that is used by the hidden input element of the form. Then BridgeSetup invokes StateManager.getViewState generating a second view state key and associated state.
        ice.singleSubmit will use the view state key generated by the BridgeSetup but because StateManager.getViewState was invoked before all of the resource components are added to the UIViewRoot the state represented by the key would not include the state of the remaining resource components. Thus when ice.singleSubmit is used the restored state of the tree will be different (missing resource components) and as a direct result the DOM diff will generate an update for the <html> element which in turn will generate a page reload.

        To solution used was to avoid relying on the state manager for restoring the resource components. The marker on the UIViewRoot is not used anymore because its state is not saved along with the state of the component tree. All component resources are made transient and added before every render pass. Adding component resources before every render pass is a much simpler solution than using the state manager with additional logic needed for checking what components remain to be added and what components should not be added to avoid duplicates. By doing this the components resources will generate the same markup on each render pass (without generating updates for <html> element).

        ice.submit and ice.retrieveUpdate functions were changed as well to use the view state key generated by BridgeSetup effectively making all the parts of the bridge and core use the same view state key.

        Show
        Mircea Toma added a comment - - edited It seems that every time StateManager.getViewState() is invoked the method will return a different key. The key will be associated with the saved state of the component tree at the moment of invocation. When the page loads the first time StateManager.getViewState is called once by com.sun.faces.application.view.WriteBehindStateWriter which generate one view state key (and associated state) that is used by the hidden input element of the form. Then BridgeSetup invokes StateManager.getViewState generating a second view state key and associated state. ice.singleSubmit will use the view state key generated by the BridgeSetup but because StateManager.getViewState was invoked before all of the resource components are added to the UIViewRoot the state represented by the key would not include the state of the remaining resource components. Thus when ice.singleSubmit is used the restored state of the tree will be different (missing resource components) and as a direct result the DOM diff will generate an update for the <html> element which in turn will generate a page reload. To solution used was to avoid relying on the state manager for restoring the resource components. The marker on the UIViewRoot is not used anymore because its state is not saved along with the state of the component tree. All component resources are made transient and added before every render pass. Adding component resources before every render pass is a much simpler solution than using the state manager with additional logic needed for checking what components remain to be added and what components should not be added to avoid duplicates. By doing this the components resources will generate the same markup on each render pass (without generating updates for <html> element). ice.submit and ice.retrieveUpdate functions were changed as well to use the view state key generated by BridgeSetup effectively making all the parts of the bridge and core use the same view state key.
        Hide
        Ted Goddard added a comment -

        setTransient is a good idea in general since the resource components do not have any useful state. I was hopeful that this would resolve ICE-5157, but it does not appear to.

        Perhaps a similar fix should be applied to ExtrasSetup in compat.

        Show
        Ted Goddard added a comment - setTransient is a good idea in general since the resource components do not have any useful state. I was hopeful that this would resolve ICE-5157 , but it does not appear to. Perhaps a similar fix should be applied to ExtrasSetup in compat.
        Hide
        Mircea Toma added a comment -

        Changed also ExtrasSetup to use transient resource components.

        Show
        Mircea Toma added a comment - Changed also ExtrasSetup to use transient resource components.

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Ted Goddard
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: