+ Start a Discussion
Molson94Molson94 

Multiple File Upload Through REST API in Visualforce?

Hello,

Looking for some help/direction on the best way to handle file uploads in a Visualforce page.
I have a page that works fine using <apex:inputFile> but as we know this only supports 1 file at a time.
This creates a poor user experience for my use case since the users will have to click "browse" for each <apex:inputFile> on the page.

Has anyone been able to solve for multiple files being uploaded by use the REST API and jQuery/XHR in a visualforce page?
I have only seen a few raw examples but nothing complete to be able to research.

Thanks in advance.
Molson94Molson94
To add some more context to this question, I have been playing with the following resources to try and get this to work but it is not clear to me what needs to go in the xhr.open(); method.

https://salesforce.stackexchange.com/questions/49795/upload-a-file-using-apexactionfunction-integrated-with-jquery
https://stackoverflow.com/questions/6211145/upload-file-with-ajax-xmlhttprequest

Here is the code so far, nothing seems to be happening, and the request is not going through.

Visualforce Page
<apex:page standardStylesheets="false" sidebar="false" showHeader="false" title="API File Uploader Test" >
    <apex:stylesheet value="{!URLFOR($Resource.Bootstrap, 'bootstrap-3.3.6-dist/css/bootstrap.css')}"/>
    <apex:includeScript value="//code.jquery.com/jquery-2.1.4.min.js"/> 
    
    <script>
    $(document).ready(function(){
        var clickerButton = document.getElementById('upload');
        clickerButton.addEventListener('click', function() {
            var testParentID = "a0b3D000000gsvM";
            var file = $("#uploadedFiles")[0].files[0];
            var xhr = new XMLHttpRequest();
            
            
            xhr.file = file; 
            xhr.open('post', ''); 
//this is required before setRequestHeader but I am not clear what to put as the URL parameter
            xhr.setRequestHeader('Authorization', 'Bearer {!$Api.Session_ID}');
            xhr.setRequestHeader('SalesforceProxy-Endpoint', 'https://' + window.location.toString().split('.')[1] + '.salesforce.com/services/apexrest/FileUpload/v1/upload?id=' + testParentID + '&filename=' + encodeURIComponent(file.name));
            
            
            alert(xhr.getResponseHeader("SalesforceProxy-Endpoint"));
            xhr.send(file);
        }, false);
    });
    </script>
    <apex:form>
        <div class="container">
            <h1>
                File Upload through API Test...
            </h1>
            <div class="form-group">
                <label>
                    Upload a file(s)                
                </label>
                <input type="file" id="uploadedFiles" class="form-control" multiple="true" />
                <a class="btn-sm btn-success" id="upload">+ Select Files</a>
            </div>
        </div>
    </apex:form>
</apex:page>

And the simple class to handle the incoming request:
 
@RestResource(urlMapping='/FileUpload/v1/*')
global class FileUploadController
{
    @HttpPost
    global static Attachment attachPic(){
        RestRequest req = RestContext.request;
        Blob data = req.requestBody;
        String name = RestContext.request.params.get('filename');
        String parentID = RestContext.request.params.get('id');
        system.debug(Name);
        system.debug(parentID);

        Attachment a = new Attachment (ParentId = parentID,
                                       Body = data,
                                       Name = name);
        insert a;
        return [Select Id, ParentId, BodyLength, Name, ContentType from Attachment Where Id = :a.Id];
    }
}