5 Replies Latest reply on Oct 26, 2015 6:31 AM by michpetrov

    mediaOutput only renders once?

    arnieaustin

      Consider the markup below. The photo is stored as a blob. Using the imageLoader class from the RF photo library demo as a template, I simplified the code to output the bytes to the browser and the photo appears if the field is not null. The command link to empty the field also works at the DB level and the place holder graphic appears instead of the media output.

       

      So the outputPanel is rendering as expected. But the mediaOutput is being invoked only when the page is initially rendered. I know this due to logging in the imageLoader class (called only once). If I pick a different photo, the mediaOutput appears, the place holder vanishes, but it is the original photo, not the new one.

       

      I would have thought render="photoPerson" on one of the two (fileUpload or the uploadcomplete event) below would have forced it to regenerate, but alas no.

       

      Putting imageLoader into the Conversation scope from Request didn't help either.

       

      How does one get it to regenerate the graphic? Or is it something else? Like the URI of the photo resource not being updated in the browser resulting in the updated graphic not being downloaded?

       

      <rich:panel style="vertical-align:top;">

          <f:facet name="header"><h:outputFormat value="#{messages.getString('infoPersonEdit.name.label.photoFacet')}" /></f:facet>

          <a4j:outputPanel id="panelInfoPersonPhoto" ajaxRendered="true" >

         

              <h:panelGrid columns="1" columnClasses="table-column-center" >

             

                  <a4j:mediaOutput id="photoPerson" element="img" createContent="#{imageLoader.paintImage}"

                      value="#{infoPersonDTOCDI.id}" style="width:200px;height:200px;"

                      rendered="#{not empty infoPersonDTOCDI.photo}"

                      title="#{infoPersonDTOCDI.nameFirst} #{infoPersonDTOCDI.nameLast}" />

                 

                  <h:graphicImage library="images" name="man-icon.gif" 

                      rendered="#{empty infoPersonDTOCDI.photo}" style="width:200px;height:200px;"

                      title="#{messages.getString('infoPersonEdit.name.label.noPhotoTitle')}" />

                     

                  <a4j:commandLink value="#{messages.getString('infoPersonEdit.name.label.clearPhoto')}"

                      rendered="#{!empty infoPersonDTOCDI.photo}" execute="@this"

                      render="panelInfoPersonPhoto"

                      status="statusInProgress"

                      actionListener="#{infoPersonEdit.clearPhotoListener}"

                  />

                     

                  <rich:fileUpload id="uploadPhoto" fileUploadListener="#{infoPersonEdit.photoUploadListener}"

                      immediateUpload="true" acceptedTypes=".jpg, .gif, .png"

                      maxFilesQuantity="1" maxFileSize="500000"

                      listHeight="0" status="statusInProgress" execute="@this" render="panelInfoPersonPhoto"

                      rendered="#{not empty infoPersonDTOCDI.id and !infoPersonDTOCDI.inactive and !infoPersonDTOEdit.readOnly}"

                      ontyperejected="alert('#{messages.getString('infoPersonEdit.name.label.invalidPhoto')}');"

                      >

                      <a4j:ajax event="uploadcomplete" execute="@this" render="panelInfoPersonPhoto" />

                  </rich:fileUpload>

                 

              </h:panelGrid>

       

          </a4j:outputPanel>

      </rich:panel>

        • 1. Re: mediaOutput only renders once?
          michpetrov

          The target for @render shouldn't be a conditionally rendered element. Rerendering works by replacing the original element with a new one, if there is no element to begin with it cannot be replaced. Wrap the medioOutput in another element and rerender that.

          • 2. Re: mediaOutput only renders once?
            arnieaustin

            I'm lost. Wrap it in what? It is already in an outputPanel. Would an a4j:region be helpful?

             

            I removed the graphicImage and altered the imageLoader to return the data for the place holder graphic if a photo isn't assigned to the user.

             

            But the mediaOutput doesn't re-render after the upload and assignment (or removal) of the blob (the panel does though).

             

            Also, here's another question. This code returns null:

             

            inputStream = this.getClass().getClassLoader().getResourceAsStream(MAN_ICON);

             

            returns null unless the file in question is in the WEB-INF/classes folder. It is already in the <war>/resources/images folder but isn't found there. Why? And can I access the RF resource loader to access it instead?

            • 3. Re: mediaOutput only renders once?
              arnieaustin

              Ok, found this and it works:

               

                 ResourceHandler rh = facesContext.getApplication().getResourceHandler();
                 Resource resource = rh.createResource(MAN_ICON, "images");
                 inputStream = resource.getInputStream();

               

              Now, how to get mediaOutput to re-generate the graphic - or the browser to ask for the file again.

              • 4. Re: mediaOutput only renders once?
                arnieaustin

                Ugh, this turned out to the answer:

                 

                <a4j:mediaOutput id="photoPerson" element="img" createContent="#{imageLoader.paintImage}"

                    value="#{infoPersonDTOCDI.id}" style="width:200px;height:200px;" cacheable="false"

                    title="#{infoPersonDTOCDI.nameFirst} #{infoPersonDTOCDI.nameLast}" >

                    <f:param value="#{imageLoader.timeStamp}" name="time" />

                </a4j:mediaOutput>

                 

                always returning the current time and the expiration for the picture was the crucial item.

                 

                Why isn't that discussed in the documentation?

                • 5. Re: mediaOutput only renders once?
                  michpetrov

                  That's weird, the example I tried works without setting the timestamp. I'll check the code.