javaserverfaces-spec-public
  1. javaserverfaces-spec-public
  2. JAVASERVERFACES_SPEC_PUBLIC-790

javax.faces.ViewState + PPR does not work out for cross form ppr cases

    Details

    • Type: Bug Bug
    • Status: In Progress
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 2.0
    • Fix Version/s: 2.3
    • Component/s: Ajax/JavaScript
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: Macintosh

    • Issuezilla Id:
      790
    • Status Whiteboard:
      Hide

      size_small importance_small

      Show
      size_small importance_small

      Description

      Following problem

      <h:form id="a">
          <h:commandButton action="#{TestBean.action}" value="submit"/>
      </h:form>
      
      <h:form id="b">
          <h:commandLink value="ajax ReRender" 
              onclick="jsf.ajax.request(this,event,{execute:'b a',render:'a'}); return false;"/>
      </h:form> 
      

      Cannot work out because, the viewstate is returned as separate viewstate block
      (in both implementations the <update id="a"> does not pass the viewState in the
      update block).

      Now the specification says:

      If an update element is found in the response with the identifier
      javax.faces.ViewState:

      <update id="javax.faces.ViewState">
         <![CDATA[...]]>
      </update>
      

      locate and update the submitting form's javax.faces.ViewState value with the
      CDATA contents from the response.

      Which means in this special case that the viewState for form a is lost.
      Mojarra has fixed this to some degree by setting the viewstate if a direct form
      render on a happens.

      However if you do following:

      <h:panelGroup id="myGroup">
          <h:form id="a">
              <h:commandButton action="#{TestBean.action}" value="submit"/>
          </h:form>
      </h:panelGroup>
      
      <h:form id="b">
          <h:commandLink value="ajax ReRender" 
              onclick="jsf.ajax.request(this,event,{execute:'b a',render:'myGroup'}); return false;"/>
      </h:form> 
      

      Mojarra also fails.

      The problem here lies clearly with the spec, I am not sure why the viewstate is
      only updated to the issuing form.

      Either all forms must be updated or at least the forms which are processed both
      within the execute and render parts.

      I also opened a discussion on the open mailing list regarding this, since this is
      a usecase which can happen quite often in a typical rich client scenario where a
      lot of detachments can happen to satisfy ie6 and multiple forms are the norm if
      you have floating frames.

      1. 790-js-workaround.txt
        2 kB
        mdirkse
      2. changebundle.txt
        7 kB
        frederickkaempfer
      3. changebundle.txt
        6 kB
        frederickkaempfer
      4. ExtendedViewHandler.java
        5 kB
        sharath.naik

        Issue Links

          Activity

          Hide
          balusc added a comment - - edited

          As to line 495 of jsf.js, this part is fine. The clientIds[i] or f:ajax render is already namespaced (as it is generated by server). The test case associated with issue 790 would otherwise have failed. Line 2501 of jsf.js contains similar part with ids[i] of f:ajax execute which is also already namespaced. This is only not covered by the unit test yet. I will improve the unit test to make sure it's properly being dealt with.

          Or did you encounter a problem with this in your test application?

          Show
          balusc added a comment - - edited As to line 495 of jsf.js, this part is fine. The clientIds [i] or f:ajax render is already namespaced (as it is generated by server). The test case associated with issue 790 would otherwise have failed. Line 2501 of jsf.js contains similar part with ids [i] of f:ajax execute which is also already namespaced. This is only not covered by the unit test yet. I will improve the unit test to make sure it's properly being dealt with. Or did you encounter a problem with this in your test application?
          Hide
          Neil Griffin added a comment -

          @balusc: In my testing of line 495 using the JS debugger, clientIds[i] is a JavaScript array of length 1 and the value of clientIds[0] is simply 'a' (it is not namespaced). I can provide you with a downloadable Pluto 3 ZIP if you'd like to try it.

          Show
          Neil Griffin added a comment - @balusc: In my testing of line 495 using the JS debugger, clientIds [i] is a JavaScript array of length 1 and the value of clientIds [0] is simply 'a' (it is not namespaced). I can provide you with a downloadable Pluto 3 ZIP if you'd like to try it.
          Hide
          Neil Griffin added a comment -

          Do you think specifying in API is necessary?

          Yes, I think it would be good to add a sentence to ExternalContext#getRequestParameterMap() and ExternalContext#getRequestParameterValuesMap() that says the map's get(String key) method should first try calling getParameter(key) on the underlying request object, but if it returns null, it should try getParameter(namespacePrefix + key). I suppose that ExternalContext. getRequestParameterNames() method should probably return the namespaced version of the key.

          In that case, we could probably remove the explicit requirement to namespace predefined postback parameters as it will then happen "automatically" in request parameter map.

          I think it is good to have the requirement that the namespace prefix be written as part of the name attribute of hidden fields. However, if we added the map requirements I mentioned, then line 204 of RenderKitUtils.java would not need to prepend the namespacePrefix.

          Show
          Neil Griffin added a comment - Do you think specifying in API is necessary? Yes, I think it would be good to add a sentence to ExternalContext#getRequestParameterMap() and ExternalContext#getRequestParameterValuesMap() that says the map's get(String key) method should first try calling getParameter(key) on the underlying request object, but if it returns null, it should try getParameter(namespacePrefix + key) . I suppose that ExternalContext. getRequestParameterNames() method should probably return the namespaced version of the key. In that case, we could probably remove the explicit requirement to namespace predefined postback parameters as it will then happen "automatically" in request parameter map. I think it is good to have the requirement that the namespace prefix be written as part of the name attribute of hidden fields. However, if we added the map requirements I mentioned, then line 204 of RenderKitUtils.java would not need to prepend the namespacePrefix.
          Hide
          balusc added a comment -

          In my testing of line 495 using the JS debugger, clientIds[i] is a JavaScript array of length 1 and the value of clientIds[0] is simply 'a' (it is not namespaced). I can provide you with a downloadable Pluto 3 ZIP if you'd like to try it.

          Is the portlet rendering non-namespaced client IDs? This is confusing. I'd like to see the ZIP and try it, yes.

          I think it is good to have the requirement that the namespace prefix be written as part of the name attribute of hidden fields. However, if we added the map requirements I mentioned, then line 204 of RenderKitUtils.java would not need to prepend the namespacePrefix.

          I'd prefer consistency over convenience. Otherwise things will be too confusing in long term. If the UIViewRoot is an instance of NamingContainer, it's expected that its ID is prefixed over all place.

          Show
          balusc added a comment - In my testing of line 495 using the JS debugger, clientIds [i] is a JavaScript array of length 1 and the value of clientIds [0] is simply 'a' (it is not namespaced). I can provide you with a downloadable Pluto 3 ZIP if you'd like to try it. Is the portlet rendering non-namespaced client IDs? This is confusing. I'd like to see the ZIP and try it, yes. I think it is good to have the requirement that the namespace prefix be written as part of the name attribute of hidden fields. However, if we added the map requirements I mentioned, then line 204 of RenderKitUtils.java would not need to prepend the namespacePrefix. I'd prefer consistency over convenience. Otherwise things will be too confusing in long term. If the UIViewRoot is an instance of NamingContainer, it's expected that its ID is prefixed over all place.
          Hide
          balusc added a comment - - edited

          While working on https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1372 I think I discovered your problem: invalid client IDs in f:ajax execute/render are not namespaced. I could reproduce it when replacing e.g. render="validClientId" by render="thisDoesNotExist". Can you please reverify?

          Show
          balusc added a comment - - edited While working on https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1372 I think I discovered your problem: invalid client IDs in f:ajax execute/render are not namespaced. I could reproduce it when replacing e.g. render="validClientId" by render="thisDoesNotExist" . Can you please reverify?

            People

            • Assignee:
              balusc
              Reporter:
              werpu12
            • Votes:
              59 Vote for this issue
              Watchers:
              43 Start watching this issue

              Dates

              • Created:
                Updated:

                Time Tracking

                Estimated:
                Original Estimate - 5 days
                5d
                Remaining:
                Remaining Estimate - 5 days
                5d
                Logged:
                Time Spent - Not Specified
                Not Specified