Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 4.5.7
    • Fix Version/s: 4.5-Tracking
    • Component/s: None
    • Labels:
      None
    • Steps to Reproduce:
      Hide
         <h:form enctype="multipart/form-data">
              rich:ajax on upload button (<strong>broken</strong>)
              <h:inputFile
                  id="file"
                  value="#{uploadBean.file}">
      
              </h:inputFile>
      
              <h:commandButton
                  value="Upload"
                  action="#{uploadBean.upload}">
                  <a4j:ajax
                      listener="#{uploadBean.upload}"
                      execute="@all" />
              </h:commandButton>
      
          </h:form>
      
      Show
      <h:form enctype= "multipart/form-data" > rich:ajax on upload button (<strong>broken</strong>) <h:inputFile id= "file" value= "#{uploadBean.file}" > </h:inputFile> <h:commandButton value= "Upload" action= "#{uploadBean.upload}" > <a4j:ajax listener= "#{uploadBean.upload}" execute= "@all" /> </h:commandButton> </h:form>

      Description

      JSF 2.2.12 included a fix for file inputs and ajax.

      https://java.net/jira/browse/JAVASERVERFACES-3984
      Patch:
      https://java.net/jira/secure/attachment/55010/JAVASERVERFACES-3976.patch
      jsf.js:

                     // check the execute ids to see if any include an input of type "file"
                      context.includesInputFile = false;
                      var ids = options.execute.split(" ");
                      if (ids == "@all") { ids = [ form.id ]; }
                      if (ids) {
                          for (i = 0; i < ids.length; i++) {
                              var elem = document.getElementById(ids[i]);
                              if (elem) {
                                  var nodeType = elem.nodeType;
                                  if (nodeType == Node.ELEMENT_NODE) {
                                      var elemAttributeDetector = detectAttributes(elem);
                                      if (elemAttributeDetector("type")) {
                                          if (elem.getAttribute("type") === "file") {
                                              context.includesInputFile = true;
                                              break;
                                          }
                                      } else {
                                          if (hasInputFileControl(elem)) {
                                              context.includesInputFile = true;
                                              break;
                                          }
                                      }
                                  }
                              }
                          }
                      }
      

      Basically they are now checking all the values passed to a execute="" and seeing if any are "input type="file". If one of the elements in the execute is a file then it will use the file upload transfer iframe (and set the proper enctype). If none of the elements contains a file input then it wil use a regular form submission with a regular encoding type (!= multipart/form-data)

      The problem with a4j:rich is that the execute value when inside javascript contains a "@component" which jsf does not understand (and can't determine that it's a file upload).

      For example. The following xhtml:

         <h:form enctype="multipart/form-data">
              rich:ajax on upload button (<strong>broken</strong>)
              <h:inputFile  id="file"  value="#{uploadBean.file}" />
      
              <h:commandButton
                  value="Upload"
                  action="#{uploadBean.upload}">
                  <a4j:ajax
                      listener="#{uploadBean.upload}"
                      execute="@all" />
              </h:commandButton>
          </h:form>
      

      When a file is selected and the command button is clicked an exception is thrown: UT010016: Not a multi part request

      Stepping through jsf.js, you'll eventually see that ids equals:

      ids = ["j_idt20:j_idt22", "@component"],
      

      (j_idt20:j_idt22 is the h:commandButton)

      Jsf then tries to lookup up @component using document.getElementById but obviously can't find it and then doesn't think the execute requires a multipart/form-data upload.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                gabboflabbo Andrew Schmidt
              • Votes:
                3 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated: