-
-
Save peterknolle/bb4b7ac63f67f66c32b0 to your computer and use it in GitHub Desktop.
public class FileController { | |
@AuraEnabled | |
public static Id saveTheFile(Id parentId, String fileName, String base64Data, String contentType) { | |
base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8'); | |
Attachment a = new Attachment(); | |
a.parentId = parentId; | |
a.Body = EncodingUtil.base64Decode(base64Data); | |
a.Name = fileName; | |
a.ContentType = contentType; | |
insert a; | |
return a.Id; | |
} | |
@AuraEnabled | |
public static Id saveTheChunk(Id parentId, String fileName, String base64Data, String contentType, String fileId) { | |
if (fileId == '') { | |
fileId = saveTheFile(parentId, fileName, base64Data, contentType); | |
} else { | |
appendToFile(fileId, base64Data); | |
} | |
return Id.valueOf(fileId); | |
} | |
private static void appendToFile(Id fileId, String base64Data) { | |
base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8'); | |
Attachment a = [ | |
SELECT Id, Body | |
FROM Attachment | |
WHERE Id = :fileId | |
]; | |
String existingBody = EncodingUtil.base64Encode(a.Body); | |
a.Body = EncodingUtil.base64Decode(existingBody + base64Data); | |
update a; | |
} | |
} |
<!-- fileUpload2.cmp is identical --> | |
<aura:component controller="paura.FileController"> | |
<aura:attribute name="parentId" type="Id"/> | |
<aura:handler event="aura:waiting" action="{!c.waiting}"/> | |
<aura:handler event="aura:doneWaiting" action="{!c.doneWaiting}"/> | |
<div class="container"> | |
<input type="file" class="file" aura:id="file" /> | |
<ui:button label="Save" press="{!c.save}"/> | |
<div aura:id="uploading" class="notUploading"> | |
<img src="/resource/paura__images/loading-gray.gif" alt="uploading" class="small-spinner" /> Uploading... | |
</div> | |
</div> | |
</aura:component> |
/* fileUpload2.css is identical */ | |
.THIS .notUploading { | |
visibility: hidden; | |
} | |
.THIS .uploading { | |
visibility: visible; | |
display: inline-block; | |
margin-top: 10px; | |
} | |
.THIS .small-spinner { | |
height: 20px; | |
width: 20px; | |
} | |
.THIS .file { | |
margin-bottom: 5px; | |
display: block; | |
} |
/* fileUploadController2.js is identical */ | |
({ | |
save : function(component, event, helper) { | |
helper.save(component); | |
}, | |
waiting: function(component, event, helper) { | |
$A.util.addClass(component.find("uploading").getElement(), "uploading"); | |
$A.util.removeClass(component.find("uploading").getElement(), "notUploading"); | |
}, | |
doneWaiting: function(component, event, helper) { | |
$A.util.removeClass(component.find("uploading").getElement(), "uploading"); | |
$A.util.addClass(component.find("uploading").getElement(), "notUploading"); | |
} | |
}) |
({ | |
MAX_FILE_SIZE: 750 000, /* 1 000 000 * 3/4 to account for base64 */ | |
save : function(component) { | |
var fileInput = component.find("file").getElement(); | |
var file = fileInput.files[0]; | |
if (file.size > this.MAX_FILE_SIZE) { | |
alert('File size cannot exceed ' + this.MAX_FILE_SIZE + ' bytes.\n' + | |
'Selected file size: ' + file.size); | |
return; | |
} | |
var fr = new FileReader(); | |
var self = this; | |
fr.onload = function() { | |
var fileContents = fr.result; | |
var base64Mark = 'base64,'; | |
var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length; | |
fileContents = fileContents.substring(dataStart); | |
self.upload(component, file, fileContents); | |
}; | |
fr.readAsDataURL(file); | |
}, | |
upload: function(component, file, fileContents) { | |
var action = component.get("c.saveTheFile"); | |
action.setParams({ | |
parentId: component.get("v.parentId"), | |
fileName: file.name, | |
base64Data: encodeURIComponent(fileContents), | |
contentType: file.type | |
}); | |
action.setCallback(this, function(a) { | |
attachId = a.getReturnValue(); | |
console.log(attachId); | |
}); | |
$A.run(function() { | |
$A.enqueueAction(action); | |
}); | |
} | |
}) |
({ | |
MAX_FILE_SIZE: 4 500 000, /* 6 000 000 * 3/4 to account for base64 */ | |
CHUNK_SIZE: 950 000, /* Use a multiple of 4 */ | |
save : function(component) { | |
var fileInput = component.find("file").getElement(); | |
var file = fileInput.files[0]; | |
if (file.size > this.MAX_FILE_SIZE) { | |
alert('File size cannot exceed ' + this.MAX_FILE_SIZE + ' bytes.\n' + | |
'Selected file size: ' + file.size); | |
return; | |
} | |
var fr = new FileReader(); | |
var self = this; | |
fr.onload = function() { | |
var fileContents = fr.result; | |
var base64Mark = 'base64,'; | |
var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length; | |
fileContents = fileContents.substring(dataStart); | |
self.upload(component, file, fileContents); | |
}; | |
fr.readAsDataURL(file); | |
}, | |
upload: function(component, file, fileContents) { | |
var fromPos = 0; | |
var toPos = Math.min(fileContents.length, fromPos + this.CHUNK_SIZE); | |
// start with the initial chunk | |
this.uploadChunk(component, file, fileContents, fromPos, toPos, ''); | |
}, | |
uploadChunk : function(component, file, fileContents, fromPos, toPos, attachId) { | |
var action = component.get("c.saveTheChunk"); | |
var chunk = fileContents.substring(fromPos, toPos); | |
action.setParams({ | |
parentId: component.get("v.parentId"), | |
fileName: file.name, | |
base64Data: encodeURIComponent(chunk), | |
contentType: file.type, | |
fileId: attachId | |
}); | |
var self = this; | |
action.setCallback(this, function(a) { | |
attachId = a.getReturnValue(); | |
fromPos = toPos; | |
toPos = Math.min(fileContents.length, fromPos + self.CHUNK_SIZE); | |
if (fromPos < toPos) { | |
self.uploadChunk(component, file, fileContents, fromPos, toPos, attachId); | |
} | |
}); | |
$A.run(function() { | |
$A.enqueueAction(action); | |
}); | |
} | |
}) |
<!-- This is a simple app that shows how the component can be used. | |
The Id could be passed in via URL or some other mechanism. | |
This is just for testing. | |
--> | |
<aura:application> | |
<div class="container"> | |
<!--<paura:fileUpload parentId="0013020s006DqaI"/>--> | |
<paura:fileUpload2 parentId="0013020s006DqaI"/> | |
</div> | |
</aura:application> |
HI Peter , How can we add a file which have file size 10 MB?
The code has two places to update BEFORE YOU USE IT:
-
Change CHUNK_SIZE to a smaller number:
CHUNK_SIZE: 450 000, /* Use a multiple of 4 */
-
Add $A.getCallback() to the async file reader onload event:
fr.onload = $A.getCallback(function() {
var fileContents = fr.result;
var base64Mark = 'base64,';
var dataStart = fileContents.indexOf(base64Mark) + base64Mark.length;
fileContents = fileContents.substring(dataStart);
self.upload(component, file, fileContents);
});
- Delete $A.run() since it's not supported anymore
Change
$A.run(function() {
$A.enqueueAction(action);
});
TO
$A.enqueueAction(action);
How can I make the user load attachments when using this on a form?
why do you have 2 helper classes?
I'm getting below error on save.
'TypeError: $A.run is not a function[Learn More] safeEval.html:63:9
VIC$FileUploadCompt.helper.upload components/VIC/FileUploadCompt.js:63:9
VIC$FileUploadCompt.helper.save/fr.onload'
Any Idea ?
Hi @lushang, I have implemented this code to upload file size upto 4mb. But when i trying to upload file size 1.3mb getting error
'Input too long. [1, 173]' . Can you please help.
Hi @lushang, After attachments are uploading twice for me after double clicking the save button.If i click once the save button i did not see anything is uploaded.Can you please assist on your code??
hey iam getting below error please rectify........
aura_proddebug.js:24605 Uncaught TypeError: Cannot read property 'upload' of undefined
throws at components/c/upload.js:24:15 TypeError: Cannot read property 'upload' of undefined
at FileReader.fr.onload (components/c/upload.js:24)
o erro ainda continua
How can we modify the code to upload a 10 MB file ?
How can we add a file which have file size 10 MB?