Thursday, April 26, 2012

Uploading an Attachment using Visualforce and a Custom Controller in Salesforce

Upload a file as an Attachment to a record using Visualforce and Extensions


In Salesforce we can easily upload a file through attachment by simply making and an extension on any object and using Visualforce page for inserting a new attachment.

Goal:--Our goal is that we want to make a custom button on account and then by onclick on this custom button which is there on detail page of any individual account  we are redirected to a page which is designed for inserting a new attachment and onclick on "upload Attachment" button on VF Page Parent Window is reloaded through JavaScript and Child window Close automatically.

Finally we easily see this attachment on page in notes and attachment Section on the page and inspite of this there is a custom page is there is also for designing "Notes & Attachment" related list through page in which we also have Serial no. corresponding to each record implement there by use of Wrapper Class. 

 So finally We have :--

 Step 1:--- 

1. Apex Class ===> Have Wrapper Class and Code for making Custom "Notes & Attachment" related list (which is show on page by editing page Layout ) and here have a extension (therefore we can now use Custom Button functionality)

2. Now Page is designed for  Custom "Notes and Attachment" related List.

 Note:--- In case of Custom "Notes & Attachment" related list for data Parent is required therefore extension comes in existence.

Code :---

Apex Class:---

public class NotesAttachmentModelController{
    public List<Attachment> attachmentList{set;get;}
    public List<Account> allAccounts{get;set;}
    public List<AttachmentModel> modelList{get;set;}
    public Integer srNo{get;set;}
    Account acc;
    public NotesAttachmentModelController(ApexPages.StandardController sc){
        acc = (Account)sc.getRecord();
        allAccounts = [SELECT id,name from account where id=:acc.id];
        attachmentList = [SELECT id,name,ContentType,OwnerId,ParentId from Attachment
                           where ParentId =: acc.id];
        system.debug('#################### value in Attachment List'+attachmentList);
        srNo=0;
        integer  i =0;
        modelList = new List<AttachmentModel>();
        for(Attachment att : attachmentList){
            AttachmentModel am = new AttachmentModel();
            am.srno = ++i;
            am.att = att;
            modelList.add(am);
        }
    }
    public class AttachmentModel{
        public Integer srNo{get;set;}
        public Attachment att{get;set;}
        public AttachmentModel(){
            srNo = 0;
            att = new Attachment();
             
        }
    }
}
 
 
 
Page:----
  
<apex:page standardController="Account" extensions="NotesAttachmentModelController">
  <apex:form >
      <apex:pageBlock title="Notes & Attachment">
      <apex:pageBlockButtons >
          <apex:commandButton value="Add Note"/>
          <apex:commandButton value="Attach Fil"/>
          <apex:commandButton value="View All"/>
      </apex:pageBlockButtons>
          <apex:pageBlockTable value="{!modelList}" var="mod">
              <apex:column headerValue="Srno" value="{!mod.srno}"/>
              <apex:column value="{!mod.att.name}" headerValue="Name"/>
              <apex:column headerValue="Type">
              <apex:outputText value="{!mod.att.ContentType}"/>
              </apex:column>
              <apex:column headerValue="Owner">
              <apex:outputText value="{!mod.att.OwnerId}"/>
              </apex:column> 
              <apex:column headerValue="ParentId">
              <apex:outputText value="{!mod.att.ParentId}"/>
              </apex:column>
          </apex:pageBlockTable>
      </apex:pageBlock>
  </apex:form>
</apex:page> 
 
Test Class:---
 
@isTest
public class TestNotesAttachmentModelController{
public static TestMethod void runTest(){
    Account acc = new Account(Name ='Test iBirds');
    insert acc;
     Attachment attach=new Attachment();    
     attach.Name='Unit Test Attachment';
     Blob bodyBlob=Blob.valueOf('Unit Test Attachment Body');
     attach.body=bodyBlob;
     attach.parentId=acc.id;
     insert attach;
     ApexPages.StandardController sc = new ApexPages.StandardController(acc);
     NotesAttachmentModelController na = new NotesAttachmentModelController(sc);
    }
}
 
After this we implement logic for attachment insertion on parent and 
automatic reload of Parent Page through JavaScript.
 
Apex Class:---
 
Now on click on Custom Button Class uploadAttachmentAssignmentController execute.

 
 
public class uploadAttachmentAssignmentController{  
    public Id recId{get;set;}
    public string fileName{get;set;}  
    public Blob fileBody{get;set;}
    public boolean isSaved{get;set;}  
    public Attachment myAttachment{get;set;}
    public uploadAttachmentAssignmentController(ApexPages.StandardController ctlr){  
        recId = ctlr.getRecord().Id;
        isSaved = false; 
    }          
    public PageReference UploadFile(){  
       isSaved = true; 
        if(fileBody != null && fileName != null)  
        {  
            Attachment myAttachment  = new Attachment();  
            myAttachment.Body = fileBody;  
            myAttachment.Name = fileName;  
            myAttachment.ParentId = recId;
            insert myAttachment; 
           // isSaved = true; 
            system.debug('############# value of isSaved'+isSaved);
        } 
          return null;  
    }   
}
 
Page:---
 
<apex:page id="pg" standardController="Account" extensions="uploadAttachmentAssignmentController">
    <apex:form id="pgb" >
            <apex:pageBlock title="Upload Attachment">         
                <apex:inputFile style="width:100%" id="fileToUpload" value="{!fileBody}" 
                  filename="{!fileName}" />  
                <apex:commandButton value="Upload Attachment" action="{!UploadFile}" />  
                
            </apex:pageBlock> 
             </apex:form> 
              <script>
              alert({!isSaved});
                if({!isSaved} == true){
                alert({!isSaved});
        window.opener.location.reload();
        window.close();
        }
    </script>
</apex:page> 
 
Finally job is completely Done. Enjoy Code and implement thinking.
 
                                         -----Abhinav Sharma 
 
 
 

4 comments:

  1. Thanks you for such a good post on attachment. really Helpful.

    ReplyDelete
  2. Nice Post indeed !
    But ,point is how can I make similar standard behavior for 'New Note' and 'Attach file' button under Notes and attachment Related list .

    ReplyDelete
  3. @Mayank Please refer Apex language cookbook for this because we have a topic in that related to functionality for which you are asking.

    ReplyDelete
  4. Thanks Abhinav ,I am able to made custom RL for Notes and Attachment .

    ReplyDelete