0

I just created a VF page that lets a user to upload an image to Salesforce. My final goal is to print the image width and size to the console with the script below:

<script>
    $(document).ready(function() {
        var _URL = window.URL || window.webkitURL;
        $("#file").change(function(e) {
            var file, img;


            if ((file = this.files[0])) {
                img = new Image();
                img.onload = function() {
                    alert(this.width + " " + this.height);
                };
                img.onerror = function() {
                    alert("not a valid file: " + file.type);
                };
                img.src = _URL.createObjectURL(file);
            }

        });
    });
</script>

The problem is that nothing happens when I use apex:inputFile:

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

BUT if I use HTML input it works!

<input type="file" id="file" value="{!attachment.body}" filename="{!attachment.name}"/>

What am I missing? Why JS does not work with apex:inputFile and how can it be resolved?

Here is the complete code: VF Page:

<apex:page controller="AttachmentUploadController">
<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>  
<script>
    $(document).ready(function() {
        var _URL = window.URL || window.webkitURL;
        $("#file").change(function(e) {
            var file, img;


            if ((file = this.files[0])) {
                img = new Image();
                img.onload = function() {
                    alert(this.width + " " + this.height);
                };
                img.onerror = function() {
                    alert("not a valid file: " + file.type);
                };
                img.src = _URL.createObjectURL(file);
            }

        });
    });
</script>

  <apex:sectionHeader title="Visualforce Example" subtitle="Attachment Upload Example"/>

  <apex:form enctype="multipart/form-data">
    <apex:pageMessages />
    <apex:pageBlock title="Upload a Attachment">

      <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"/>
          <!--<input type="file" id="test1" value="{!attachment.body}" filename="{!attachment.name}"/>-->
          <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>
  </apex:form>
</apex:page>  

Apex 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 = '0037E00000QX2Bp'; // 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

This is a common problem. Visualforce prefixes your ids, so you need to use a different selector. The simplest and best practice would be to use a class selector instead:

<apex:inputFile styleClass="fileUpload" ... />
$(".fileUpload").change(function (event) { /*implementation*/ });

You could alternatively use an "ends with" ($=) selector instead:

<apex:inputFile id="fileUpload" ... />
$("[id$='fileUpload']").change(function (event) { /*implementation*/ });

Or if you really want to do things the hard way, you can go with Salesforce's recommendation and use the $Component global variable.

$("{!$Component.figure.out.the.path.to.your.element}").change(...)

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.