+ Start a Discussion

How to add upload document functionality on a VF page(webform) ?

Hi Everyone,
I have a requirement to display different fieldsets after rerender based on its respective picklist value selection by user in the field called Request Type.
After clicking save(saverequest custom method to save records) one record in Case Object and one in Custom Obj (Functional_Request__c) should be created along with an attached document(document should go into document object),now my records are saving in objects but i am unable to provide upload and download  functionality to my webforms.

Note: The upload option shoud be enabled/available to users only for the 1st Select option and download option for the 3rd option out of 3 options and currently there are unused variable and methods in the cotroller, i left it in as they are,thought it gets easier for anyone of you to help me.
Sample Web form

I have tried the steps from below links but no luck,i wonder it is because i have custom save method to save records and may not be close to my use case.

Help will be highly appreciated.

VF Page code:

                         <apex:actionRegion >
                            <apex:selectList label="Request Type" value="{!RequestValue}" size="1" multiselect="false">
                                    <apex:actionSupport event="onchange"  reRender="fieldSet"/>
                                    <apex:actionstatus startText="Applying Values.............">                   
                                     <apex:selectOption itemLabel="Provide Access Request" itemValue="Provide_Access_Request"></apex:selectOption
                                     <apex:selectOption itemLabel="Other" itemValue="Other"></apex:selectOption>
                                     <apex:selectOption itemLabel="Package Request" itemValue="Package_Request"></apex:selectOption> 

          <apex:commandButton action="{!saveRequest}" value="Submit" styleClass="js-save-button button green submitButton" />
          <apex:commandButton action="{!Cancel}" value="Cancel" styleClass="js-save-button button green submitButton" />


