I've built a simple Drag & Drop image preview over the file input in Vue. It's works fine but when the image is dragged over the dropzone I want to add a class so it will highlight the area, which it already does when you hover over it.
HTML:
<div id="wrapper">
<upload-image help="Specific requirements for this dropzone"></upload-image>
</div>
<template id="dropzone">
<div v-if="!image">
<div class="dropzone-area" drag-over="handleDragOver">
<div class="dropzone-text">
<span class="dropzone-title">Drop image here or click to select</span>
<span class="dropzone-info" v-if="help">{{ help }}</span>
</div>
<input type="file" @change="onFileChange">
</div>
</div>
<div class="dropzone-preview">
<img :src="image" />
<button @click="removeImage" v-if="image">Remove</button>
</div>
</template>
JavaScript (Vue.js):
Vueponent('upload-image', {
template: '#dropzone',
props: ['help'],
data() {
return {
image: ''
}
},
methods: {
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length) return;
this.createImage(files[0]);
},
createImage(file) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage: function (e) {
this.image = '';
}
}
});
new Vue({
el: '#wrapper'
});
Here is my example fiddle (with styling):
I can get it to work (on a static HTML element) using dragenter in vanilla JavaScript, but not when the element is generated by Vue.
I've built a simple Drag & Drop image preview over the file input in Vue. It's works fine but when the image is dragged over the dropzone I want to add a class so it will highlight the area, which it already does when you hover over it.
HTML:
<div id="wrapper">
<upload-image help="Specific requirements for this dropzone"></upload-image>
</div>
<template id="dropzone">
<div v-if="!image">
<div class="dropzone-area" drag-over="handleDragOver">
<div class="dropzone-text">
<span class="dropzone-title">Drop image here or click to select</span>
<span class="dropzone-info" v-if="help">{{ help }}</span>
</div>
<input type="file" @change="onFileChange">
</div>
</div>
<div class="dropzone-preview">
<img :src="image" />
<button @click="removeImage" v-if="image">Remove</button>
</div>
</template>
JavaScript (Vue.js):
Vue.ponent('upload-image', {
template: '#dropzone',
props: ['help'],
data() {
return {
image: ''
}
},
methods: {
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length) return;
this.createImage(files[0]);
},
createImage(file) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage: function (e) {
this.image = '';
}
}
});
new Vue({
el: '#wrapper'
});
Here is my example fiddle (with styling): https://jsfiddle/jackbarham/sxfept4t/1
I can get it to work (on a static HTML element) using dragenter in vanilla JavaScript, but not when the element is generated by Vue.
Share Improve this question asked Jan 15, 2016 at 18:40 Jack BarhamJack Barham 3,21912 gold badges44 silver badges64 bronze badges 1-
1
Where is
handleDragOver
defined? – Evan Zamir Commented Aug 4, 2017 at 23:22
2 Answers
Reset to default 6Use @dragenter
attribute to bind your method to a dragenter event.
<div :class="['dropzone-area', dragging ? 'dragenterClass' : '']" drag-over="handleDragOver" @dragenter="dragging=true" @dragend="dragging=false" @dragleave="dragging=false">
...
</div>
And in a data section:
data() {
return {
image: '',
dragging: false
}
}
Here is an example based on your code.
Question was answered here: http://forum.vuejs/topic/1446/add-class-in-drop-area-file-input-when-dragging-an-external-image-over-dragenter/2
With: @dragenter
, @dragleave
and the :class
binding to the rescue