While uploading the multiple files at the same time you may have faced the problem like ‘View state size limit exceeded’, ‘Heap size’ limit and file size limit. To overcome these limits we can use javascript to handle the file uploading through the Visualforce page.
I have also faced the problem like View state size limit exceeded and Heap size limit, to solve the issue I decided to send/upload the files using HTTP POST Request with the help of Ajax, Jquery, javascript. Below is the code snippet for uploading files in the ContentVersion object.
<apex:page> | |
<html> | |
<head> | |
<apex:slds /> | |
<apex:includeScript value="https://code.jquery.com/jquery-2.2.4.js"/> | |
<script> | |
//function starts | |
$(function(){ | |
var fileLenght=0; | |
$('#uploadBtn').click(function() { | |
var v=document.getElementById('addr'); | |
console.log(v.files.length); | |
fileLenght = v.files.length; | |
for (var i = 0; i < v.files.length; i++) { | |
uploadSelectedFile(v.files[i], function(err, res){ | |
FileUploading += 1; | |
if (FileUploading === FileUploaded){ | |
alert('upload completed'); | |
//blank input file value | |
document.getElementById("addr").value = ""; | |
} | |
}) | |
} | |
}); | |
var FileUploading = 0; | |
var FileUploaded = 0; | |
var ids = new Array(); | |
var uploadSelectedFile = function(file, callback) { | |
filetoBase64(file, function(err, content){ | |
var conVer_object = { | |
ContentLocation : 'S', | |
VersionData : content, | |
PathOnClient : file.name, | |
Title : file.name | |
}; | |
$.ajax({ | |
url: '/services/data/v39.0/sobjects/ContentVersion', | |
data: JSON.stringify(conVer_object ), | |
type: 'POST', | |
processData: false, | |
contentType: false, | |
headers: {'Authorization': 'Bearer {!$Api.Session_ID}', 'Content-Type': 'application/json'}, | |
xhr: function(){ | |
var xhr = new window.XMLHttpRequest(); | |
//Upload progress | |
xhr.upload.addEventListener("progress", function(evt){ | |
if (evt.lengthComputable) { | |
$('#progress_bar_container').css('display', 'block'); | |
var percentComplete = evt.loaded / evt.total; | |
console.log('percentComplete '+percentComplete ); | |
var percentCompletex= percentComplete*100; | |
$('#percentText').html("Uploading. Please wait... "+Math.round(percentCompletex)+"%"); | |
$('.progress').css('width', percentCompletex+ "%"); | |
if(percentCompletex == 100){ | |
$('#progress_bar_container').css('display', 'none'); | |
} | |
} | |
}, false); | |
return xhr; | |
}, | |
success: function(response) { | |
FileUploaded += 1; | |
console.log(response.id); // the id of the attachment | |
ids.push(response.id); | |
console.log('Ids: ' +ids); | |
$('#records').html('File has been uploeded. Uploaded File ids: ' +ids); | |
if(fileLenght == FileUploaded ){ | |
//calculateLocation(ids.toString()); | |
} | |
callback(null, true) | |
}, | |
}); | |
}); | |
} | |
//Read file | |
var filetoBase64 = function(file, callback){ | |
var reader = new FileReader(); | |
reader.onload = function() { | |
var myFileContents = reader.result; | |
var base64Mark = 'base64,'; | |
var dataStart = myFileContents.indexOf(base64Mark) + base64Mark.length; | |
myFileContents = myFileContents.substring(dataStart); | |
callback(null, myFileContents); | |
} | |
reader.readAsDataURL(file); | |
} | |
}); | |
</script> | |
<style> | |
.slds-scope .slds-page-header{ | |
border-radius: 0px; | |
box-shadow: 0 0px 0px 0 rgba(0, 0, 0, 0.1); | |
} | |
.bodyPart{ | |
padding:10px; | |
} | |
</style> | |
</head> | |
<body> | |
<apex:form > | |
<div class="slds" style="border:1px solid #D9D9D9;"> | |
<div class="slds-page-header"> | |
<span style=""> Upload Files</span> | |
</div> | |
<div id="progress_bar_container" style="display:none; padding:10px;"> | |
<span id="percentText"></span> | |
<div class="slds-progress-bar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="25" role="progressbar"> | |
<span class="slds-progress-bar__value progress" style=" width: 0%;"> | |
<span class="slds-assistive-text">Progress: 25%</span> | |
</span> | |
</div> | |
</div><br/> | |
<div class="bodyPart"> | |
Select file: <input type="file" name="files[]" multiple="multiple" id="addr"/> | |
<input type="button" id="uploadBtn" name="Address" value="Upload" class="slds-button slds-button--brand"></input> | |
</div> | |
<div id="uploadedrec" style="padding:10px;"> | |
<span id="records" style=" color:green; "> | |
</span> | |
</div> | |
</div> | |
</apex:form> | |
</body> | |
</html> | |
</apex:page> |
On ‘Upload’ button click this method will be called. Here ‘#uploadBtn’ is the id of the button.
$(‘#uploadBtn’).click(function() { …}
If the user selects multiple files, Iterating over files length.
for (var i = 0; i < v.files.length; i++) { … }
In every iteration uploadSelectedFile, JS function will be called.
uploadSelectedFile(v.files[i], function(err, res){ …}
Reading the files and converted into the base64 format.
filetoBase64(file, function(err, content){ }
ContentVersion object variable with required fields.
var conVer_object = {
ContentLocation : ‘S’,
VersionData : content, // File body
PathOnClient : file.name, // File name
Title : file.name //File title
};
This AJAX method used to perform the asynchronous HTTP request to Salesforce.
$.ajax({ … }
URL or Endpoint: HTTP POST method will post the content to the specified location (ContentVersion object).
url: ‘/services/data/v39.0/sobjects/ContentVersion’,
Header: Salesforce Session_ID used for authentication.
headers: {‘Authorization’: ‘Bearer {!$Api.Session_ID}’, ‘Content-Type’: ‘application/json’},
XML HttpRequest object: Send the data from page to server (Salesforce) in the background.
var xhr = new window.XMLHttpRequest();
The addEventListener function listen to the progress of uploading.
xhr.upload.addEventListener(“progress”, function(evt){ … }
These lines of code will display the Progress bar on the page.
$(‘#progress_bar_container’).css(‘display’, ‘block’);
var percentComplete = evt.loaded / evt.total;
console.log(‘percentComplete ‘+percentComplete );
var percentCompletex= percentComplete*100;
$(‘#percentText’).html(“Uploading. Please wait… “+Math.round(percentCompletex)+”%”);
$(‘.progress’).css(‘width’, percentCompletex+ “%”);
if(percentCompletex == 100){
$(‘#progress_bar_container’).css(‘display’, ‘none’);
}
This success function will return the success message with the ids of the file that just uploaded.
Output:
References:
Hope this blog post will help many.
Happy coding…
Hi,
Nice Article.
I have one question, If we use the same thing for salesforce community user it’s not working.
LikeLike