0

I am trying to create a VF page using which I can attach files and save it to notes and attachment object. I am almost close but there is some problem with the code. I am using input file tag to get the attachment and insert the attachment in extension. But I get an error saying - apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute.

I am doing this on a sample custom object that i created - test_Object2__c

VF page:

<apex:page standardController="test_Object2__c" extensions="testobject2">

<apex:form >
<apex:commandButton action="{!savetest}" value="Save" id="theButton" rerender="test"/>
Name <apex:inputfield label="Name" value="{!testobj2.Name}"/>


<apex:outputpanel id="test">
<!-- some code which I rerender , I have to rerender this block when I click save, so I cannot do it in any other way
-->

</apex:outputpanel>
</apex:form>


 <apex:form >
Attachment <apex:inputfile value="{!myfile.body}" filename="{!myfile.Name}" /> 
</apex:form>

</apex:page>

Extension:

public class testobject2 {

    public test_Object2__c testobj2{get;set;}
     public blob attc{get;set;}
     private Attachment myfile;
    public Attachment getmyfile() {
    myfile = new Attachment();
    return myfile;
    }
    public testobject2(ApexPages.StandardController controller) {

    this.testobj2 = (test_Object2__c) controller.getrecord();

    }

    public pagereference savetest(){

    insert testobj2;
    system.debug('******************' + attc );

    Attachment a = new Attachment(parentid=testobj2.id, Name = myfile.name , Body = myfile.body);
    insert a;
    return null;
    }

}

If I remove rerender in the save commandbutton syntax then I am able to create the attachment but If I use rerender I get the error. For my requirement I have some essential code which I rerender when I click save so I can not remove rerender attribute. Is there any other way to do this.

2
  • Segregate comamndButton and inputFile in separate actionRegions(apex:actionRegion) or forms (apex:form). Even I faced the same issue. I separated them into two actionRegions.
    – Avinash
    Jul 7, 2016 at 23:09
  • Pls see my edit - I use two different apex form as you suggested, but I get a null pointer exception when i cam creating a new attachment object. Do you know the reason?
    – SfdcBat
    Jul 7, 2016 at 23:42

2 Answers 2

0

Do something like this:

Visualforce Page:


  <apex:pageBlockButtons >
    <apex:commandButton action="{!upload}" value="Save"/>
  </apex:pageBlockButtons>

  <apex:pageBlockSection showHeader="false" columns="2" id="block1">

    <apex:pageBlockSectionItem >
      <apex:outputLabel value="File Name" for="fileName"/>
      <apex:inputText value="{!attachment.name}" id="fileName"/>
    </apex:pageBlockSectionItem>

    <apex:pageBlockSectionItem >
      <apex:outputLabel value="File" for="file"/>
      <apex:inputFile value="{!attachment.body}" filename="{!attachment.name}" id="file"/>
    </apex:pageBlockSectionItem>

    <apex:pageBlockSectionItem >
      <apex:outputLabel value="Description" for="description"/>
      <apex:inputTextarea value="{!attachment.description}" id="description"/>
    </apex:pageBlockSectionItem>

  </apex:pageBlockSection>

</apex:pageBlock>

Controller:

public with sharing class AttachmentUploadController {

  public Attachment attachment {
  get {
      if (attachment == null)
        attachment = new Attachment();
      return attachment;
    }
  set;
  }

  public PageReference upload() {

    attachment.OwnerId = UserInfo.getUserId();
    attachment.ParentId = '0012800000iCVLi'; // the record the file is attached to
    attachment.IsPrivate = true;

    try {
      insert attachment;
    } catch (DMLException e) {
      ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading attachment'));
      return null;
    } finally {
      attachment = new Attachment(); 
    }

    ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Attachment uploaded successfully'));
    return null;
  }

}
1

I suspect that at the root of your issue is that both of the below need to use the transient keyword. When you do a rerender, the view state is saved and you'll exceed it's capacity if these aren't declared as transient. You don't have the memory available to maintain their view state.

 public test_Object2__c testobj2{get;set;}
 public blob attc{get;set;}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .