2 Replies Latest reply on Sep 14, 2010 10:13 PM by mkienenb

    Component outside of a4j:region silently ignored when listed in process attribute

    mkienenb

      I am using richfaces 3.3.3 Final, Facelets, and Myfaces 1.2.9.

       

      I am trying to replace non-ajax pages originally written using Tomahawk subforms with a4j:support and a4j:region components.

       

      The biggest rewrite issue is that due to strange layout requirements, inputs and buttons are not next to each other, and other buttons and inputs are interspersed between them.

       

      The process attribute, combined with ajaxSingle, allows me to choose which elements should be combined for a submit by a particular button.

       

      However, tracing through the code, it appears that once the ajax submit is processed, only components contained by the ajax region are check aganist the names of the components listed in the process attribute.

       

      I wrote a simple example which appears to demonstrate this as well.  The heart of it is below.  I didn't expect the changes to make any difference, but I also tried with ":form:outsideRegionInput" and "form:outsideRegionInput" in case my understanding of the code was flawed.

       

      In each case, outsideRegionInput is always null while insideRegionInput always contains the submitted value.

       

               <h:outputText value="outsideRegionInput:"/>
                  <h:inputText id="outsideRegionInput"
                          value="#{bean.outsideRegionValue}">
                  </h:inputText>
         
                <a4j:region id="regionId">
                
                  <h:outputLabel for="insideRegionInput"
                      value="insideRegionInput:"/>
                  <h:inputText id="insideRegionInput"
                          value="#{bean.insideRegionValue}">
                  </h:inputText>
                     
                  <h:commandButton
                      value="Test">

       

                      <a4j:support
                          event="onclick"
                          ajaxSingle="true"
                             disableDefault="true"
                          action="#{bean.testProcessOutsideRegion}"
                          process="insideRegionInput,outsideRegionInput"
                          />

       

                  </h:commandButton>
             
                </a4j:region>

       

      I suppose one workaround would be to remove all of the a4j:region objects from my page and explicitly list out the components used by every button.  However, the real page is very complex, with many buttons and many inputs.  Most of the time, a region does exactly what I want because the input and button layout matches the submitted values.   I would be forced to list out dozens of components for dozens of buttons.

       

      It seems to me that the right solution is for UIAjaxRegion.processDecodes(FacesContext) to try to find the component at the root level if it cannot be found as a child of the region.  Or at minimum, if the component name begins with ":" to search for the component at the root level to start with.  Right now, it only invokes the processing, validation, updating, etc, on children, silently ignoring whether a valid match is found by invokeOnComponent().

       

      public void processDecodes(FacesContext context) {
      [...]
              if (ajaxContext.isAjaxRequest() && null != ajaxSingleClientId) {
                  invokeOnComponent(context, ajaxSingleClientId, new ContextCallbackWrapper(decodeCallback));
                  Set<String> areasToProcess = ajaxContext.getAjaxAreasToProcess();
                  if(null != areasToProcess){
                      for (String areaId : areasToProcess) {
                          invokeOnComponent(context, areaId, new ContextCallbackWrapper(decodeCallback));
                      }
                  }
              } else {

      [...]
          }

       

      I can attach my example project (or more parts of it) upon request.

       

      As a side note, setting up this example also revealed another bug.  I had accidentally used "regionId" instead of "insideRegionInput" in my first draft.   This caused a Stack Overflow error, as each time the a4j:region evaluated the process attribute values, it would find itself and call itself again.

       

       

      The debug log looks like this, but all it proves is that the value is submitted:

       

      debug[20:16:56,470]: Have Event [object Object] with properties: target: [object HTMLInputElement], srcElement: undefined, type: click
      debug[20:16:56,470]: Query preparation for form 'form' requested
      debug[20:16:56,471]: Append text control form:outsideRegionInput with value [outside] and value attribute []
      debug[20:16:56,471]: Append text control form:insideRegionInput with value [inside] and value attribute []
      debug[20:16:56,471]: Append hidden control form_SUBMIT with value [1] and value attribute [1]
      debug[20:16:56,472]: Append hidden control javax.faces.ViewState with value [9JgUKANlia8gDSeJJ6dfgYtl3C3vAXPnXVlCITj3uBAVO9vrRAoUkVsv8ULhBxNNTvDVE4Pphmk7  O7ooKRKt/y4QpZQARrx6boHv8DUqhR4RFKVyjVc7TwISnPsLyKN0z6ma0jy5PlJfQKlGgNEEsMzA  B8A= ] and value attribute [9JgUKANlia8gDSeJJ6dfgYtl3C3vAXPnXVlCITj3uBAVO9vrRAoUkVsv8ULhBxNNTvDVE4Pphmk7  O7ooKRKt/y4QpZQARrx6boHv8DUqhR4RFKVyjVc7TwISnPsLyKN0z6ma0jy5PlJfQKlGgNEEsMzA  B8A= ]
      debug[20:16:56,472]: parameter form:j_id7 with value form:j_id7
      debug[20:16:56,472]: parameter ajaxSingle with value form:j_id6
      debug[20:16:56,472]: Look up queue with default name
      debug[20:16:56,473]: NEW AJAX REQUEST !!! with form: form
      debug[20:16:56,473]: Start XmlHttpRequest
      debug[20:16:56,475]: Request state : 1
      debug[20:16:56,475]: QueryString: AJAXREQUEST=form%3AregionId&form%3AoutsideRegionInput=outside&form%3AinsideRegionInput=inside&form_SUBMIT=1&javax.faces.ViewState=9JgUKANlia8gDSeJJ6dfgYtl3C3vAXPnXVlCITj3uBAVO9vrRAoUkVsv8ULhBxNNTvDVE4Pphmk7%0D%0AO7ooKRKt%2Fy4QpZQARrx6boHv8DUqhR4RFKVyjVc7TwISnPsLyKN0z6ma0jy5PlJfQKlGgNEEsMzA%0D%0AB8A%3D%0D%0A&form%3Aj_id7=form%3Aj_id7&ajaxSingle=form%3Aj_id6&
      debug[20:16:56,480]: Request state : 1
      debug[20:17:17,823]: Request state : 2
      debug[20:17:17,824]: Request state : 3
      debug[20:17:17,824]: Request state : 4
      debug[20:17:17,824]: Request end with state 4
      debug[20:17:17,824]: Response  with content-type: text/xml; charset=utf-8
      debug[20:17:17,825]: Full response content: <?xml version="1.0"?> <html lang="en_US" xmlns="http://www.w3.org/1999/xhtml"><head><title></title><script src="/SimpleRichFacesProject/faces/a4j/g/3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript" type="text/javascript"> </script></head><body><span id="form:j_id2"><ul><li>outsideRegionValue is null</li></ul></span><meta name="Ajax-Update-Ids" content="form:j_id2" /><span id="ajax-view-state"><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="9JgUKANlia8gDSeJJ6dfgYtl3C3vAXPnXVlCITj3uBAVO9vrRAoUkVsv8ULhBxNNTvDVE4Pphmk7 O7ooKRKt/y4QpZQARrx6boHv8DUqhR4RFKVyjVc7TwISnPsLyKN0z6ma0jy5PlJfQKlGgNEEsMzA B8A= " /></span><meta id="Ajax-Response" name="Ajax-Response" content="true" /><meta name="Ajax-Update-Ids" content="form:j_id2" /><span id="ajax-view-state"><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="9JgUKANlia8gDSeJJ6dfgYtl3C3vAXPnXVlCITj3uBAVO9vrRAoUkVsv8ULhBxNNTvDVE4Pphmk7 O7ooKRKt/y4QpZQARrx6boHv8DUqhR4RFKVyjVc7TwISnPsLyKN0z6ma0jy5PlJfQKlGgNEEsMzA B8A= " /></span><meta id="Ajax-Response" name="Ajax-Response" content="true" /></body></html>
      debug[20:17:17,826]: Header Ajax-Expired not found, search in <meta>
      debug[20:17:17,826]: search for elements by name 'meta'  in element #document
      debug[20:17:17,827]: Find <meta name='Ajax-Update-Ids' content='form:j_id2'>
      debug[20:17:17,827]: Find <meta name='Ajax-Response' content='true'>
      debug[20:17:17,827]: Find <meta name='Ajax-Update-Ids' content='form:j_id2'>
      debug[20:17:17,827]: Find <meta name='Ajax-Response' content='true'>
      debug[20:17:17,828]: Header Ajax-Update-Ids not found, search in <meta>
      debug[20:17:17,828]: search for elements by name 'meta'  in element #document
      debug[20:17:17,828]: Find <meta name='Ajax-Update-Ids' content='form:j_id2'>
      debug[20:17:17,828]: Update page by list of rendered areas from response form:j_id2
      debug[20:17:17,828]: search for elements by name 'script'  in element #document
      debug[20:17:17,829]: <script> in response with src=/SimpleRichFacesProject/faces/a4j/g/3_3_3.Finalorg.ajax4jsf.javascript.AjaxScript
      debug[20:17:17,829]: Such element exist in document
      debug[20:17:17,829]: search for elements by name 'link'  in element #document
      debug[20:17:17,829]: call getElementById for id= org.ajax4jsf.queue_script
      debug[20:17:17,829]: Update page part from call parameter for ID form:j_id2
      debug[20:17:17,830]: call getElementById for id= form:j_id2
      debug[20:17:17,830]: Replace content of node by replaceChild()
      debug[20:17:17,830]: search for elements by name 'script'  in element span
      debug[20:17:17,830]: Scripts in updated part count : 0
      debug[20:17:17,831]: call getElementById for id= org.ajax4jsf.oncomplete
      debug[20:17:17,831]: Processing updates finished, no oncomplete function to call
      debug[20:17:17,831]: Update part of page for Id: form:j_id2 successful
      debug[20:17:17,831]: call getElementById for id= ajax-view-state
      debug[20:17:17,831]: Hidden JSF state fields: [object HTMLSpanElement]
      debug[20:17:17,831]: Namespace for hidden view-state input fields is undefined
      debug[20:17:17,832]: search for elements by name 'input'  in element span
      debug[20:17:17,832]: Replace value for inputs: 5 by new values: 1
      debug[20:17:17,832]: Input in response: javax.faces.ViewState
      debug[20:17:17,832]: Found same input on page with type: hidden
      debug[20:17:17,833]: search for elements by name 'INPUT'  in element span
      debug[20:17:17,833]: Replace value for inputs: 5 by new values: 0
      debug[20:17:17,833]: call getElementById for id= _A4J.AJAX.focus
      debug[20:17:17,833]: No focus information in response