'Uploading Multiple Files in Salesforce through Visualforce

I would like to upload multiple files in Salesforce using visualforce. I can upload one file at a time.

But my requirement is, i want to display only one "add a file" button in visualforce page, when clicked over that button browse window should open and user selects a particular file and adds it. But after adding a file, the file path should be displayed as well as the same "add a file" button should be displayed below that which allows us to add another file. And after that we can save what we have added. It is same as adding attachments in our email.

Any help regarding this will be appreciated.



Solution 1:[1]

<!-- Use uploadFile function to attach multiple attachment.Update hardcoded parent id.-->  

  <apex:page>
            <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
        <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
            <script type="text/javascript">
                var __sfdcSessionId = '{!GETSESSIONID()}';
                var filesToUpload = [];  
                var uploadedFile = 0;
            </script>
            <style>
              .FilebuttonStyle{      
                  font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;
                  font-size:13px`enter code here`;color:#ffffff;
                  background-color: #169fcc !important;
                  text-decoration:none;
                  text-align:center;
                  border:1px solid #1691ba !important;
                  line-height: 25px;!important;
                  border-radius:4px;
                  display:inline-block;
                  cursor:pointer;
                  width:85px;
              }

            td.fileRow {
                  overflow: hidden;
                  font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;
                  font-size:13px;color:#ffffff;
                  background-color: #8db728;
                  text-decoration:none;
                  text-align:center;
                  border:1px solid #6c8049;
                  line-height: 32px;!important;
                  border-radius:4px;
                  //padding-left:10px;
                  //padding-right:10px;
                  background-image:linear-gradient(top,#9dcc3d,#7da223);
                  background-image:-o-linear-gradient(top,#9dcc3d,#7da223);
                  background-image:-moz-linear-gradient(top,#9dcc3d,#7da223);
                  background-image:-webkit-linear-gradient(top,#9dcc3d,#7da223);
                  background-image:-ms-linear-gradient(top,#9dcc3d,#7da223);
                  display:inline-block;
                  cursor:pointer;
                  width:120px;
                  overflow: hidden;
        }

        td.fileRow  input {
            display: block !important;
            width: 157px !important;
            height: 57px !important;
            opacity: 0 !important;
            overflow: hidden !important;
        }
          .fileCheckBox {
               width: 16px;
            height: 16px;
            display: inline-block;
            margin: 3px 5px 3px 3px;
            background-color: white;
                //box-shadow: 0px 0px 1px #b0b3ae;
            text-align: center;
            vertical-align: top; 
           }

                .FilebuttonGroup{
                 float:right;
                padding-right: -70px!important;
                }
            </style>   
            <script src="/soap/ajax/32.0/connection.js" type="text/javascript"></script>

            <script type="text/javascript">

            function uploadFile(parentId)
                {


                   // var input = $('.fileInput')[0];
                    //var input = document.getElementById("file-input");
                   // var filesToUpload = input.files;

                    $("input[type=file]").each(function(){

                      filesToUpload.push($(this)[0].files[0]);
                    });
                    //console.log(filesToUpload);
                     for(var i = 0, f; f = filesToUpload[i]; i++)
                    {
                        var reader = new FileReader();

                        // Keep a reference to the File in the FileReader so it can be accessed in callbacks
                        reader.file = f;

                        reader.onload = function(e)
                        {
                            var att = new sforce.SObject("Attachment");
                            att.Name = this.file.name;
                            att.ContentType = this.file.type;
                            att.ParentId = parentId;

                            var binary = "";
                            var bytes = new Uint8Array(e.target.result);
                            var length = bytes.byteLength;

                            for (var i = 0; i < length; i++)
                            {
                                binary += String.fromCharCode(bytes[i]);
                            }

                            att.Body = (new sforce.Base64Binary(binary)).toString();

                            sforce.connection.create([att],
                            {
                                onSuccess : function(result, source)
                                {
                                    if (result[0].getBoolean("success"))
                                    {
                                        console.log("new attachment created with id " + result[0].id);
                                    }
                                    else
                                    {
                                        console.log("failed to create attachment " + result[0]);
                                    }
                                },
                                onFailure : function(error, source)
                                {
                                    console.log("an error has occurred " + error);
                                }
                            });
                        };

                        reader.readAsArrayBuffer(f);
                    }


                }               



              function addRow(tableID){                

                  var row = '<tr><td><input type="checkbox" onclick="processCheckbox()" name="chk" class="fileCheckBox"/</td><td class="fileRows"><input type="file"/> </td></tr>';
                $('#'+tableID).append(row);  


              }

            function deleteRow(tableID)
            {    
                try
                {
                    var table=document.getElementById(tableID);
                    var rowCount=table.rows.length;
                    for(var i=0;i<rowCount;i++)
                    {

                        var row=table.rows[i];
                        var chkbox=row.cells[0].childNodes[0];
                        if(null!=chkbox&&true==chkbox.checked)
                        {
                            table.deleteRow(i);

                            filesToUpload.splice(i, 1);
                            // console.log(filesToUpload);

                            rowCount--;
                            i--;
                        }
                    }
                    processCheckbox();
                 }
                 catch(e)
                 {
                     alert(e);
                 }
             }

            function processCheckbox(){
                   $("[id$='_remove']").hide();
                  var checkCount=0;
                    $("#dataTable input[type='checkbox']").each(function(){
                    if($(this).is(':checked'))
                    {
                        checkCount++;
                    }
                   });
                  if(checkCount >0){
                       $("[id$='_remove']").show();
                  }

                }
          </script>
              <div class="FilebuttonGroup">
                <input type="button" value="Delete Row" id="_remove" onclick="deleteRow('dataTable')"  class="FilebuttonStyle" title="Delete Row"/>

                <input type="button" value="Add Row" onclick="addRow('dataTable')" id="_add"   class="FilebuttonStyle" title="Add Row"/>
               </div>   
                <table id="dataTable"  >      
                    <tbody>
                        <tr>
                            <td> </td>
                            <td class="fileRows"> <input type="file" class="fileInput"/> </td>
                            <td></td>
                        </tr>
                    </tbody>       
                </table>
                                                                        <!--Correct this attachment parentid -->
                <input type="button" value="Upload" onclick="uploadFile('5009000000cjeZn')"  title="Upload"/>



            <div id="statusid"></div>

            <script>
                $(document).ready(function(){
                     $("[id$='_remove']").hide();
                     $("[id$='attachmentBlock']").find('.pbSubsection').attr({'style':'margin-right:-70px !important;'});
                 });

            </script>

    </apex:page>

Solution 2:[2]

You can upload multiple attachment using ajax asynchronously. You need to update the parent record id of attachment. Find the code at:

https://github.com/DebGit/Dev_2015_org1/blob/master/src/pages/FileUploaderAjax.page

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Shepmaster