1

I have a huge and complex vf page (force.com site) - So I will try to explain my issue with an example instead publish here all the code - I hope it will be understanble:

I want to upload a file from vf page - the problem -

I have a lot of apex actions, command buttons and links that use rerender and onComplete attributes, so if I trying to use apex:inputFile tag- something get ruined and I get the issue :

apex:inputFile can not be used in conjunction with an action component, apex:commandButton or apex:commandLink that specifies a rerender or oncomplete attribute.

even though I wrapped that with actionRegion tags.

So I tried to get it done by using an HTML input tag and Its worked but not good enuff. The File that saved inside the Opportunity Cannot be opened from salesforce and even if I download it its said that its doesn't support that file. In other words, the file is broken.

I did the following - hopping for a silly mistake:

    <input type= "file" Id= "fileinput"/>
    <apex:commandButton onclick="uploadFiles(); return false;" value="Upload"/>

And the "uploadFiles" JS function is :

    var maxStringSize = 6000000;
    var attachmentList;
    var j;
    function uploadFiles()
    {
        input = document.getElementById('fileinput');
        attachmentList = input.files;
        console.log("attachmentList",attachmentList);
        if(j == undefined) 
        j = 0;   
        var file;
        if(j < attachmentList.length)
        {
            file = attachmentList[j];
         var name = file.name;
            var reader = new FileReader();  
            reader.onload = function(e) {  
             var attachmentbodybase64 = window.btoa(reader.result);//console log will print : ZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzB.....
                console.log(attachmentbodybase64.length);
                if(attachmentbodybase64.length > maxStringSize )
                alert("File size is too large to handle");
                else
                {
                    j++;
                    saveFileAF(attachmentbodybase64, name);
                }
            }
             reader.readAsDataURL(file);
        }
        else
        {
            console.log('this is end');
            
        }
        
     }

 

and that function called an action fcuntion method that calls the function "saveFile" on my controller:

     <apex:actionFunction name="saveFileAF" action="{!saveFile}" oncomplete="uploadFiles();"  status="statusSaveTrip">
         <apex:param name="base64File" value="" assignTo="{!base64}"/>
         <apex:param name="fileName" value="" assignTo="{!fileName}"/>
     </apex:actionFunction>

My Controller has the attributes :

    public String base64;
      public String getBase64()
      {
          return base64;
      }
      public void setbase64(String base64)
      {
          this.base64 = base64;
      }
      public String fileName {get; set;}




**And the function that the actionFunction fire :**



  public void saveFile()
  {

    ContentVersion testContentInsert = new ContentVersion();
          testContentInsert.Title = this.filename;
          testContentInsert.VersionData = Blob.valueOf(this.base64);
          testContentInsert.PathOnClient = filename ;
          testContentInsert.Line_Item_Id__c = 'lineItemIDDDD' ;

  
          insert testContentInsert;
  
          List<ContentVersion> cvList = [select id, ContentDocumentId from ContentVersion WHERE Id =:testContentInsert.Id];
          Opportunity opp = [SELECT Id FROM Opportunity LIMIT 1];
          System.debug('opp- > ' + opp);
  
          ContentDocumentLink cl = new ContentDocumentLink();
          cl.ContentDocumentId = cvList[0].ContentDocumentId;
          cl.LinkedEntityId = opp.Id;
          cl.ShareType = 'V';
          cl.Visibility = 'AllUsers';
  
          insert cl;
    System.debug('this.base64- > ' + this.base64);
  }

Screenshots:

enter image description here

enter image description here

Thanks

1
  • Look at the file in a text editor... does it look like a proper PNG (first three characters should be PNG)? If not, that would be the problem.
    – sfdcfox
    Commented Jun 22, 2020 at 15:53

3 Answers 3

2

You've base-64 encoded the data, but then you didn't reverse the encoding. This change should fix your problem:

testContentInsert.VersionData = EncodingUtil.base64decode(this.base64);
1
  • Thanks for you answer. I tried to change it as you said - but the same result. When I open the detail of the file (right-click and properties ) it said PNG but with a text editor it still the long input : ZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlW...... (not starting with the PNG letters..) When I try to upload the same file manually to the object - It works as expected.
    – Salvation
    Commented Jun 22, 2020 at 17:13
0

The Issue was on my VF-JS side -

Instead using this line window.btoa(reader.result) I used reader.result.replace(/^data:.+;base64,/, ''), and the encoding works well.

Along with the change that @sfdcfox suggested in my apex controller side -

EncodingUtil.base64decode(this.base64);

instead of

Blob.valueOf(this.base64);

2
  • 1
    Could u accept sfdcfox's reply and mark it as you answer?
    – MnZ
    Commented Jun 21, 2021 at 8:41
  • 1
    just did.. thanks :)
    – Salvation
    Commented Jun 21, 2021 at 13:10
0

you could have used apex:inputFile instead of using html normal input tag but as you said that you got an error '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 can tell you a very easy way to remove this error and that is to just remove the ' reRender ' tag from your page. because the reRender tag can not be applied on a page where apex:inputFile tag is used anywhere.

You can consider both of them as enemy. So just remove the reRender tag from your entire page and you will see the error is gone and you file is being saved.

1
  • Thanks for your contribution. This answer can be confusing, the reRender attribute is not mentioned in the original code snippet in the question. Did u mean oncomplete attribute?
    – Shamina
    Commented Dec 22, 2022 at 16:53

You must log in to answer this question.

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