⚡ Lightning – File upload with a title using “lightning:fileUpload”

Lightning File Uploader Component:

giphy

I am writing this blog post just because, I faced a problem while working with the standard file uploader component, the problem is when you upload the file using the standard component there is no way to enter the file Name or Title, it automatically gets the file name and updates the Title with that file name, but sometimes users want to enter the specific Name or Title, in that case, we can not do that with the standard component.

Advertisements

The first thing that comes to my mind to solve this problem is if anyhow I get the details of the file before upload then I can change the file Title with the user entered name but no luck, there is no action defined for before upload in lightning:fileUpload documentation.

But, lightning:fileUpload component provides ‘onuploadfinished‘ (The action triggered when files have finished uploading.) action, we can call the action (Method) after the file uploading is finished and can get the details of files that just uploaded, after that, we can change the Title of File based on the user entered Title.

Below are the Lightning component codes that I have developed to solve the problem that I was facing.

FileUploaderCmp:

<aura:component controller="SimplyfyFilesCntrl" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="files" type="ContentDocument[]"/>
<aura:attribute name="recordId" type="string"/>
<aura:attribute name="accept" type="List" default="['.jpg', '.jpeg','.pdf','.csv','.xlsx']"/>
<aura:attribute name="multiple" type="Boolean" default="true"/>
<aura:attribute name="disabled" type="Boolean" default="false"/>
<div class="slds">
<div style="border-left: 1px solid rgb(221, 219, 218);
border-right: 1px solid rgb(221, 219, 218);
border-bottom: 1px solid rgb(221, 219, 218);
border-top: 1px solid rgb(221, 219, 218);">
<div class="slds-page-header" style="border-radius: 0px; border-right: 0px;border-left: 0px;border-top: 0px;
box-shadow: 0 0px 0px 0 rgba(0, 0, 0, 0.1);">
Files
</div>
<div class="slds-grid">
<div class="slds-col slds-size--5-of-12">
<lightning:input type="text" name="input1" label="Enter File Name" aura:id="fileName" />
</div>&nbsp; &nbsp;
<div class="slds-col slds-size---of-12">
<lightning:fileUpload label="" multiple="{!v.multiple}"
accept="{!v.accept}" recordId="{!v.recordId}"
onuploadfinished="{!c.UploadFinished}" />
</div>
</div><br/>
<table class="slds-table slds-table--bordered">
<thead>
<tr>
<th>Title</th>
<th>FileType</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.files}" var="f">
<tr>
<td> <a href="" id="{!f.Id}" onclick="{!c.OpenFile}">{!f.Title}</a></td>
<td>{!f.FileType}</td>
<td>{!f.Description}</td>
</tr>
</aura:iteration>
</tbody>
</table>
</div>
</div>
</aura:component>
view raw FileUploaderCmp hosted with ❤ by GitHub

FileUploaderCmpController:

({
doInit:function(component,event,helper){
var action = component.get("c.getFiles");
action.setParams({
"recordId":component.get("v.recordId")
});
action.setCallback(this,function(response){
var state = response.getState();
if(state=='SUCCESS'){
var result = response.getReturnValue();
console.log('result: ' +result);
component.set("v.files",result);
}
});
$A.enqueueAction(action);
} ,
//Open File onclick event
OpenFile :function(component,event,helper){
var rec_id = event.currentTarget.id;
$A.get('e.lightning:openFiles').fire({ //Lightning Openfiles event
recordIds: [rec_id] //file id
});
},
UploadFinished : function(component, event, helper) {
var uploadedFiles = event.getParam("files");
var documentId = uploadedFiles[0].documentId;
var fileName = uploadedFiles[0].name;
helper.UpdateDocument(component,event,documentId);
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
"title": "Success!",
"message": "File "+fileName+" Uploaded successfully."
});
toastEvent.fire();
/* Open File after upload
$A.get('e.lightning:openFiles').fire({
recordIds: [documentId]
});*/
},
})

FileUploaderCmpHelper:

({
UpdateDocument : function(component,event,Id) {
var action = component.get("c.UpdateFiles");
var fName = component.find("fileName").get("v.value");
//alert('File Name'+fName);
action.setParams({"documentId":Id,
"title": fName,
"recordId": component.get("v.recordId")
});
action.setCallback(this,function(response){
var state = response.getState();
if(state=='SUCCESS'){
var result = response.getReturnValue();
console.log('Result Returned: ' +result);
component.find("fileName").set("v.value", " ");
component.set("v.files",result);
}
});
$A.enqueueAction(action);
},
})

