Another of the challenges in my assessment XPage problem is that the evaluators will need to open the attachments that were submitted with each grant request. There are two issues here – first, that the attachments are uploaded to multiple separate documents from the grant request and, second, that there might be multiple attachments on each of those documents.
We chose to have the attachments on separate documents to reduce the size of the request document and lower the likelihood of truncation or replication issues. The users requesting these grants are all located in Africa and may well be in remote locations. So, bandwidth issues, even for the browser side, are of paramount concern for us. We’ve had some issues in the past on the Notes side with some truncations or with replication issues and found it better to keep documents smaller as a precaution.
So, for each request, there can be up to 4 documents with an unknown number of attachments associated with each request. As such, I stumbled upon the idea of using a repeat-within-a-repeat to display the links for each attachment.
First, I made sure to get only the attachment documents that I want by filtering my source view (as discussed previously):
<xp:dominoView viewName="AnnexLinks" var="linksView"> <xp:this.keys><![CDATA[#{javascript:appDoc.getItemValueString("appUniqueID");}]]></xp:this.keys> </xp:dominoView>
Then, I needed to build my repeat control. The code itself is actually very brief. My AnnexLinks view is very simple, with only three columns: AppUniqueID (my index, which is not the document unique ID, by the way), the AttachmentType and the URLs for the attachments.
The URLs column builds a unique URL for each attachment:
unid := @Text ( @DocumentUniqueID ); base := "0/" + unid + "/$file/"; base + @AttachmentNames
Since there can be multiple values in the URLs column for a single document, I have the link embedded inside a repeat control, using that value as an array to populate my link. I’m computing the filename back from the URL to use as the link label, but using the AttachmentType for the document in the outer repeat to display a label for the attachments.
<xp:repeat id="repeat3" rows="30" value="#{linksView}" var="rowData" indexVar="rowIndex"> <xp:text escape="true" id="computedField1" value="#{rowData.AttachmentType}" style="font-weight:bold"> </xp:text> <xp:label value=" files:" id="label2" style="font-weight:bold"> </xp:label> <xp:repeat id="repeat4" rows="30" value="#{rowData.URLs}" var="url"> <xp:link escape="true" id="link1" value="#{url}"> <xp:this.text><![CDATA[#{javascript:@RightBack(url,"/") + " ";}]]></xp:this.text> </xp:link> <br /> </xp:repeat> </xp:repeat>
It’s shocking to me that something that ends up so small can accomplish what seemed like a huge tasks initially. On my notepad, I’ve got all kinds of SSJS written to get a handle to the attachment documents, then to try building an array of URLs, synchronized with a list of filenames to be used as labels. Fortunately, by poking around for URL info (h/t to Stephan Wissel – this will have to be updated for XPiNC and upgradeability) and referring back to my copy of Mastering XPages, I was able to sort out how to do it in just a few lines of simple, elegant code.