Public without sharing class  Provisional_Request_ctrl extends WSitesController


    /*Public Variables*/
    Public Functional_Request__c FormExtn {get;set;}
    Public List<Functional_Request__c> licaseformextn;// {get;set;}
    Public Map<string,Functional_Request__c> caseformmap;// {get;set;}
    Public Case Ocase; //{get;set;} 
    Public List<RecordType> OcaseRecordType;// {get;set;}
    public String recordType {get;set;}
    public String requesttype {get;set;}
    public String additionalcomments;//{get;set;} 
    public List<RecordType> ProvisionalRecordtypes {get; set;}
    public List<SelectOption> orecordtypes {get; set;}
    Public string iscentraloginisuue{get;set;}
    Functional_Request__c str;
    Public Document doc {get;set;}
    public List<String> docIdList = new List<string>();
    public boolean addAttachment{get; set;}
    public string setpopdisplay{get;set;}
    public List<Document> selectedDocumentList {get;set;}
    /* Error Message related variables */
    public boolean pageError {get; set;}
    public boolean showlist{get; set;}
    public boolean RenderFunction{get; set;}
    public boolean RenderFieldSetBlock{get; set;}
    public String pageErrorMessage {get; set;}
    public string formname{get;set;}
    Public Map<string,Id> caseformextrecordtypeMap{get;set;}
    public boolean displayPopup{get; set;}
    Public string contactemailid{get;set;}
    public boolean fileUpload{get;set;}
    public string RequestValue{get; set;}
    Public Provisional_Request_ctrl(){
      //Create New Record in Functional Request Obj Object      
        FormExtn = new Functional_Request__c ();
        caseformmap =  new Map<string,Functional_Request__c> ();
        Ocase = new case();        
        doc = new Document();
        doc = null;
       // UploadedDocumentList = new List<AttachmentsWrapper>();
        showlist = false;
        RenderFieldSetBlock = false;
        requesttype = 'None';
        iscentraloginisuue = 'false';
        RenderFunction = true;
        displayPopup = true;
        contactemailid = '';
        addAttachment = false;
        setpopdisplay = ''; 
   public pagereference Cancel()
        pageReference pg=new PageReference('https://domain.visual.force.com/apex/FRS_Request');
        return pg;
   // Get record types for  request forms and display in 'Request type'.
    Public void getfields(){
           RenderFunction = false;
           requesttype = apexpages.currentpage().getparameters().get('Param1');
           requesttype = EncodingUtil.urlDecode(requesttype, 'UTF-8');
           FormExtn.TDR_Request_Type__c = requesttype ;   
           DlccategorySelection = '';
           system.debug('12784563' + requesttype);
           if(requesttype != 'None'){
               requesttype=requesttype.replace(' ','_').replace('(' , '').replace(')' , '').replace(',' , '_').replace('-' , '_').replace('/' , '_').replace('.' , '');
           if(requesttype.length() > 41){
             requesttype = requesttype.substring(0,40);
             system.debug('@@@@@@@@@@@@' + requesttype );
              requesttype= requesttype.removeEnd('_');
   // saverequest method is to save the request.
    Public PageReference saveRequest(){
         pageError = false;
         pageErrorMessage = '';
        // If there is no validation error save the request.
          if(pageError == false){  
              RecordType rectype = new RecordType();
             string recrdtname; 
             if( RequestValue=='Provide_Access_Request')//referring fieldsets
                         FormExtn.RecordTypeId = System.Label.Provide_Access_Request; //custom labels which has record typeIds in its value field
             if( RequestValue=='Other')
                        FormExtn.RecordTypeId = System.Label.Other; 
                        fileUpload = true;
             if( RequestValue=='Package_Request')
                         FormExtn.RecordTypeId = System.Label.Package_Request; 
        //Insert Case
              Ocase = new case();
              Ocase.Status    = 'New';
              Ocase.Subject =  System.Label.TDR_Case_Subject;
              Ocase.Origin = System.Label.TDR_Case_Origin;
              Ocase.Description = apexpages.currentpage().getparameters().get('description') ;  
              Ocase.Contactid   = loggedInContact.id;             
              Ocase.Gen_Request_Type__c = RequestValue;
              Ocase.RecordTypeid   = System.Label.Provisional_RecordTypeId;
           // Assigning Case using Case-Assignment Rule.
             Database.DMLOptions dmlOpts = new Database.DMLOptions();
             dmlOpts.assignmentRuleHeader.assignmentRuleId= Label.Case_Assignment_Rule_Id ;
             dmlOpts.EmailHeader.TriggerUserEmail = true;
             Database.insert(Ocase, dmlOpts);
             system.debug('=========Case=======' + Ocase);
           // Insert Functional Request Obj. 
             FormExtn.Case_Form_App__c = System.Label.Case_Form_App;
             FormExtn.TDR_Employee__c  = loggedInContact.id;
             FormExtn.GEN_Case__c= Ocase.Id;
             system.debug('=========Form Extension=======' + FormExtn);
             Insert FormExtn;
             return new PageReference('/apex/AutoResponse_Page url); 
             }catch(Exception e){
             return null;
           return null;
catch(Exception ex){
 return null;


Austin GAustin G
Hi Cvrk,

There are a few things you need to do in order to have that file upload capability, and a few things to watch out for. The mechanics of it are pretty straightforward. Just use an <apex:inputFile> tag on the visualForce page, and tie it to an Attachment variable in your controller. Something like:
<!-- VisualForce -->
<apex:inputFile id="elementId" fileName="{!ControllerVariable.Name}" value="{!ControllerVariable.Body}" />

/* Controller */
Public without sharing class  Provisional_Request_ctrl extends WSitesController

public Attachment ControllerVariable
        if(ControllerVariable == null) //Ensure that you don't try to dereference a null document
            return new Attachment();
        else return ControllerVariable;

That's all the code you need to get a document upload up and running in VF. In your case, you need to attach it to a case as well. Since the ControllerVariable is already an Attachment, at a minimum all you need to set is the parentId. You can set the other fields you need, description, owner, private, etc), and then insert.
/* ... Controller logic, case is created, etc ...*/

ControllerVariable.ParentId = NewlyInsertCase.Id;
insert ControllerVariable;

A couple caveats though. File size can be a big issue when doing this. I see that you're not using an <apex:form> element, so I don't believe you'll have to worry about viewstate size. That said, I would make sure you test it out with an impossibly large file for the use case just to make sure nothing strange happens. If your files are over 5mb, you might need to use a different method.

Another thing to watch out for is the <apex:inputFile> tag does not disable when an upload is in progress. By default, there is nothing preventing your users from clicking the save button over and over and sending extra saveRequests. A quick solution to that is add a state variable. Something like:
/* Controller Variables */
boolean uploadInProgress = false;

/* Start of save request function */
uploadInProgress = true;


/* ... rest of the function .. */

uploadInProgress = false;

That's maybe not the right solution for your needs, but it's a quick way to prevent multiple uploads. Unfortunately, you can't use certain components' reRender function if you're using an <apex:inputFile> element, so you can't actually grey out the button and prevent users from clicking on it without some extra work. Hope this helps!

Thanks for your time Austin.. finally i made it but i have a problem here,after entering field values when i click on add button to upload,fields are becomming empty and the document is not being uploaded.i have partially succeded in getting that functionality on my page but its not working as expected.The problem is i can not remove the javascript and CSS out of my code,
Austin GAustin G
Check out this link for a lot of good info on view states: View States (https://developer.salesforce.com/page/An_Introduction_to_Visualforce_View_State" target="_blank). Also check out the doc page for <apex:inputFile> (https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_inputFile.htm). Check out how the view state is tied to the <apex:form> tag in visualforce pages, and see if it can apply in this case. You shouldn't need to change any client-side code for this functionality, the standard components should get you there.