SimplyfyFilesCntrl:

public class SimplyfyFilesCntrl {
@AuraEnabled
public static List<ContentDocument> getFiles(string recordId){
List<ContentDocument> DocumentList = new List<ContentDocument>();
Set<Id> documentIds = new Set<Id>(); //store file ids
List<ContentDocumentLink> cdl=[select id,LinkedEntityId,ContentDocumentId from ContentDocumentLink where LinkedEntityId=:recordId];
for(ContentDocumentLink cdLink:cdl){
documentIds.add(cdLink.ContentDocumentId); // Document ids
}
DocumentList = [select Id,Title,FileType,ContentSize,Description from ContentDocument where id IN: documentIds];
return DocumentList;
}
@AuraEnabled
public static List<ContentDocument> UpdateFiles(string documentId,string title,string recordId){
system.debug('title: ' +title);
ContentDocument cd = [select id,title from ContentDocument where Id=:documentId]; // Getting files from Parent record
cd.Title = title; // Changing file Title with user entered title
try{
update cd; // Update ContentDocument (File)
}
catch(DMLException e){
system.debug('Exception has occurred! ' +e.getMessage());
}
List<ContentDocument> DocumentList = new List<ContentDocument>();
Set<Id> documentIds = new Set<Id>();
List<ContentDocumentLink> cdl=[select id,LinkedEntityId,ContentDocumentId from ContentDocumentLink where LinkedEntityId=:recordId];
for(ContentDocumentLink cdLink:cdl){
documentIds.add(cdLink.ContentDocumentId);
}
DocumentList = [select Id,Title,FileType,ContentSize,Description from ContentDocument where id IN: documentIds];
return DocumentList; // Return list of files on parent record
}
}

Advertisements

👉 Steps to create quick Action:

  • Go to object manager and click on the Object for that you want to create ‘New Action’.
  • Click on ‘Buttons Links and Action’ and then click on the ‘New Action’ button.
  • Select the ‘Action Type’ Lightning Component.
  • Select the Lightning Component that you just created.
  • Enter Label and Name and click on the Save button.
  • Go to the object page layout and add this action there

Enter the file name and upload the file.

1
2

👉 Uploaded files. If you click on uploaded files it will open in the SVG file preview player in lightning experience.

3
4

Join 242 other subscribers
Advertisements
Advertisements

Arun Kumar

Arun Kumar is a Salesforce Certified Platform Developer I with over 7+ years of experience working on the Salesforce platform. He specializes in developing custom applications, integrations, and reports to help customers streamline their business processes. Arun is passionate about helping businesses leverage the power of Salesforce to achieve their goals.

This Post Has 7 Comments

  1. Deved

    I think you missed uploading the helper. Since both files appear to be same. If you can upload that it would be really helpful.

    1. Arun Kumar

      Oh! Yes, I just updated the “FileUploaderCmpHelper” code.

      Thanks, Deved.

      1. raja

        Hi Arun ,I like yr post .Do you have any example to upload file to outside of Salesforce without saving ContentDocument object? We have REST service to call from Apex controller after browse files from local drive.
        And also I need mark files as private/public checkbox in the table selection.
        I really appreciate iif you code send some code for helper to call.

  2. Kalaiselvan G

    Hi Arun, The update query is not working for normal users. It is running only for Administrator. Any solution for this issue

  3. susmitha

    Hi Arun, Your multiple file uploading component helped a lot for my requirement.. Do you have test class for this

  4. Rose

    Hi Arun,
    Thanks for sharing this code.

    I have an urgent question, I’m using the “lightning:fileUpload” tag in a lightning component, and in the UploadFinished function I’d like to get the base64 content of the loaded file in order to set it as ContentVersion.VersionData.
    I used FileReader for this purpose and then I used btoa(reader.result) to get the base64 encoded data, but it doesn’t work. it says parameter1 is not of type Blob.
    Do you have any idea how can I do that?

  5. Rose

    Hi Arun,
    Thanks for sharing this code.

    I have an urgent question, I’m using the “lightning:fileUpload” tag in a lightning component, and in the UploadFinished function I’d like to get the binary content of the loaded file in order to set it as ContentVersion.VersionData and save the uploaded file in Salesforce.
    I used FileReader.readAsBinaryString(file) for this purpose, but it doesn’t work. it says parameter1 is not of type Blob.
    Do you have any idea how I can do that?
    Thank you.

Leave a Reply