event.preventDefault not working file chooser

Hi Everyone,

I am working on some image upload module, in this, I have an upload button and on click of it, there is a file chooser which allows you to choose any jpg or png file. After that on selecting the file, the image gets uploaded to the server. But the problem is after this process gets completed page reloads.

I am using OSTRIO for uploading the image to Server.
Let’s have a look at my code.

Template.create_new_group.events({
  'change #fileCh': function(e,template) {
     e.preventDefault(); 
        // event.preventDefault();
    var files = e.currentTarget.files;
    if (e.currentTarget.files && e.currentTarget.files[0]) {
    var file = e.currentTarget.files[0];
      if (file) {
        var uploadInstance = Images.insert({
          file: file,
          streams: 'dynamic',
          chunkSize: 'dynamic'
        });

        uploadInstance.on('start', function() {
          template.currentUpload.set(this);
        });
          uploadInstance.on('end', function(error, fileObj) {
          if (error) {
            window.alert('Error during upload: ' + error.reason);
          } else {
            Session.set("imagePath",fileObj._id+'.'+  fileObj.ext);
            template.currentUpload.set(false);

          }
        });

        uploadInstance.start();
      }
    
  }
}
<template name="create_new_group">
  <div class="container">
    <input type="file" id="fileCh"   ><br/><br/>
    <button  id="create_group_button" class="cancelbtn"   type="submit">Create Group</button>   
  </div>
</template>

What you describe sounds like the default action for a form submit event. There is no default action for a input’s change event so calling preventDefault() on the event will have no effect.

Potentially you could put a onChange on the input, and handle it yourself, cause I needed to do something similar. In my case I wanted to upload to trigger on a custom button.

<IconButton
  disabled={!canEdit || !canUpload}
  onTouchTap={this.handleOnTouchTapFileUpload.bind(this, this.mediaString.fieldFinalValues.length)}
>
  <input
    id={this.mediaString.fieldFinalValues.length}
    type='file'
    hidden={true}
    onChange={this.handleChangeFileUpload.bind(this, tmpFileObject, this.mediaString.fieldFinalValues.length)}
  />
  <FileFileUpload />
</IconButton>

and …

handleOnTouchTapFileUpload(field) {
  document.getElementById(field).click();
}

handleChangeFileUpload(tmpFileObject, index, event) {
  if (event.target.files.length !== 0) {
    let image = event.target.files[0];

    let fileName = event.target.files[0].name;
    let fileContent;

    let reader = new FileReader();

    reader.addEventListener('load', () => {
      fileContent = reader.result;

      // this is where your stuff goes basically...
      // to handle the upload.
    });

    reader.readAsDataURL(image);
  }
}

This might be quite helpful, as depending on your content.

HI @tathagatbanerjee,
I am using blaze in Frontend. Could you help me achieve the same using Blaze, I am new to it and can’t understand the code you shared. Please help

Hi @copleykj, Could you please suggest me any better option in which I could achieve the desired funcitonality.

I can’t tell from your provided code if you are using a form, only that you have a submit button. If you are using a form, then you will need to prevent the default action for the form’s submit event rather than the file input’s change event.

2 Likes

hey mate,

So my front end is react, and i’m using the material-ui react lib. So the IconButton with the embedded FileFileUpload looks like below.

So, effectively ignore everything apart from the input tag tag for what you need. I’m using the trigger on the IconButton to handle the click event, which is triggering the hidden input’s onChange event [the handleChangeFileUpload function]. The click event then creates a new FileReader, and then adds an onLoad event handler to the FileReader. Does that make sense?

You would need to write a function on either the onChange to the input, or as @copleykj has suggested (a superior suggestion in my opinion) use the onSubmit event of the form rather than handling it in the input. It never even occurred to me, cause I simply wanted it hidden, but I think his idea is better.

Have a look at this, to see examples of using the onClick vs the onSubmit event.

Re the code, it should just be like:

Template.create_new_group.events({
  'the on submit or onChange here': function (event, template) {
    <this is where the contents of the code I have used can be put>
  }
})

Note: the input tags properties look like below.

{
  "id": 0,
  "type": "file",
  "hidden": true,
  "onChange": "[function bound handleChangeFileUpload]",
  "style": {}
}