ShowTable of Contents
Introduction
The issue we are addressing:
- Users currently have to manually download attachments and open them from their hard drive.
If a particular file type can be displayed in the browser, we would like to do so instead.
Three such file types are images, PDFs and Flash movies.
Attachments within Quickr:
Attachment "pdfbefore.png" shows how a PDF normally displays. The user must download the PDF shown here to view it.
What we need to do to implement our changes:
- Code to override the call to display the usual download options for attachments
- Code to render the attachment within the page if it is of an appropriate file type, and display the default download options otherwise.
- Load the new javascript file into the existing javascript extension file
Relevant Files
We now collect the files currently in Quickr that we will modify to display our new links.
First, we create folder structure qext\inlineAttachments under qphtml\skins
This folder will hold our modified files which be loaded instead of the ordinary ones by the widget extension registry
Copy and paste the following files from qphtml\widgets\page directory to your new directory qphtml\skins\qext\widgets\page:
1. page\field\singleAttachment.js – rename to inlineAttachments\defaultAttachment.js
2. page\field\singleAttachment.js – rename to inlineAttachments\pdfAttachment.js
3. page\defaultUpload.js - rename to inlineAttachments\customUpload.js
4. page\defaultUpload.xsl – rename to inlineAttachments\customUpload.xsl
Required Changes
defaultAttachment.js:
Remove all the functions from the defaultAttachment.js file except the renderRead function, which we will rename to defaultUpload
Change the definition of the file to qext instead of quickr (see below)
We will also add a number of functions used to pull in url paths
When finished, the overall structure of the file should look like this (each of the functions are explained below):
dojo.provide("qext.inlineAttachments.defaultAttachment");
dojo.declare("qext.inlineAttachments.defaultAttachment", null, {
defaultUpload: function(aValue, addNode) {
...},
getValue(){...},
getNode(){...},
getSrc(){...}
});
The defaultUpload function is similar to the "renderRead" function. It builds a span with the default download/preview links for the attachment if the widget finds that it has been called for a file that is not a PDF.
defaultUpload: function(aValue, addNode) {
var diffNumber = 0;
for (var ii = 0; ii < aValue.length; ii++) {
aValue[ii] = dojo.trim(aValue[ii]);
if (aValue[ii].length > 0) {
var sName = aValue[ii];
sName = sName.replace(new RegExp("\\n","g"), "");
sName = sName.replace(new RegExp("\\r","g"), "");
if (sName.indexOf("/") > -1) sName = sName.substring(sName.lastIndexOf("/")+1);
var info = this._getIconInfo(sName, "80");
var sTemplate = "<div class='qkrFileSection'><table class='lotusDetails' cellspacing='0' cellpadding='0'><tr><td class='lotusFirst'><img height='" + this.size + "' width='" + this.size + "' title='" + info.alt + "' alt='" + info.alt + "' src=\"" + info.src + "\"/></td><td><div class='qkrWide'><div class='qkrWideInner'>";
if(this.description) {
var sDescription = this.description;
sDescription = sDescription.replace(new RegExp("\\n","g"), "<br>");
sTemplate += "<div>" + this._getText("PAGE.CREATE.FIELDS.UPLOAD.DESCRIPTION.TEXT", sDescription) + "</div>";
}
sTemplate +="<a href=\"javascript:;\" onclick=\"alert('This is not yet implemented');\">" + q_LocaleUtils.getStringResource("PAGE.ATTACHMENT.PREVIEWLINK") + "</a><br>" + "<a href=\"" + this._getDownloadLink(sName) + "\">" + this._getText("PAGE.ATTACHMENT.DOWNLOADNAME", sName) + "</a>" + "</div></div></td></tr></table></div>";
addNode.innerHTML = sTemplate;
}
}
return addNode;
}
The other three functions generate data that will be required by all attachments
The filenames of the attachments:
getValue: function(startingValue) {
var aValue = startingValue.replace(/\n/g,"").split(",");
if(aValue.length === 2 && aValue[1] === ""){
aValue = [aValue[0]];
}
return aValue;
},
The div node that will contain the attachment:
getNode: function(UNID) {
var addNode = dojo.doc.createElement("div");
addNode.id = UNID;
addNode.className ="lotusSection";
return addNode;
},
The full URL of the attachment:
getSrc: function(UNID, aValue, serverURL, placeName) {
var fileSrc = serverURL + placeName;
fileSrc += "/0/";
fileSrc += UNID;
fileSrc +="/$file/";
fileSrc +=aValue;
return fileSrc;
}
customUpload.js:
We want our widget to be able to do everything a normal upload page can, so we inherit the functions from the defaultUpload.js file. The only change we make is to associate the widget with a new XSL file.
dojo.provide("qext.inlineAttachments.customUpload");
dojo.require("quickr.widgets.page.defaultModalPage");
dojo.require("qext.inlineAttachments.defaultAttachment");
dojo.require("qext.inlineAttachments.pdfAttachment");
dojo.require("qext.inlineAttachments.imageAttachment");
dojo.require("qext.inlineAttachments.flashAttachment");
dojo.declare("qext.inlineAttachments.customUpload",
[quickr.widgets.page.defaultModalPage],
{
xslSource: "/qphtml/skins/qext/inlineAttachments/customUpload.xsl"
}
);
customUpload.xsl:
The only difference between our widget and an ordinary Upload page is in the attachments section, and so we replace the section of the XSL file with the following code.
This calls the appropriate JavaScript file for embedding files, after checking to make sure it is a PDF file.
We will also account for the other file types that we are going to display inline (.swf and images) here so that we don't need to return and edit it again later.
If the filetype does not match any of the files we want, we use the default quickr attachment page.
<!--attachments -->
<xsl:variable name="AttNames" select="child::*[attribute::fid='h_AttachmentNames']"/>
<xsl:variable name="AttNumber" select="count($AttNames)"></xsl:variable>
<xsl:choose>
<xsl:when test="$AttNumber=1">
<xsl:variable name="xslAttNames"><xsl:value-of select="$AttNames" /></xsl:variable>
<xsl:choose>
<!-- Check for images -->
<xsl:when test="contains($AttNames, '.jpg') or contains($AttNames, '.png') or contains($AttNames, '.gif')or contains($AttNames, '.GIF')">
<span dojoType="qext.inlineAttachments.imageAttachment" state="read" value="{$xslAttNames}" label="PAGE.CREATE.FIELDS.ATTACHMENTS.LABEL" unid="{$UNID}" description="{summary}" ></span>
</xsl:when>
<!-- Check for PDF files -->
<xsl:when test="contains($AttNames, '.pdf')">
<span dojoType="qext.inlineAttachments.pdfAttachment" state="read" value="{$xslAttNames}" label="PAGE.CREATE.FIELDS.ATTACHMENTS.LABEL" unid="{$UNID}" description="{summary}" ></span>
</xsl:when>
<!-- Check for ShockWave files -->
<xsl:when test="contains($AttNames, '.swf')">
<span dojoType="qext.inlineAttachments.flashAttachment" state="read" value="{$xslAttNames}" label="PAGE.CREATE.FIELDS.ATTACHMENTS.LABEL" unid="{$UNID}" description="{summary}" ></span>
</xsl:when>
<!-- Default -->
<xsl:otherwise>
<span dojoType="quickr.widgets.page.field.singleAttachment" state="read" value="{$xslAttNames}" label="PAGE.CREATE.FIELDS.ATTACHMENTS.LABEL" unid="{$UNID}" description="{summary}" ></span>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
pdfAttachment.js:
This widget inherits all of defaultAttachments functions.
The _isPdf function checks to make sure we are dealing with a PDF file, and if not, calls the inherited defaultUpload function
The function returns true if the file extension of the attachments matches a pdf formatted file.
When rendering the document, we get the url of the server, and use this to find the attachment's URL then build an