I have a huge and complex vf page (force.com site) - So I will try to explain my issue with an example instead publish here all the code - I hope it will be understanble:
I want to upload a file from vf page - the problem -
I have a lot of apex actions, command buttons and links that use rerender and onComplete attributes, so if I trying to use apex:inputFile tag- something get ruined and I get the issue :
apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute.
even though I wrapped that with actionRegion tags.
So I tried to get it done by using an HTML input tag and Its worked but not good enuff. The File that saved inside the Opportunity Cannot be opened from salesforce and even if I download it its said that its doesn't support that file. In other words, the file is broken.
I did the following - hopping for a silly mistake:
<input type= "file" Id= "fileinput"/>
<apex:commandButton onclick="uploadFiles(); return false;" value="Upload"/>
And the "uploadFiles" JS function is :
var maxStringSize = 6000000;
var attachmentList;
var j;
function uploadFiles()
{
input = document.getElementById('fileinput');
attachmentList = input.files;
console.log("attachmentList",attachmentList);
if(j == undefined)
j = 0;
var file;
if(j < attachmentList.length)
{
file = attachmentList[j];
var name = file.name;
var reader = new FileReader();
reader.onload = function(e) {
var attachmentbodybase64 = window.btoa(reader.result);//console log will print : ZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzB.....
console.log(attachmentbodybase64.length);
if(attachmentbodybase64.length > maxStringSize )
alert("File size is too large to handle");
else
{
j++;
saveFileAF(attachmentbodybase64, name);
}
}
reader.readAsDataURL(file);
}
else
{
console.log('this is end');
}
}
and that function called an action fcuntion method that calls the function "saveFile" on my controller:
<apex:actionFunction name="saveFileAF" action="{!saveFile}" oncomplete="uploadFiles();" status="statusSaveTrip">
<apex:param name="base64File" value="" assignTo="{!base64}"/>
<apex:param name="fileName" value="" assignTo="{!fileName}"/>
</apex:actionFunction>
My Controller has the attributes :
public String base64;
public String getBase64()
{
return base64;
}
public void setbase64(String base64)
{
this.base64 = base64;
}
public String fileName {get; set;}
**And the function that the actionFunction fire :**
public void saveFile()
{
ContentVersion testContentInsert = new ContentVersion();
testContentInsert.Title = this.filename;
testContentInsert.VersionData = Blob.valueOf(this.base64);
testContentInsert.PathOnClient = filename ;
testContentInsert.Line_Item_Id__c = 'lineItemIDDDD' ;
insert testContentInsert;
List<ContentVersion> cvList = [select id, ContentDocumentId from ContentVersion WHERE Id =:testContentInsert.Id];
Opportunity opp = [SELECT Id FROM Opportunity LIMIT 1];
System.debug('opp- > ' + opp);
ContentDocumentLink cl = new ContentDocumentLink();
cl.ContentDocumentId = cvList[0].ContentDocumentId;
cl.LinkedEntityId = opp.Id;
cl.ShareType = 'V';
cl.Visibility = 'AllUsers';
insert cl;
System.debug('this.base64- > ' + this.base64);
}
Screenshots:
Thanks