Last active
January 30, 2023 20:40
-
-
Save peterknolle/bb4b7ac63f67f66c32b0 to your computer and use it in GitHub Desktop.
Lightning File Upload Component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- 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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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"); | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
({ | |
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); | |
}); | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
({ | |
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- 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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @peterknolle @Satya738
How can we modify the code to upload a 10 MB file ?