0

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...

VF

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

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

        <br/><br/><br/>
        <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:pageBlockSection>
        </apex:pageBlock>
        <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>  
                   <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>  
                       </span>  
                     </div>  
                   </div><br/>  
                   <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>  
                 <div id="uploadedrec" style="padding:10px;">  
                   <span id="records" style=" color:green; ">  
                   </span>  
                 </div>  
               </div>
            </apex:pageBlockSection>
            <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:outputPanel>
                </apex:outputPanel>
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
  </body>  
 </html>  
</apex:page>

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');
            editpage.setRedirect(true);
            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.