Dec 22, 2012

Uploading Multiple Attachments into Salesforce - Simple Code

Okay, so here is the simple code to upload multiple attachments into Salesforce. Please note that I've used standard controller ("Account" in the code) so you need to pass the record Id in parameter. You can also change this according to your need as code is dynamic.

So first option allow you to select how many files you want to upload. Say, you have selected "5", then it will give you 5 options to select files and once you click on "Upload" it will upload the files as attachments to the associated record.



Visualforce Page Code:


<apex:page standardController="Account" extensions="MultipleUploadController">
    <apex:form>
        <apex:pageBlock title="Upload Multiple Attachment to Object">
            
            <apex:pageBlockButtons>
                <apex:commandButton value="Upload"  action="{!SaveAttachments}"/>
            </apex:pageBlockButtons>
            
            <apex:pageMessages id="MSG"/>
            <apex:actionFunction name="ChangeCount" action="{!ChangeCount}"/>
            
            <apex:pageblocksection>
                            
                <apex:pageBlockSectionItem>
                    <apex:outputLabel value="How many files you want to upload?"/>
                    <apex:selectList onchange="ChangeCount() ;" multiselect="false" size="1" value="{!FileCount}">
                        <apex:selectOption itemLabel="--None--" itemValue=""/>
                        <apex:selectOptions value="{!filesCountList}"/>
                    </apex:selectList>
                </apex:pageBlockSectionItem>
            
            </apex:pageblocksection>
            
            <apex:pageBlockSection title="Select Files" rendered="{!IF(FileCount != null && FileCount != '', true , false)}">
                <apex:repeat value="{!allFileList}" var="AFL">
                    <apex:inputfile value="{!AFL.body}" filename="{!AFL.Name}" />
                    <br/>
                </apex:repeat>
            </apex:pageBlockSection>
            
        </apex:pageBlock>
    </apex:form>
</apex:page>


Apex Code:


public class MultipleUploadController
{   
    //Picklist of tnteger values to hold file count
    public List<SelectOption> filesCountList {get; set;}
    //Selected count
    public String FileCount {get; set;}
    
    public List<Attachment> allFileList {get; set;}
    
    public MultipleUploadController(ApexPages.StandardController controller)
    {
        //Initialize  
        filesCountList = new List<SelectOption>() ;
        FileCount = '' ;
        allFileList = new List<Attachment>() ;
        
        //Adding values count list - you can change this according to your need
        for(Integer i = 1 ; i < 11 ; i++)
            filesCountList.add(new SelectOption(''+i , ''+i)) ;
    }
    
    public Pagereference SaveAttachments()
    {
        String accId = System.currentPagereference().getParameters().get('id');
        if(accId == null || accId == '')
            ApexPages.addmessage(new ApexPages.message(ApexPages.Severity.ERROR,'No record is associated. Please pass record Id in parameter.'));
        if(FileCount == null || FileCount == '')
            ApexPages.addmessage(new ApexPages.message(ApexPages.Severity.ERROR,'Please select how many files you want to upload.'));

        List<Attachment> listToInsert = new List<Attachment>() ;
        
        //Attachment a = new Attachment(parentId = accid, name=myfile.name, body = myfile.body);
        for(Attachment a: allFileList)
        {
            if(a.name != '' && a.name != '' && a.body != null)
                listToInsert.add(new Attachment(parentId = accId, name = a.name, body = a.body)) ;
        }
        
        //Inserting attachments
        if(listToInsert.size() > 0)
        {
            insert listToInsert ;
            ApexPages.addmessage(new ApexPages.message(ApexPages.Severity.INFO, listToInsert.size() + ' file(s) are uploaded successfully'));
            FileCount = '' ;
        }
        else
            ApexPages.addmessage(new ApexPages.message(ApexPages.Severity.ERROR,'Please select at-least one file'));
            
        return null;
    }
    
    public PageReference ChangeCount()
    {
        allFileList.clear() ;
        //Adding multiple attachments instance
        for(Integer i = 1 ; i <= Integer.valueOf(FileCount) ; i++)
            allFileList.add(new Attachment()) ;
        return null ;
    }
}


You can enhance the code if you like, as I've provided the basic code which is re-usable. Also you can change the object passed in standard controller and code will handle the rest. URL should have ID else you will get error on UI :-)

Say, I've saved my VFP code as "MultipleUpload", so my URL will be https://...../apex/MultipleUpload?id=XXXXXXXXXXXXXXX (account id in this code).

Happy Coding.

16 comments:

  1. Thanks so much for this sample. I am pre-populating number of files base on value in my custom object. Working very well. This code save lot of time for me.

    ReplyDelete
  2. Hi Ankit,

    Thanks so much for your sample programs.

    Please add the one more condition in MultipleUploadController class at line number 56.
    In this case it will throws error.
    Case : let us assume A user select the "2" from the pick list, it is working fine.But if A user select again "None" then it will throws the following error.

    ------------------------
    System.NullPointerException: Argument 1 cannot be null
    Error is in expression '{!ChangeCount}' in component in page multiplefilesupload

    Class.MultipleUploadController.ChangeCount: line 57, column 1
    -------------------------------------------------

    Solution:
    ---------
    if(FileCount != Null)
    for(Integer i = 1 ; i <= Integer.valueOf(FileCount) ; i++)
    allFileList.add(new Attachment()) ;

    ReplyDelete
  3. Is there a way to restrict or check the attachment using ContentType field in attachment object?

    ReplyDelete
  4. I am getting the following error when trying upload file with 2MB (during testing) Any suggestions on how I can use "transient" with this example
    Maximum view state size limit (135KB) exceeded. Actual view state size for this page was 1,287.984KB

    ReplyDelete
    Replies
    1. Even I am getting this error, please help.

      Delete
    2. Hi, I think you should add on line# 38. So the list is empty, it will drop the view state size.

      allFileList.clear();

      Delete
  5. While uploading the document i am getting the following error. System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Parent]: [Parent]
    Error is in expression '{!SaveAttachments}' in page multiupload

    Class.MultipleUploadController.SaveAttachments: line 42, column 1. How can i solve that ?

    ReplyDelete
    Replies
    1. Pass account id in the URL and then attache the file and upload it.

      Delete
  6. Hi - This code has helped me a lot, thank you. Would you have a test class so I can migrate it to production, I am struggling to write one that tests enough lines. Kind regards Ciaran Hayden

    ReplyDelete
  7. Hi Ankit,
    It's all working fine . But when i am going to insert 8-10 attachments i am getting " view state size limit (135KB) exceeded" So how can i over come this error and insert max number of attachments required.

    ReplyDelete
    Replies
    1. Yes Ankit,

      Even I am getting this error please suggest

      Delete
  8. How can I use this code to either create a new account with attachments or add the files to an existing account?

    ReplyDelete
  9. I'm sorry, what part of the code does the URL get inserted to?

    I am getting the same error as above.

    System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Parent]: [Parent]
    Error is in expression '{!SaveAttachments}' in page multiupload

    ReplyDelete
  10. This comment has been removed by the author.

    ReplyDelete
  11. this code helps me so much while creating new case with multiple attachments.

    ReplyDelete
  12. Thanks so much for this sample Code..... :)

    ReplyDelete