2 Replies Latest reply on Jul 31, 2008 10:36 AM by dragonfly0806

    a4j:jsFunction reRender with a4j:repeat and rich:fileUpload

    dragonfly0806

      Hello, I am having trouble rerendering a component inside of an a4j:repeat with an a4j:jsFunction. Please take a look at the onComplete#{int} jsFunction near the bottom of the code snippet. The oncomplete method runs and resolves to the correct clientId, but the reRender does not occur. Also, I can successfully reRender the container div for the a4j:repeat element, and I can successfully reRender the photoContainer block if there is only one element in the repeat list. Is there an interaction between these components that I am missing?

      Thanks in advance.

       <t:div id="photoUploadWrapper">
      
       <a4j:repeat id="photoUploadDataList" var="url" rowKeyVar="int" first="0" value="#{photoListBean.photoList}">
       <t:div id="photoOuterContainer"
       styleClass="#{int == 0 and photoListBean.hasPrimary ? 'photo-outer-selected' : 'photo-outer'}">
      
      
       <t:div id="photoContainer" styleClass="photo">
       <!-- DEBUG --><h:outputText value="renderCount: #{photoListBean.renderCount}" rendered="false"/>
      
       <t:div id="primary-photo-lable" styleClass="primaryPhotoLabel" rendered="#{int == 0 and photoListBean.hasPrimary}">
       Primary Photo<a href="javascript:" onclick="showPrimaryPhotoPopup()"><img src="img/photo_upload/primary_photo_help_image.gif"/></a>
       </t:div>
      
       <h:form id="uploadInProgress" style="display:none">
       <h:graphicImage value="/img/photo_upload/loading.gif"/>
       <a4j:commandLink
       id="cancelLink"
       styleClass="cancel"
       value="Cancel"
       onclick="if (!confirm('Are you sure you want to cancel this upload?')) return false;">
       <rich:componentControl for="photoUploadDataList:#{int}:photoForm:fileUploadComponent" operation="stop" event="onclick"/>
       </a4j:commandLink>
       <t:div styleClass="instructions">
       <h:outputText value="For best results, limit your photo size to 150K"/>
       </t:div>
       </h:form>
       <a4j:form id="photoForm">
      
       <!-- PHOTO EXISTS AT THIS INDEX -->
       <t:div rendered="#{!empty url}">
       <a4j:commandLink
       action="#{photoListBean.movePhoto(int, 0)}"
       reRender="photoUploadGrid"
       styleClass="set-as-primary"
       rendered="#{int > 0 and photoListBean.hasPrimary}"><h:outputText value="Set as primary"/></a4j:commandLink>
       <a4j:commandLink
       action="#{photoListBean.removePhoto(int)}"
       reRender="photoUploadGrid"
       styleClass="delete-icon"
       onclick="if (!confirm('Are you sure you want to delete this photo?')) return false;">
       <h:graphicImage value="img/photo_upload/delete_icon.gif" />
       </a4j:commandLink>
       <h:graphicImage id="photo" styleClass="photo" value="#{url}" onload="new PhotoHeightCorrector().correctPhoto(this, 90)"/>
       </t:div>
       </a4j:form>
      
       </t:div>
      
       <!-- PHOTO DOES *NOT* EXIST AT THIS INDEX -->
       <t:div id="fileUploadDiv" styleClass="file-upload" rendered="#{empty url}">
       <a4j:form>
       <t:div id="browseButton" styleClass="browse-button">
       <!-- ATTENTION! Don't change the width of the component to less than 122px. It will cause an IE bug! -->
       <rich:fileUpload
       id="fileUploadComponent"
       listHeight="0px"
       listWidth="122px"
       addButtonClass="addButtonClass"
       addControlLabel=""
       clearAllControlLabel=""
       stopControlLabel=""
       stopEntryControlLabel=""
       fileUploadListener="#{photoListBean.fileUploaded}"
       immediateUpload="true"
       maxFilesQuantity="1"
       onsizerejected="alert('Please upload an image that is #{photoListBean.maxImageSizeInMB}MB or less.');"
       ontyperejected="alert('Please upload an image of the following types: #{photoListBean.acceptedTypes}');"
       onuploadcomplete="onComplete#{int}()"
       acceptedTypes="#{photoListBean.acceptedTypes}"
       onupload="document.getElementById('#{rich:clientId('uploadInProgress')}').style.display = '';"
       >
       </rich:fileUpload>
       </t:div>
       </a4j:form>
       </t:div>
      
       </t:div>
      
       <h:form>
       <a4j:jsFunction name="onComplete#{int}" reRender="#{rich:clientId('photoContainer')}" oncomplete="alert('#{rich:clientId('photoContainer')}')"/>
       </h:form>
      
       </a4j:repeat>
       </t:div>
      



        • 1. Re: a4j:jsFunction reRender with a4j:repeat and rich:fileUpl

          Hi,
          Try to use 'ajaxKeys' attribute. It defines the row number to be rerendered after AJAX submit.

          There are steps to modify your code to fire it:

          1. Add 'ajaxKeys' attribute:

          <a4j:repeat ... rowKeyVar="int" ajaxKeys="#{photoListBean.keys}" ....>


          2. Modify a4j:function:
          <a4j:jsFunction name="onComplete#{int}" reRender="photoContainer"
          actionListener="#{photoListBean.listener}"
          oncomplete="alert('#{rich:clientId('photoContainer')}')">
          <a4j:actionparam name="row" value="#{int}"></a4j:actionparam>
          </a4j:jsFunction>
          


          3. Add keys property to bean:
          Set keys = new HashSet();


          4. Specify action listener that should set up row index to rerender:

          public void listener(ActionEvent event) {
           FacesContext context = FacesContext.getCurrentInstance();
           Map<String, String> params = context.getExternalContext().getRequestParameterMap();
           String row = params.get("row");
           Integer r = Integer.parseInt(row);
           keys.clear();
           keys.add(r);
           }
          



          ..........


          This is a simple example how you can manage row to be rerendered after AJAX submit.

          • 2. Re: a4j:jsFunction reRender with a4j:repeat and rich:fileUpl
            dragonfly0806

            That worked like a charm! Thanks for your detailed explanation. It was difficult to understand what the ajaxKeys attribute was for without a detailed example.