Monday 18 July 2016

Painlessly upload a huge files in Salesforce Using a Visualforce Page

This article (Upload a File as Large as 2GB in Salesforce Using a Visualforce Page) is a brilliant read and well worth a squint if you're asked to facilitate attachments within a SalesForce VisualForce page. There are a couple of things that might warrant changing though. The <chatter:feed entityId="[ID of the custom object record]" /> bit brings in a shed load of CSS that may well not play nicely with your layout so please remember to disabled all CSS files with the class of user:

$(".user").attr("disabled", "disabled");

Of course, you might not mind, but I prefer having a wee bit more control. I prefer to have more control over the blocking behaviour as well so it's also worth including this in the script that's triggered by your uploading a file:

// Hide the chatter:feed file upload guff
setTimeout(function(){ 
    $("#uploadProgressDialog").addClass("hidden");
    $(".shadowDiv").addClass("hidden");
    $(".overlayBackground").addClass("hidden");
}, 100);

Should you want to listen to the return from the upload there is a really nice way of doing so detailed here. We use an awful lot of jQuery so being able to listen to other AJAX requests made from within jQuery is a really rather useful tool. Simply listening to the onReadyStateChangeReplacement and seeing if the readyState is 4 means that you can trigger your own events.

/*
 * This is so we can listen to ajax calls made outside of jQuery.
 */
var open = window.XMLHttpRequest.prototype.open,
    send = window.XMLHttpRequest.prototype.send,
    onReadyStateChange;
function openReplacement(method, url, async, user, password) {
    var syncMode = async !== false ? 'async' : 'sync';
    return open.apply(this, arguments);
}
function sendReplacement(data) {
    if(this.onreadystatechange) {
        this._onreadystatechange = this.onreadystatechange;
    }
    this.onreadystatechange = onReadyStateChangeReplacement;
    return send.apply(this, arguments);
}
function onReadyStateChangeReplacement() {
    // If the ajax is finished
    if(~~this.readyState === 4){
        // repopulate the fake file list
        setTimeout(function(){ 
            /* a setTimeout is probably not required but we 
             * might need to reference something that the 
             * original component has done to the DOM
             */
            // YOUR CODE HERE 
        }, 500);
    }
    if(this._onreadystatechange) {
        return this._onreadystatechange.apply(this, arguments);
    }
}
window.XMLHttpRequest.prototype.open = openReplacement;
window.XMLHttpRequest.prototype.send = sendReplacement;

We use this to check whether the number of attachments has changed, and if it has we re-draw our list.