0 Replies Latest reply on Jan 14, 2009 12:00 AM by sandman202

    Refreshing a Listing on an Edit Screen

    sandman202

      Using Richfaces 3.2.2, Seam 2.1.1, JBoss 4.2.3 and MySQL. The Listing, detail and edit screens are like those described in the seam in action.


      I have an edit screen called InFilesEdit.xhtml which I use to validate and post an imported file. In This case, it is a collection of city-state-zip records. The importing, validation and posting is working fine. The problem I am having is once I validate or post the records, the listing of city-state-zip records does not get refreshed.


      I have tried using an event/observer and afterTransactionSuccess, but it does not seem to refresh the tab.


      InFileEdit.xhtml


      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                      xmlns:s="http://jboss.com/products/seam/taglib"
                      xmlns:ui="http://java.sun.com/jsf/facelets"
                      xmlns:f="http://java.sun.com/jsf/core"
                      xmlns:h="http://java.sun.com/jsf/html"
                      xmlns:a="http://richfaces.org/a4j"
                      xmlns:rich="http://richfaces.org/rich"
                      template="/layout/template.xhtml">
                             
      <ui:define name="body">
              
          <h:form id="inFilesForm" styleClass="edit" enctype="multipart/form-data">
          
              <rich:panel>
                  <f:facet name="header">#{inFilesHome.managed ? 'Edit' : 'Add'} InFiles</f:facet>                   
                   
                  <s:decorate id="nameDecoration" template="/layout/display.xhtml">
                      <ui:define name="label">Name</ui:define>
                          <h:inputTextarea id="name"
                                     cols="80"
                                     rows="3"
                                 disabled="true"
                                    value="#{inFilesHome.instance.name}"/>
                  </s:decorate>                      
                  
                   <s:decorate id="typeDecoration" template="/layout/edit.xhtml">
                      <ui:define name="label">Type</ui:define>               
                        <h:selectOneMenu id="inFilesType"
                                   styleClass="selectOneMenu"
                                          value="#{inFilesHome.instance.type}"  
                                     disabled="true">
                             <s:selectItems value="#{inFilesHome.inFileTypes}" var="inFilesType" label="#{inFilesType.value}" 
                                               noSelectionLabel=""/>
                             <s:convertEnum />
                        </h:selectOneMenu>
                   </s:decorate>
                                
                   <s:decorate id="statusDecoration" template="/layout/edit.xhtml">
                      <ui:define name="label">Status</ui:define>               
                        <h:selectOneMenu id="inFilesStatus"
                                   styleClass="selectOneMenu"
                                          value="#{inFilesHome.instance.status}"  
                                     disabled="true">
                             <s:selectItems value="#{inFilesHome.inFileStatuses}" var="inFilesStatus" label="#{inFilesStatus.value}" 
                                               noSelectionLabel=""/>
                             <s:convertEnum />
                        </h:selectOneMenu>
                   </s:decorate>
                  
                   <s:decorate id="createdOnDecoration" template="/layout/display.xhtml">
                          <ui:define name="label">Created On</ui:define>
                       <rich:calendar id="createdOn" 
                                   value="#{inFilesHome.instance.createdOn}" 
                                required="true" 
                                disabled="true"
                            datePattern="MM/dd/yyyy" 
                                  event="onblur" 
                               reRender="createdOnDecoration" 
                                  style="width: auto;">
                      </rich:calendar>                 
                  </s:decorate>
                                         
                                          
                  <div style="clear:both">
                      <span class="required">*</span> 
                      required fields
                  </div>
                              
              </rich:panel>
              
                  
      
              <div class="actionButtons">
              
                  <h:commandButton id="save" 
                                value="Save" 
                               action="#{inFilesHome.persist}"
                             rendered="#{!inFilesHome.managed}"/> 
                  <h:commandButton id="delete" 
                                value="Delete" 
                               action="#{inFilesHome.remove}"
                            immediate="true"
                             rendered="#{inFilesHome.managed}"/>
                  <s:button propagation="end" 
                                     id="done" 
                                  value="Done"
                                   view="/admin/InFiles.xhtml"
                               rendered="#{inFilesHome.managed}"/>
                  <s:button propagation="end"
                                         id="cancel" 
                                  value="Cancel"
                                   view="/admin/#{empty inFilesFrom ? 'InFilesList' : inFilesFrom}.xhtml"
                               rendered="#{!inFilesHome.managed}"/>
                     <h:commandButton id="validate" 
                                value="Validate" 
                               action="#{inFilesHome.validate}"
                             rendered="#{inFilesHome.managed}"
                             disabled="#{!inFilesHome.readyForValidation}"/>  
                  <h:commandButton id="post" 
                                value="Post" 
                               action="#{inFilesHome.post}"
                             rendered="#{inFilesHome.managed}"
                             disabled="#{!inFilesHome.readyForPosting}"/>                      
              </div>
              
          </h:form>    
          
          
          
              <rich:tabPanel switchType="ajax">
                             
                <rich:tab label="InCityStateZip">             
                     <ui:include src="/admin/InCityStateZipTable.xhtml">
                            <ui:param name="inCityStateZipFrom" value="InFilesEdit"/>
                        </ui:include>
                </rich:tab>
                                       
                <rich:tab label="Errors">
                     <ui:include src="InErrorsTable.xhtml">
                            <ui:param name="inErrorsFrom" value="InFilesEdit"/>
                        </ui:include>                        
                </rich:tab>               
      
           </rich:tabPanel>    
                 
          
      </ui:define>
      
      </ui:composition>
      



      InCityStateZipList.java


      @Name("inCityStateZipList")
      public class InCityStateZipList extends EntityQuery<InCityStateZip> 
      {
           private static final long serialVersionUID = -3524846754525228492L;
      
           private static final String[] RESTRICTIONS = { 
                "lower(inCityStateZip.country) like concat(lower(#{inCityStateZipList.inCityStateZip.country}),'%')",
                "lower(inCityStateZip.city) like concat(lower(#{inCityStateZipList.inCityStateZip.city}),'%')",
                "lower(inCityStateZip.province) like concat(lower(#{inCityStateZipList.inCityStateZip.province}),'%')",          
                "lower(inCityStateZip.zipcode) like concat(lower(#{inCityStateZipList.inCityStateZip.zipcode}),'%')",     
                "lower(inCityStateZip.county) like concat(lower(#{inCityStateZipList.inCityStateZip.county}),'%')",
                "inCityStateZip.status = #{inCityStateZipList.inCityStateZip.status}",
                "inCityStateZip.inFiles.id = #{inFilesHome.inFilesId}",
                };
      
           private InCityStateZip inCityStateZip = new InCityStateZip();
           
           public InCityStateZipList() {
                this.setMaxResults(25);
                this.setEjbql("select inCityStateZip from InCityStateZip inCityStateZip");
                this.setOrder("inCityStateZip.status asc");
                this.setRestrictionExpressionStrings(Arrays.asList(RESTRICTIONS));
           }
           
           public InCityStateZip getInCityStateZip() {
                return inCityStateZip;
           }
      
           public InFileStatus[] getInFileStatuses() {
                 return InFileStatus.values();
           }
      }
      



      InCityStateZipTable.xhtml



      <a4j:form id="inCityStateZipTableForm"
                  xmlns="http://www.w3.org/1999/xhtml"
                 xmlns:s="http://jboss.com/products/seam/taglib"
                 xmlns:ui="http://java.sun.com/jsf/facelets"
                 xmlns:f="http://java.sun.com/jsf/core"
                 xmlns:h="http://java.sun.com/jsf/html"
                 xmlns:a4j="http://richfaces.org/a4j"
                 xmlns:rich="http://richfaces.org/rich">
                
           <div class="association" id="inCityStateZips">
                          
                 <h:outputText value="No city-state-zips exists" 
                          rendered="#{empty inCityStateZipList.resultList}"/>    
      
                <rich:dataTable id="inCityStateZipList" 
                                   var="_inCityStateZip"
                               value="#{inCityStateZipList.resultList}" 
                             rendered="#{not empty inCityStateZipList.resultList}">
        
                        <h:column>
                            <f:facet name="header">
                                <a4j:htmlCommandLink styleClass="columnHeader" reRender="inCityStateZipList"
                                   value="Country #{inCityStateZipList.order=='country asc' ? messages.down : ( inCityStateZipList.order=='country desc' ? messages.up : '' )}">
                                    <f:param name="inCityStateZipListOrder" value="#{inCityStateZipList.order=='country asc' ? 'country desc' : 'country asc'}"/>
                                </a4j:htmlCommandLink>
                            </f:facet>
                            #{_inCityStateZip.country}
                        </h:column>
         
                        <h:column>
                            <f:facet name="header">
                                <a4j:htmlCommandLink styleClass="columnHeader" reRender="inCityStateZipList"
                                   value="City #{inCityStateZipList.order=='city asc' ? messages.down : ( inCityStateZipList.order=='city desc' ? messages.up : '' )}">
                               <f:param name="inCityStateZipListOrder" value="#{inCityStateZipList.order=='city asc' ? 'city desc' : 'city asc'}"/>
                                </a4j:htmlCommandLink>
                            </f:facet>
                            #{_inCityStateZip.city}
                        </h:column>
         
                     <h:column>
                         <f:facet name="header">
                             <a4j:htmlCommandLink styleClass="columnHeader" reRender="inCityStateZipList"
                                          value="State #{inCityStateZipList.order=='province asc' ? messages.down : ( inCityStateZipList.order=='province desc' ? messages.up : '' )}">
                                 <f:param name="inCityStateZipListOrder" value="#{inCityStateZipList.order=='province asc' ? 'province desc' : 'province asc'}"/>
                             </a4j:htmlCommandLink>
                         </f:facet>
                         #{_inCityStateZip.province}
                     </h:column>   
                     
                     <h:column>
                         <f:facet name="header">
                             <a4j:htmlCommandLink styleClass="columnHeader" reRender="inCityStateZipList"
                                          value="Zipcode #{inCityStateZipList.order=='zipcode asc' ? messages.down : ( inCityStateZipList.order=='zipcode desc' ? messages.up : '' )}">
                                 <f:param name="inCityStateZipListOrder" value="#{inCityStateZipList.order=='zipcode asc' ? 'zipcode desc' : 'zipcode asc'}"/>
                             </a4j:htmlCommandLink>
                         </f:facet>
                         #{_inCityStateZip.zipcode}
                     </h:column>            
           
                     <h:column>
                         <f:facet name="header">
                             <a4j:htmlCommandLink styleClass="columnHeader" reRender="inCityStateZipList"
                                          value="County #{inCityStateZipList.order=='county asc' ? messages.down : ( inCityStateZipList.order=='county desc' ? messages.up : '' )}">
                                 <f:param name="inCityStateZipListOrder" value="#{inCityStateZipList.order=='county asc' ? 'county desc' : 'county asc'}"/>
                             </a4j:htmlCommandLink>
                         </f:facet>
                         #{_inCityStateZip.county}
                     </h:column>    
                     
                     <h:column>
                         <f:facet name="header">
                             <a4j:htmlCommandLink styleClass="columnHeader" reRender="inCityStateZipList"
                                          value="Status #{inCityStateZipList.order=='status.value asc' ? messages.down : ( inCityStateZipList.order=='status.value desc' ? messages.up : '' )}">
                                 <f:param name="inCityStateZipListOrder" value="#{inCityStateZipList.order=='status.value asc' ? 'status.value desc' : 'status.value asc'}"/>
                             </a4j:htmlCommandLink>
                         </f:facet>
                         #{_inCityStateZip.status.value}
                     </h:column> 
                        
                     <h:column>
                         <f:facet name="header">Action</f:facet>
                         <s:link view="/admin/#{empty from ? 'InCityStateZip' : from}.xhtml" 
                                value="Select" 
                                   id="inCityStateZip"
                             propagation="none">                                                               
                             <f:param name="inCityStateZipFrom" 
                                     value="#{inCityStateZipFrom}"/>
                             <f:param name="inCityStateZipId" 
                                     value="#{_inCityStateZip.id}"/>
                         </s:link>
                     </h:column>
                          
                </rich:dataTable>
      
           </div>
      
           <div class="tableControl">
            
                <s:link view="/admin/#{inCityStateZipFrom}.xhtml"
                     rendered="#{inCityStateZipList.previousExists}" 
                        value="#{messages.left}#{messages.left} First Page"
                           id="inCityStateZipListFirstPage">
                     <f:param name="firstResult" value="0"/>
                </s:link>
                             
                <s:link view="/admin/#{inCityStateZipFrom}.xhtml"
                     rendered="#{inCityStateZipList.previousExists}" 
                        value="#{messages.left} Previous Page"
                           id="inCityStateZipListPreviousPage">
                     <f:param name="firstResult" 
                          value="#{inCityStateZipList.previousFirstResult}"/>
                </s:link>
                             
                <s:link view="/admin/#{inCityStateZipFrom}.xhtml"
                     rendered="#{inCityStateZipList.nextExists}" 
                        value="Next Page #{messages.right}"
                           id="inCityStateZipListNextPage">
                     <f:param name="firstResult" 
                             value="#{inCityStateZipList.nextFirstResult}"/>
                </s:link>
                             
                <s:link view="/admin/#{inCityStateZipFrom}.xhtml"
                     rendered="#{inCityStateZipList.nextExists}" 
                        value="Last Page #{messages.right}#{messages.right}"
                           id="inCityStateZipListLastPage">
                     <f:param name="firstResult" 
                             value="#{inCityStateZipList.lastFirstResult}"/>
                </s:link>
              
          </div>
      
      </a4j:form>
      



      InFilesHome.java


      @Name("inFilesHome")
      public class InFilesHome extends EntityHome<InFiles> {
      
           private static final long serialVersionUID = 2221010914357487335L;
           
           @In private Events events;
      
           /**
            * Setter for the entity id.
            * 
            * @param id
            *            the entity id.
            */     
           public void setInFilesId(Long id) {
                setId(id);
           }
      
           /**
            * Getter for the entity id.
            * 
            * @return the entity id.
            */     
           public Long getInFilesId() {
                return (Long) getId();
           }
      
           /**
            * Initializes the entity instance.
            */     
           @Override
           protected InFiles createInstance() {
                InFiles inFiles = super.createInstance();
                // inFiles.setStatus(InFileStatus.NEW);
                // inFiles.setCreatedOn(new Date());
                return inFiles;
           }
      
           /**
            * Called from the object's page.xml to establish the association prior to
            * the editor being rendered.
            */     
           public void wire() {
           }
      
           /**
            * Toggles the disabled attribute of the Save button if a wired object has
            * not been selected.
            * 
            * @return true if object is selected and false if object is not selected
            */     
           public boolean isWired() {
                return true;
           }
      
           /**
            * A custom method that strictly attempts to retrieve an instance from the
            * persistence manager if the id is established, as determined by the
            * isIdDefined() method.
            * 
            * @return
            */     
           public InFiles getDefinedInstance() {
                return isIdDefined() ? getInstance() : null;
           }
      
           // ---------------------------------------------------------------------------------
           // Detail Screen
           // ---------------------------------------------------------------------------------
      
           // Tab listings are queried and displayed through their perspective java and
           // xhtml.
      
           // ---------------------------------------------------------------------------------
           // Edit Screen
           // ---------------------------------------------------------------------------------
      
      
           /**
            * Checks to see if inFiles record is ready for validation.
            * 
            * @return true if ready for validation.
            */
           public boolean isReadyForValidation() {
                return (getInstance().getStatus().getKey() == InFileStatus.IMPORTED.getKey()
                          || getInstance().getStatus().getKey() == InFileStatus.VALIDATING.getKey() 
                          || getInstance().getStatus().getKey() == InFileStatus.VALIDATION_ERROR.getKey());
           }
      
           /**
            * Validates the inFiles data.
            * 
            * NOTE: If any new validation needs to be added, place it in the action bean.
            */
           public void validate() {
                if (getInstance().getStatus().getKey() == InFileStatus.IMPORTING.getKey()
                          || getInstance().getStatus().getKey() == InFileStatus.IMPORT_ERROR.getKey()) {
                     if (!areErrorsDeleted(InFileStatus.IMPORTED)) {
                          return;
                     }
                }
               this.info("validating...");
               InFilesValidateAction contentAction = (InFilesValidateAction) Component.getInstance(InFilesValidateActionBean.class);
                if (contentAction.inFilesValidateAction(getInstance()).equalsIgnoreCase("success")) {
                     getInstance().setStatus(InFileStatus.VALIDATED);
                } else {
                     getInstance().setStatus(InFileStatus.VALIDATION_ERROR);
                }
                update();
               //events.raiseTransactionSuccessEvent("refreshInCityStateZip");
           }
      
           /**
            * Checks to see if inFiles record is available for posting.
            * 
            * @return true if available for posting.
            */
           public boolean isReadyForPosting() {
                return (getInstance().getStatus().getKey() == InFileStatus.VALIDATED.getKey()
                          || getInstance().getStatus().getKey() == InFileStatus.POSTING.getKey() 
                          || getInstance().getStatus().getKey() == InFileStatus.POSTING_ERROR.getKey());
           }
      
           /**
            * Posts the inFiles data.
            * 
            * NOTE: If any new posting needs to be added, place it in the action bean.
            */
           public void post() {
                if (getInstance().getStatus().getKey() == InFileStatus.POSTING.getKey()
                          || getInstance().getStatus().getKey() == InFileStatus.POSTING_ERROR.getKey()) {
                     if (!areErrorsDeleted(InFileStatus.VALIDATED)) {
                          return;
                     }
                }
               this.info("posting...");
               InFilesPostAction contentAction = (InFilesPostAction) Component.getInstance(InFilesPostActionBean.class);
                if (contentAction.inFilesPostAction(getInstance()).equalsIgnoreCase("success")) {
                     getInstance().setStatus(InFileStatus.POSTED);
                } else {
                     getInstance().setStatus(InFileStatus.POSTING_ERROR);
                }
                update();     
           }
           
           /**
            * Tries to delete any errors and set the inFiles status to the passed
            * InFileStatus.
            * 
            * @param inFilesStatus
            *            the status to set the inFile record to after deletion.
            * @return true if the errors were deleted.
            */
           private boolean areErrorsDeleted(InFileStatus inFilesStatus) {
                try {
                     this.getEntityManager().createNamedQuery(
                               "inErrors.deleteByInFilesId").setParameter(
                               InErrors.FIELD_TO_INFILES, getInstance().getId());
                     getInstance().setStatus(inFilesStatus);
                     persist();
                } catch (Exception ex) {
                     FacesMessages.instance().add(ex.getMessage());
                     ex.printStackTrace();
                     return false;
                }
                return true;
           }
      
           
           
           
           private byte[] inFile;
           private String inContentType;
           private String inFileName;
      
           /**
            * Method called when import is invoked.
            */
           public void uploadInFile() {
                if (inFile == null) {
                     FacesMessages.instance().add("The file: " + inFileName + "is null");
                     return;
                }
                if (inFile != null && inFile.length > 0) {
                     getInstance().setName(inFileName);
                     FacesMessages.instance().add(
                               "Filename: " + inFileName + "; filesize: " + inFile.length);
                     // System.out.println("filename: " + inFileName);
                }
           }
      
           public void setInFile(byte[] inFile) {
                this.inFile = inFile;
           }
      
           public byte[] getInFile() {
                return inFile;
           }
      
           public String getInContentType() {
                return inContentType;
           }
      
           public void setInContentType(String contentType) {
                this.inContentType = contentType;
           }
      
           public InFileType[] getInFileTypes() {
                return InFileType.values();
           }
      
           public InFileStatus[] getInFileStatuses() {
                return InFileStatus.values();
           }
           
      }
      




      The reason I have an InCityStateZipTable.xhtml is to eliminitate duplication of listings.


      Does anyone have any idea how to refresh the tab listing?