Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

XPages – delay before second button click takes place

I have a form with two rich text fields used to hold attachments and an XPage that contains two file download controls (one for each field) and two buttons.

The buttons call a method in a Java class that creates a zip file containing the files from the relevant field. The zip file is downloaded in the browser for the user.

It all works perfectly – apart from the fact that if you download either zip file, you cannot immediately download the other. There is a delay of around 15-20 seconds before the second button click does anything.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

XPage :-

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.data>
        <xp:dominoDocument var="document1" formName="Document"></xp:dominoDocument>
    </xp:this.data>
    
    <xp:panel tagName="div"
        style="margin-left:auto; margin-right:auto; width:50%">

        <xp:br></xp:br>

        <xp:fileDownload rows="30" id="fileDownload1"
            displayLastModified="false" value="#{document1.Body1}">
        </xp:fileDownload>
        
        <xp:button value="Download Zipfile 1" id="button1">
            <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
                <xp:this.script><![CDATA[console.log("Button1 click")]]></xp:this.script>
                <xp:this.action><![CDATA[#{javascript:uk.co.mp.DownloadAllAttachments.downloadFromField(context.getUrlParameter("documentId"), "Body1");
}]]></xp:this.action>
            </xp:eventHandler>
        </xp:button>

        <xp:br></xp:br>

        <xp:fileDownload rows="30" id="fileDownload2"
            displayLastModified="false" value="#{document1.Body2}">
        </xp:fileDownload>

        
        <xp:button value="Download Zipfile 2" id="button2">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="complete">
                <xp:this.script><![CDATA[console.log("Button2 click")]]></xp:this.script>
                <xp:this.action><![CDATA[#{javascript:uk.co.mp.DownloadAllAttachments.downloadFromField(context.getUrlParameter("documentId"), "Body2");
}]]></xp:this.action>
            </xp:eventHandler>
        </xp:button>

    </xp:panel>

</xp:view>

Java class :-

package uk.co.mp;

import java.io.BufferedInputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import lotus.domino.RichTextItem;

import com.ibm.xsp.designer.context.XSPContext;
import com.ibm.xsp.model.domino.DominoUtils;

//
import lotus.domino.Session;
import lotus.domino.Database;
import com.ibm.xsp.extlib.util.ExtLibUtil;

public class DownloadAllAttachments {
    

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void downloadFromField(String documentUNID, String fieldName) {

        // Initialize global XPage objects
        FacesContext facesContext = FacesContext.getCurrentInstance();
        XSPContext context = XSPContext.getXSPContext(facesContext);
        UIViewRoot view = facesContext.getViewRoot();
        Map viewScope = view.getViewMap();

        try {

            if (documentUNID == null || documentUNID.trim().equals("")) {
                viewScope.put("errorString", "URL parameter \"documentUNID\" or \"u\" is required.");
                view.setRendered(true);
                return;
            }

            Session s = ExtLibUtil.getCurrentSessionAsSigner();
            Database db = s.getCurrentDatabase();
            
            // Get and validate the document from which attachments would be zipped
            Document downloadDocument = null;
            downloadDocument = db.getDocumentByUNID(documentUNID);

            // Get and validate zip file name from URL
            String zipFileName = fieldName + ".zip";

            boolean bAnyAttachments = false;
            EmbeddedObject embeddedObj = null;
            Vector attachments = null;
            
            // ...check for attachments in the field supplied and collect the names of the attachments
            RichTextItem rtitem = (RichTextItem)downloadDocument.getFirstItem(fieldName);
            Vector vec = rtitem.getEmbeddedObjects();
            attachments = new Vector(vec.size());
            
            if (!vec.isEmpty()) {
                Iterator it = vec.iterator();

                while(it.hasNext()){
                    embeddedObj = (EmbeddedObject)it.next();
                    if (embeddedObj != null) {
                        attachments.add(embeddedObj.getName());
                        bAnyAttachments = true;
                    }

                }
            }

            
            //By this point we should have a list of the attachment names we want to include in the zip file            

            //If we have not found any attachments then return a message
            if (!bAnyAttachments) {
                viewScope.put("errorString", "<center><h3>No attachments found in the Document.</h3></center>");
                return;
            }

            // Set response header values
            HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", -1);
            response.setContentType("application/zip");
            response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);

            // Get stream related objects
            OutputStream outStream = response.getOutputStream();
            ZipOutputStream zipOutStream = new ZipOutputStream(outStream);
            BufferedInputStream bufferInStream = null;

            // Get all attachment names and loop through all of them adding to zip
            for (int i = 0; i < attachments.size(); i++) {
                embeddedObj = downloadDocument.getAttachment(attachments.get(i).toString());
                if (embeddedObj != null) {
                    bufferInStream = new BufferedInputStream(embeddedObj.getInputStream());
                    int bufferLength = bufferInStream.available();
                    byte data[] = new byte[bufferLength];
                    bufferInStream.read(data, 0, bufferLength); // Read the attachment data
                    ZipEntry entry = new ZipEntry(embeddedObj.getName());
                    zipOutStream.putNextEntry(entry);
                    zipOutStream.write(data); // Write attachment into Zip file
                    bufferInStream.close();
                    embeddedObj.recycle();
                }
            }


            // Clean up and close objects
            downloadDocument.recycle();
            zipOutStream.flush();
            zipOutStream.close();
            outStream.flush();
            outStream.close();
            facesContext.responseComplete();

        } catch (Exception e) {
            viewScope.put("errorString", "Error while zipping attachments.<br>" + e.toString());
            e.printStackTrace();
        }
    }
    
    
}

Is there something preventing the second button click from occurring for that 15-20 seconds? Many thanks for any suggestions

>Solution :

Try adding XSP.allowSubmit()to the client side JS event of your button.

<xp:button value="Download Zipfile 1" id="button1">
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
        <xp:this.script><![CDATA[console.log("Button1 click")]]></xp:this.script>
        <xp:this.action><![CDATA[#{javascript:uk.co.mp.DownloadAllAttachments.downloadFromField(context.getUrlParameter("documentId"), "Body1");
}]]></xp:this.action>
        <xp:this.script><![CDATA[XSP.allowSubmit()]]></xp:this.script>
    </xp:eventHandler>
</xp:button>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading