13 Replies Latest reply on Dec 17, 2009 2:02 PM by bolsover

    commandLink problem

    bolsover

      I have a problem with a commandLink...

       

      <h:commandLink immediate="true" action="#{ProductBean.actionOpenDocument}" value="Open" >
          <a4j:actionparam name="docid" value="#{document.id}" ></a4j:actionparam>
      </h:commandLink>

       

      The action retrieves .pdf, /.xls /.doc data from a database and sends to browser...

       

      public String actionOpenDocument() {
              HttpServletRequest    httpReq  = AppUtils.getCurrentRequest();
              String                docid    = httpReq.getParameter("docid");
              DocumentDao           dao      = new DocumentDao();
              Document              doc      = dao.retrieveDocumentById(docid);
              FacesContext          fc       = FacesContext.getCurrentInstance();
              HttpServletResponse   response = AppUtils.getCurrentResponse();
              ByteArrayOutputStream baos     = new ByteArrayOutputStream();

              try {
                  SerializableBlob sblob = (SerializableBlob) doc.getFdata();
                  Blob             blob  = sblob.getWrappedBlob();

                  // get stream from Blob
                  InputStream inStream = blob.getBinaryStream();
                  int         length   = -1;
                  byte[]      buffer   = new byte[4096];

                  // write data to output stream
                  while ((length = inStream.read(buffer)) != -1) {
                      baos.write(buffer, 0, length);
                  }

                  baos.flush();
                  response.setContentType(doc.getMimetype());
                  response.setContentLength(baos.size());

                  ServletOutputStream outStream = response.getOutputStream();

                  baos.writeTo(outStream);
                  baos.flush();
                  outStream.flush();
                  outStream.close();
                  inStream.close();
              } catch (Exception ex) {
                  ex.printStackTrace();
              }

              fc.responseComplete();

              return null;
          }

       

      The action is working just fine....

       

      The problem is that selecting other menu items on the same page after a call to the 'Open document' link cause the browser to attempt re-render of the previous document (.pdf appear to be ok since these open in the same window) - resulting in screen corruption.

       

      I suspect that I need to set the rel="" attribute of commandLink - but what to?

       

      ps. Using a4j:commandLink in this context appears to be seriously broken!

        • 1. Re: commandLink problem
          nbelaevski

          Hi,

           

          What is RF version and full page code?

           

          bolsover wrote:

           

          ps. Using a4j:commandLink in this context appears to be seriously broken!

          AJAX is not intended for binary file transfers.

          • 2. Re: commandLink problem

            Hello!

             

            Use a simple h:commandLink in this case. This is what we do and it work fine.

            a4j:commandLink must only be use to make ajax transaction.

             

            @+

            • 3. Re: commandLink problem
              bolsover

              Hi Nick

               

              Yes, I inderstand that AJAX is not intended for binary tansfers - I am using h:commandLink to initiate - the problem arises when I open an .xls and thne subsequently select the rich:menuItem - initially, the newDocModalPanel panel opens - but then immediately closes and the main page attempts to render a .xls object

               

              product_tree.jsp Page Code:

               

              <%@page contentType="text/html" pageEncoding="UTF-8"%>
              <
              %@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
              <
              %@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
              <
              %@taglib prefix="a4j" uri="http://richfaces.org/a4j" %>
              <
              %@taglib prefix="rich" uri="http://richfaces.org/rich"  %>
              <%@ taglib prefix="c" uri="
              http://java.sun.com/jstl/core" %>
              <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                  "
              http://www.w3.org/TR/html4/loose.dtd">
              <html>
                  <head>
                      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                      <link rel="stylesheet" type="text/css" href="../joshua.css">
                      <title>Joshua</title>
                  </head>
                  <body>
                      <f:view>
                          <div align="center">
                              <%@ include file="../WEB-INF/jspf/header.jspf" %>
                              <%@ include file="../WEB-INF/jspf/menubar.jspf" %>
                              <%@ include file="../WEB-INF/jspf/product_tree_body.jspf" %>
                              <%@ include file="../WEB-INF/jspf/footer.jspf" %>

                          </div>

                      </f:view>
                  </body>
              </html>

               

              product_tree_body.jspf code: - I've highlighted the link and menu item...

               

               

               

              <%@page contentType="text/html" pageEncoding="UTF-8"%>
              <
              %@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
              <
              %@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
              <
              %@taglib prefix="a4j" uri="http://richfaces.org/a4j" %>
              <
              %@taglib prefix="rich" uri="http://richfaces.org/rich"  %>
              <
              %@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
              <a4j:keepAlive beanName="ProductBean" />

              <rich:modalPanel id="editDocModalPanel" autosized="true" width="400"
                               moveable="true" resizeable="false" >

                  <f:facet name="header"><h:outputText value="Edit Document Detail"></h:outputText>
                  </f:facet>
                  <f:facet name="controls">
                      <h:panelGroup>
                          <h:graphicImage value="/images/modal/close.png" styleClass="hidelink" id="editdochidelink"/>
                          <rich:componentControl for="editDocModalPanel" attachTo="editdochidelink" operation="hide" event="onclick"/>
                      </h:panelGroup>

                  </f:facet>
                  <h:form id="editform">

                      <rich:panel>

                          <h:outputText value="" />
                          <h:inputHidden id="edocid" value="#{ProductBean.editDoc.id}" />
                          <h:inputHidden id="edocfd" value="#{ProductBean.editDoc.fdata}" />
                          <h:inputHidden id="edocel" value="#{DocumentEditBean.editDoc.element}" />
                          <h:inputHidden id="edocmt" value="#{ProductBean.editDoc.mimetype}" />
                          <h:inputHidden id="edocci" value="#{ProductBean.editDoc.classid}" />
                          <h:inputHidden id="edocst" value="#{ProductBean.editDoc.status}" />
                          <h:inputHidden id="edocmo" value="#{ProductBean.editDoc.modifier}" />
                          <h:panelGrid id="edocgrid" columns="2" >


                              <h:outputText value="Company" /><h:inputText disabled="true" id="edocco" value="#{ProductBean.editDoc.customer_id}" />
                              <h:outputText value="Document Class" /><h:inputText disabled="true" id="edocpr" value="#{ProductBean.editDoc.product_id}" />
                              <h:outputText value="Title" /><h:inputText id="edocti" value="#{ProductBean.editDoc.title}" />
                              <h:outputText value="Description" /><h:inputText id="edocds" value="#{ProductBean.editDoc.description}" />
                              <h:outputText value="Narrative" /><h:inputText id="edocnr" value="#{ProductBean.editDoc.narr}" />
                              <h:outputText value="Archive Location" /><h:inputText id="edocar" value="#{ProductBean.editDoc.archived}" />
                              <h:outputText value="Document Date" /><rich:calendar id="edocdd" value="#{ProductBean.editDoc.ddate}" />
                              <h:outputText value="Retention Years" /><h:inputText id="edocry" disabled="true" value="#{ProductBean.editDoc.ryears}" />
                              <h:outputText value="Retention Date" /><rich:calendar id="edocrd" disabled="true" value="#{ProductBean.editDoc.rdate}" />
                              <h:outputText value="File Name" /><h:inputText id="edocfn" disabled="true" value="#{ProductBean.editDoc.fname}" />
                              <a4j:commandLink id="editsave" immediate="true" action="#{ProductBean.saveEditDoc}" reRender="documentTable" value="Save"  >
                                   <rich:componentControl for="editDocModalPanel" attachTo="editsave" operation="hide" event="onclick"/>
                              </a4j:commandLink>


                          </h:panelGrid>


                      </rich:panel>
                  </h:form>

              </rich:modalPanel>

              <rich:modalPanel id="newDocModalPanel" autosized="true" width="400"
                               moveable="true" resizeable="false" >
                  <f:facet name="header"><h:outputText value="New Document Detail"></h:outputText>
                  </f:facet>
                  <f:facet name="controls">
                      <h:panelGroup>
                          <h:graphicImage value="/images/modal/close.png" styleClass="hidelink" id="newdochidelink"/>
                          <rich:componentControl for="newDocModalPanel" attachTo="newdochidelink" operation="hide" event="onclick"/>
                      </h:panelGroup>

                  </f:facet>
                  <h:form>
                      <rich:panel>
                          <h:panelGrid id="docgrid" columns="2" >

                              <h:outputText value="Company" /><h:inputText id="docco" value="#{ProductBean.updateDoc.customer_id}" />
                              <h:outputText value="Document Class" /><h:inputText id="docpr" value="#{ProductBean.updateDoc.product_id}" />
                              <h:outputText value="Title" /><h:inputText id="docti" value="#{ProductBean.updateDoc.title}" />
                              <h:outputText value="Description" /><h:inputText id="docds" value="#{ProductBean.updateDoc.description}" />
                              <h:outputText value="Narrative" /><h:inputText id="docnr" value="#{ProductBean.updateDoc.narr}" />
                              <h:outputText value="Archive Location" /><h:inputText id="docar" value="#{ProductBean.updateDoc.archived}" />
                              <h:outputText value="Document Date" /><rich:calendar id="docdd" value="#{ProductBean.updateDoc.ddate}" />
                              <h:outputText value="Retention Years" /><h:inputText id="docry" disabled="true" value="#{ProductBean.updateDoc.ryears}" />
                              <h:outputText value="Retention Date" /><rich:calendar id="docrd" disabled="true" value="#{ProductBean.updateDoc.rdate}" />
                              <h:outputText value="File Name" /><h:inputText id="docfn" disabled="true" value="#{ProductBean.updateDoc.fname}" />

                          </h:panelGrid>
                          <h:inputHidden value="#{ProductBean.updateDoc.id}" />
                          <h:inputHidden value="#{ProductBean.updateDoc.fdata}" />
                          <h:inputHidden value="#{ProductBean.updateDoc.element}" />
                          <h:inputHidden value="#{ProductBean.updateDoc.mimetype}" />
                          <h:inputHidden value="#{ProductBean.updateDoc.classid}" />
                          <h:inputHidden value="#{ProductBean.updateDoc.status}" />
                          <h:inputHidden value="#{ProductBean.updateDoc.modifier}" />
                          <p>Upload and save</p>
                          <rich:fileUpload fileUploadListener="#{ProductBean.listener}"
                                           maxFilesQuantity="1"
                                           id="doc"
                                           alt="#{ProductBean.document.id}"
                                           immediateUpload="false"
                                           acceptedTypes="jpg, gif, png, bmp, pdf, xls, doc" allowFlash="false" autoclear="true" listHeight="50px" listWidth="300px">
                              <a4j:support event="onuploadcomplete" reRender="documentTable, docgrid, docco, docpr, docti, docds, docnr, docar, docdd, docry, docrd, docfn" requestDelay="200"/>
                          </rich:fileUpload>
                      </rich:panel>
                  </h:form>
              </rich:modalPanel>

              <rich:panel  style="width: 900px" >

                  <div align="left">

                      <h:panelGrid columns="2" columnClasses="aligntop, aligntop" >
                          <h:form>
                              <h:panelGrid  style="width: 270px" columns="1"  >
                                  <rich:tree ajaxSubmitSelection="true"
                                             nodeSelectListener="#{ProductBean.selectionListener}"
                                             switchType="client"
                                             id="tree"
                                             reRender="selectedProduct, documentTable, tableHeader, newDocModalPanel, editDocModalPanel"
                                             preserveModel="request"
                                             binding="#{ProductBean.productTree}"  >
                                      <rich:treeNode  >
                                          <h:outputText value="#{item.label}" />
                                      </rich:treeNode>
                                  </rich:tree>
                              </h:panelGrid>
                          </h:form>
                          <h:form>
                              <h:panelGrid style="width: 600px" columns="1"  id="selectedProduct" >

                                  <rich:dataTable onRowMouseOver="this.className='highlight'"
                                                  onRowMouseOut="this.className='normal'"
                                                  reRender="ds"
                                                  width="100%"
                                                  id="documentTable"
                                                  sortMode="single"
                                                  value="#{ProductBean.documents }"
                                                  var="document"
                                                  rows="20">

                                      <f:facet name="header"><h:outputText id="tableHeader" value="#{ProductBean.selectedCustomerProduct.header}"/>
                                      </f:facet>

                                      <rich:column  sortBy="#{document.title}" filterBy="#{document.title}" filterEvent="onkeyup">
                                          <f:facet name="header" ><h:outputText value="Title"></h:outputText></f:facet>
                                          <h:outputText value="#{document.title}" ></h:outputText>
                                      </rich:column>

                                      <rich:column  sortBy="#{document.description}" filterBy="#{document.description}" filterEvent="onkeyup">
                                          <f:facet name="header" ><h:outputText value="Description"></h:outputText></f:facet>
                                          <h:outputText value="#{document.description}" ></h:outputText>
                                      </rich:column>

                                      <rich:column  sortBy="#{document.fname}" filterBy="#{document.fname}" filterEvent="onkeyup">
                                          <f:facet name="header" ><h:outputText value="Original File"></h:outputText></f:facet>
                                          <h:outputText value="#{document.fname}" ></h:outputText>
                                      </rich:column>

                                      <rich:column  >
                                          <f:facet name="header" ><h:outputText value="Open"></h:outputText></f:facet>
                                         <h:commandLink immediate="true" action="#{ProductBean.actionOpenDocument}" value="Open" >
                                              <a4j:actionparam name="docid" value="#{document.id}" ></a4j:actionparam>
                                          </h:commandLink>
                                          <h:outputText value=" "/>
                                      </rich:column>

                                      <rich:column>
                                         <f:facet name="header" ><h:outputText value="Edit"></h:outputText></f:facet>
                                          <a4j:commandLink immediate="true" oncomplete="#{rich:component('editDocModalPanel')}.show()"
                                                           reRender="editform"
                                                           action="#{ProductBean.actionEditDocument}" value="Edit" >
                                              <a4j:actionparam name="docid" value="#{document.id}" ></a4j:actionparam>
                                          </a4j:commandLink>
                                      </rich:column>

                                      <f:facet name="footer" >
                                          <rich:datascroller status="waitStatus" id="ds" reRender="documentTable"  align="center" for="documentTable" maxPages="10" />
                                      </f:facet>

                                  </rich:dataTable>
                                  <rich:toolBar style="width: 600px; text-align: left;"><rich:menuItem id="adddoc" submitMode="ajax" value="Add Document" >
                                          <rich:componentControl attachTo="adddoc" for="newDocModalPanel" operation="show" event="onclick"/>
                                      </rich:menuItem
              ></rich:toolBar>
                              </h:panelGrid>

                          </h:form>
                      </h:panelGrid>
                  </div>

              </rich:panel>

              • 4. Re: commandLink problem
                bolsover

                Hi Remi

                 

                Thanks for the suggestion - but I am using h:commandLink... problems arise when user subsequently selects a rich:menuItem on the same page.

                 

                David

                • 5. Re: commandLink problem
                  ebross

                  Here are two possible pointers; they might not be relevant to your problem but they are worth trying:

                   

                  1. The richfaces doc says of the modalPane usage (under 6.10.1.3. Details of Usage) that:

                   

                  "To work properly, the <rich:modalPanel> should always be placed outside the original <h:form>. For performing submits from within the <rich:modalPanel> it must include its own <h:form>..."

                   


                  I follow this advice and always do the following, and have had no issues with rich:modalPanel>. Here is what I would do:
                  ...
                    xmlns:h="http://java.sun.com/jsf/html"
                    xmlns:a4j="http://richfaces.org/a4j"
                  xmlns:rich="http://richfaces.org/rich">

                   

                  <h:form id="greetingModalForm">
                  <rich:modalPanel id="greetingModalPanel"
                  :
                  :
                  </rich:modalPanel>
                  </h:form>

                   

                  <!-- Main Form after the modalPane -->

                   

                  <h:form id="mainForm">
                  :
                  :
                  :
                  </h:form>

                   


                  2. Try your code without "a4j:keepALive" or use (tomahawk) t:saveState instead of a4j:keepALive.

                   

                   

                  BTW, it is a REAL pain in the arse trying to use this new editor. I thought the JBoss team are a very busy bunch. If so, how come they have time on their hands to fiddle around, replacing something that works with something that is a pain to use?

                  • 6. Re: commandLink problem
                    bolsover

                    Hi Benjamin

                     

                    Thanks for the input - but no solution yet..

                     

                    This is not a form within a form problem; the modal panels (edit and add new document) each have their own forms.

                     

                    Removing the  <a4j:keepAlive beanName="ProductBean" /> does not solve the issue either - in fact with this removed, none of the database served PDF's are displayed..

                     

                    Screen shot to help clarify the issue.

                     

                     

                    1.jpg

                     

                    1 User selects node in tree; table contents are updated from database

                    2 User selects to open a .pdf document from table - new window opens and document is rendered from database.

                    3 User selects Add Document menu item (foot of table)

                    4 Modal Panel with FileUpload dialog opens very briefly then closes and garbage is rendered in the browser.

                     

                    If user does not select Open first, the modal window opens and user is able to upload new documents to the server.

                     

                    I have modified the code a little from the earlier post to correct a different problem - but this issue and the code is generally the same.

                     

                    Anyone?

                    • 7. Re: commandLink problem

                      Instade of using different form for rich:modal panel we can also use

                       

                       

                      domElementAttachment="form"

                      • 8. Re: commandLink problem
                        ilya_shaikovsky
                        two additional question for you..
                        1. pelase check in debug or using logging - do you see method actionOpenDocument executed again after Add button clicked.
                        2. just want to clarify - not see RichFaces version info.
                        1 of 1 people found this helpful
                        • 9. Re: commandLink problem
                          bolsover

                          Hi Ilya

                           

                          1 - I had not checked this before  but YES - actionOpenDocument is executed again after the Add button is clicked.

                           

                          I guess with this knowledge, I should be able to prevent the second call and spurious response.. I'll let you know.

                           

                          2 - Just in case - version 3.3.2-SR1

                          • 10. Re: commandLink problem
                            bolsover

                            Hi Ilya

                             

                            I have modified the actionOpenDocument method to test for a parameter named 'AJAXREQUEST' and only execute if this is null or isEmpty.

                             

                            This has certainly solved the problem - although I'm not sure it is the cleanest way to address the issue.

                             

                            Is this a bug?   The page code for the menuItem has submitMode="ajax" - but it seems I actually get a server submit.

                             

                            Thanks for the help.

                             

                            David

                            • 11. Re: commandLink problem
                              ilya_shaikovsky
                              this unneeded call usually appears when responceComplete not called or outputStream not closed properly.. but in your code it's done.. So I'm not sure for now...
                              • 12. Re: commandLink problem
                                bolsover

                                Hi Deb

                                 

                                Thanks for the suggestion - I did try - but as you will note from the conversation with Ilya, the problem (and solution) lies elesewhere.

                                 

                                David

                                • 13. Re: commandLink problem
                                  bolsover

                                  Ilya

                                   

                                  Thanks fore the help with this; I can now move on to the next challenge.

                                   

                                  David