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.

  • 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 '16 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 '16 at 23:42
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;}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.