1

My component vue is like this :

<template>
    <div class="modal" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <form method="post" :action="baseUrl+'/product/editImage'" enctype="multipart/form-data">
                    ...
                    <input type="file" v-on:change="changeImage" name="image" id="image" required>
                    ...
                </form>
            </div>
        </div>
    </div>
</template>
<script>
    export default{
        ...
        methods: {
            changeImage(e) {
                data = new FormData();
                data.append('file', $('#image')[0].files[0]);
                var imgname  =  $('#image').val();
                var size  =  $('#image')[0].files[0].size;
                var ext =  imgname.substr( (imgname.lastIndexOf('.') +1) );
                if(ext=='jpg' || ext=='jpeg' || ext=='png' || ext=='gif' || ext=='PNG' || ext=='JPG' || ext=='JPEG') {
                    if(size<=5000000) {
                        $.ajax({
                            url: window.Laravel.baseUrl+'/product/addImage',
                            type: "POST",
                            data: data,
                            enctype: 'multipart/form-data',
                            processData: false,  // tell jQuery not to process the data
                            contentType: false   // tell jQuery not to set contentType
                        }).done(function(data) {
                            if (!$.trim(data)) {   
                                alert('No response');
                            }
                            else {   
                                var files = e.target.files || e.dataTransfer.files
                                if (!files.length)
                                    return;
                                this.createImage(files[0])
                                this.imageChanged = files[0]
                                $('#image').val(data);
                            }
                        });
                        return false;
                    }
                    else {
                        alert('Sorry File size exceeding from 5 Mb');
                        $('#image').val('');
                    }
                }
                else {
                    alert('Sorry Only you can uplaod JPEG|JPG|PNG|GIF file type ');
                }
            },
            createImage(file) {
                var image = new Image()
                var reader = new FileReader()
                var vm = this

                reader.onload = (e) => {
                    vm.image = e.target.result
                };
                reader.readAsDataURL(file)
            },
        } 
    }
</script>

I still use javascript in vue.js 2. because i am still confused when using vue.js as a whole

When I upload image, there exist error like this :

Uncaught ReferenceError: data is not defined

Seems data = new FormData(); not working on the vue.js

I had try it use javascript and it works

But when I implement it to vue.js, it does not work

How can I solve the problem?

4
  • 1. 'Seems data = new FormData(); not working on the vue.js' should not be the cause. Commented Jun 2, 2017 at 2:58
  • @J Jin, So what is the solution? Commented Jun 2, 2017 at 3:01
  • In 'data = new FormData()' , where do you define 'data' or can you use 'var data = new FormData()'. And in '.done(function(data)', can you use other name except 'data' Commented Jun 2, 2017 at 3:05
  • @J Jin, Now it works. I use like this : let myForm = document.getElementById('myForm'); let data = new FormData(myForm); Commented Jun 2, 2017 at 3:13

2 Answers 2

3

I've re-worked your code a bit to make better use of Vue. jQuery is no longer used aside from the ajax submission.

new Vue({
  el:"#app",
  data:{
    allowableTypes: ['jpg', 'jpeg', 'png', 'gif'],
    maximumSize: 5000000,
    selectedImage: null,
    image: null,
    options:{
      url: 'https://httpbin.org/post',
      type: "POST",
      processData: false, 
      contentType: false 
    }
  },
  methods: {
    validate(image) {
      if (!this.allowableTypes.includes(image.name.split(".").pop().toLowerCase())) {
        alert(`Sorry you can only upload ${this.allowableTypes.join("|").toUpperCase()} files.`)
        return false
      }

      if (image.size > this.maximumSize){
        alert("Sorry File size exceeding from 5 Mb")
        return false
      }

      return true
    },
    onImageError(err){
      console.log(err, 'do something with error')
    },
    changeImage($event) {
      this.selectedImage = $event.target.files[0]
      //validate the image
      if (!this.validate(this.selectedImage))
        return
      // create a form
      const form = new FormData();
      form.append('file', this.selectedImage);
      // submit the image
      $.ajax(Object.assign({}, this.options, {data: form}))
        .then(this.createImage)
        .catch(this.onImageError);
    },
    createImage() {
      const image = new Image()
      const reader = new FileReader()
      reader.onload = (e) => {
        this.image = e.target.result
      };
      reader.readAsDataURL(this.selectedImage)
    },
  } 
})

Template

<div id="app">
  <input type="file" v-on:change="changeImage" name="image">
  <input v-if="selectedImage" v-model="selectedImage.name" type="hidden" name="photo" />
  {{image}}
</div>

Example.

Sign up to request clarification or add additional context in comments.

17 Comments

Can you update the const onDone? I update it like this : const onDone = (data) => {if (!$.trim(data)) { alert('No response'); } else { var files = $event.target.files || $event.dataTransfer.files if (!files.length) return; this.createImage(files[0]) this.imageChanged = files[0] $('#image_changed').val(data); } }
I used to display image. I try like that, But there exist error : Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
@TrendingNews is #image_changed an img element?
sorry I mean $('#image').val(data);
@TrendingNews It's not allowed to set the value for a file input element. stackoverflow.com/q/1696877/38065
|
0

This plugin may work for you: Vue.ajax
Its file upload feature is available:

HTML

<input type="file" name="my-input" id="my-input">

VueJS

Vue.ajax.post('http://example.com', [data], {
  fileInputs: [
    document.getElementById('my-input')
  ]
});

I actually created this for myself, but then I decided to publish it in Github. I hope you will take your interest.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.