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 Answer 1

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(...)

You must log in to answer this question.

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