I'd like to provide a multiple file upload module on a public visualforce page and I'm struggling with the upload process. As the upload process requires to have a record ID, how can I save the uploaded files into a temporary location until the form is submitted and record ID is retrieved? Or is it a better way/best practice to do this?

Current VF/JS code tries to save straight without record ID. Shall I remove upload button and perform upload on same time as Save button is hit? Then perform the save through the Apex controller? I'm quite new in VF/Apex coding...


    <apex:page standardController="Feedback__c" showHeader="false" extensions="extencntrl">
       <apex:slds />  
       <apex:includeScript value="https://code.jquery.com/jquery-2.2.4.js"/>  
       //function starts  
         var fileLenght=0;  
         $('#uploadBtn').click(function() {  
           var v=document.getElementById('addr');  
           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   
               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  
                 console.log('Ids: ' +ids);  
                 $('#records').html('File has been uploeded. Uploaded File ids: ' +ids);  
                 if(fileLenght == FileUploaded ){   
                 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);  

         .slds-scope .slds-page-header{  
         border-radius: 0px;  
         box-shadow: 0 0px 0px 0 rgba(0, 0, 0, 0.1);  
            background-color: white;
            border-width: 2px;
            border-style: solid;
            z-index: 9999;
            left: 50%;
            position: absolute;
            width: 500px;
            margin-left: -250px;
            opacity: 0.20;
            filter: alpha(opacity = 20);
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            z-index: 9998;
    <apex:form id="HFF">

        <apex:pageBlock title="part1">
            <apex:pageBlockSection columns="1">
                <apex:inputField value="{!Feedback__c.p1__c}" style="width: 360px; height: 20px"/>    
                <apex:inputField value="{!Feedback__c.p2__c}" style="width: 360px; height: 20px"/>
                <apex:inputField value="{!Feedback__c.p3__c}" style="width: 360px; height: 20px"/>
                <apex:inputField value="{!Feedback__c.p4__c}" style="width: 360px; height: 20px"/>
                <apex:inputField value="{!Feedback__c.p5__c}" style="width: 360px; height: 20px"/>

        <apex:pageBlock title="Comments">
            <apex:pageBlockSection columns="1">
                <p> Description
                <apex:inputField value="{!Feedback__c.t1__c}" label="t1 details..." style="width: 360px; height: 60px" />    </p>
                <p> t2    <apex:inputField value="{!Feedback__c.t2__c}" label="t2?" style="width: 360px; height: 60px" /></p>
                <p> t3 : Please attach pictures  </p>
                <div class="slds" style="border:1px solid #D9D9D9;pointer-events: none;">  
                   <div class="slds-page-header">  
                     <span style=""> Upload Files</span>  
                   <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>  
                   <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 id="uploadedrec" style="padding:10px;">  
                   <span id="records" style=" color:green; ">  
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!showPopup}" status="go" disabled="false" rerender="gjpopup"/>
                <apex:outputPanel id="gjpopup">
                    <apex:outputPanel styleClass="popupBackground" layout="block" rendered="{!displayPopUp}"/>
                    <apex:outputPanel styleClass="custPopup" layout="block" rendered="{!displayPopUp}">
                        Thank you, you have successfully submitted the form <br/><br/><br/>
                        <apex:commandButton value="Close" action="{!SaveForm24HFF}" rerender="gjpopup"/>

Apex extension

public with sharing class extencntrl{

    private ApexPages.StandardController sc;
    public extencntrl(ApexPages.StandardController sc) {   
        this.sc = sc;

    public boolean displayPopup {get; set;}     

    public void closePopup() {  
        displayPopup = false;

    public void showPopup() {        
        displayPopup = true;


    public PageReference SaveForm24HFF() {
        PageReference detailPage = sc.Save();
        if (detailPage != null) { 
            PageReference editpage = new PageReference('http://test.mydomain.com/test');
            return editpage;
        } else {
            return null;

I've looked for samples but none worked/suited my need. Any ideas or suggestions on how I should tackle this? Looking forward to hearing from you. Cheers.

  • Have you considered inserting the record first, and then prompting the user to upload the files? – David Cheng Dec 10 '19 at 16:10
  • No, because it's a kind of satisfaction form. However, your suggestion could work if I replace the visualforce page by a Flow? First page, some fields with questions, then Button Next => record is created => Object record ID is retrieved and file upload can be done. What do you think? Would you do it differently? – poypoy Dec 19 '19 at 19:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.