Skip to content

Instantly share code, notes, and snippets.

Created May 30, 2014 18:08
Show Gist options
  • Save jeffdonthemic/3f00e51b372a4fa6f855 to your computer and use it in GitHub Desktop.
Save jeffdonthemic/3f00e51b372a4fa6f855 to your computer and use it in GitHub Desktop.
Visualforce Page for customizing Attachments. See UploadAttachmentController.
<apex:page standardController="Contact" tabStyle="Contact" extensions="UploadAttachmentController">
<apex:sectionHeader title="{!Contact.Name}" subtitle="Attach File"/>
<apex:form id="form_Upload">
<apex:pageBlock >
<apex:pageBlockButtons >
<apex:commandButton action="{!back}" value="Back to {!Contact.Name}"/>
<apex:commandButton action="{!back}" value="Cancel"/>
<apex:pageMessages />
<apex:pageBlockSection columns="1">
<apex:pageBlockSectionItem >
<apex:outputLabel value="File" for="file_File"/>
<apex:inputFile id="file_File" value="{!fileBody}" filename="{!fileName}"/>
<apex:pageBlockSectionItem >
<apex:outputLabel value="Type" for="type"/>
<apex:selectList value="{!selectedType}" size="1" id="type">
<apex:selectOption itemValue="Plain ole awesome" itemLabel="Plain ole awesome"/>
<apex:selectOption itemValue="Super awesome" itemLabel="Super awesome"/>
<apex:selectOption itemValue="Most awesomest" itemLabel="Most awesomest"/>
<apex:pageBlockSectionItem >
<apex:outputLabel value="Is the file awesome?" for="visible"/>
<apex:selectList value="{!selectedAwesomeness}" size="1" id="visible">
<apex:selectOption itemValue="false" itemLabel="No"/>
<apex:selectOption itemValue="true" itemLabel="Yes"/>
<apex:pageBlockSectionItem >
<apex:outputLabel value="Description" for="description"/>
<apex:inputTextarea id="description" value="{!description}" rows="4" cols="50"/>
<apex:pageBlockSectionItem >
<apex:outputLabel value="" for="uploadBtn"/>
<apex:commandButton id="uploadBtn" value="Attach File" action="{!processUpload}" />
public class UploadAttachmentController {
public String selectedType {get;set;}
public Boolean selectedAwesomeness {get;set;}
public String description {get;set;}
private Contact contact {get;set;}
public String fileName {get;set;}
public Blob fileBody {get;set;}
public UploadAttachmentController(ApexPages.StandardController controller) { = (Contact)controller.getRecord();
// creates a new Contact_Attachment__c record
private Database.SaveResult saveCustomAttachment() {
Contact_Attachment__c obj = new Contact_Attachment__c();
obj.contact__c = contact.Id;
obj.description__c = description;
obj.type__c = selectedType;
obj.awesome__c = selectedAwesomeness;
// fill out cust obj fields
return Database.insert(obj);
// create an actual Attachment record with the Contact_Attachment__c as parent
private Database.SaveResult saveStandardAttachment(Id parentId) {
Database.SaveResult result;
Attachment attachment = new Attachment();
attachment.body = this.fileBody; = this.fileName;
attachment.parentId = parentId;
// inser the attahcment
result = Database.insert(attachment);
// reset the file for the view state
fileBody = Blob.valueOf(' ');
return result;
* Upload process is:
* 1. Insert new Contact_Attachment__c record
* 2. Insert new Attachment with the new Contact_Attachment__c record as parent
* 3. Update the Contact_Attachment__c record with the ID of the new Attachment
public PageReference processUpload() {
try {
Database.SaveResult customAttachmentResult = saveCustomAttachment();
if (customAttachmentResult == null || !customAttachmentResult.isSuccess()) {
ApexPages.AddMessage(new ApexPages.Message(ApexPages.Severity.ERROR,
'Could not save attachment.'));
return null;
Database.SaveResult attachmentResult = saveStandardAttachment(customAttachmentResult.getId());
if (attachmentResult == null || !attachmentResult.isSuccess()) {
ApexPages.AddMessage(new ApexPages.Message(ApexPages.Severity.ERROR,
'Could not save attachment.'));
return null;
} else {
// update the custom attachment record with some attachment info
Contact_Attachment__c customAttachment = [select id from Contact_Attachment__c where id = :customAttachmentResult.getId()]; = this.fileName;
customAttachment.Attachment__c = attachmentResult.getId();
update customAttachment;
} catch (Exception e) {
return null;
return new PageReference('/'+contact.Id);
public PageReference back() {
return new PageReference('/'+contact.Id);
Copy link

ipitts commented Nov 13, 2019

Hello Jeff,

This customization is exactly what my organization needs in Salesforce. It’s a great workaround and I have set up the custom object, apex class and visualforce page in our sandbox environment. The one issue that I am running into is creating a test for the apex class that provides the necessary code coverage.

I have browsed through your site looking for the best ways to test the code you graciously provided and have been researching online for best practices on testing apex coding in general and have been coming up short. Could you please provide an additional demonstrate on how to test this specific custom code? Any additional assistance would be much appreciated.


Hi Jeff,
I would also like to know if you have test cases for this so I can deploy into production.


Copy link

Hi Jeff,
Thank you. Got error: Required fields are missing: [File Name, Body] while trying to add an attachment. (But the record is added, when I go to the Account file. And when I view the file attachment (view link) its empty)
Screen Shot 2020-10-21 at 12 12 38 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment