Reputation: 3755
pointer-events: none; has already been implemented , in debug , the boolean kept rapidly switching between true and false for both "dragging" & draggingOL"
HTML Structure
<ol id="product-images" @dragenter="draggingOL=true" @dragleave="draggingOL=false">
<li v-for="(file, key) in files" style="pointer-events: none;"></li>
</ol>
<div v-show="files.length < 1 || draggingOL == true">
<div ref="fileform" :class="['next-upload-dropzone', dragging ? 'css1' : '', draggingOL ? 'css1 css2' : '']" @dragenter="dragging=true" @dragleave="dragging=false">
</div>
</div>
Basically after you drag an image into the DIV tag, the OL Tag will appear.
The OL tag doesn't have a draggable so i added Dragenter and leave to OL
When i add the second dragenter to OL tag , when you drag a image into the area, the boolean of both dragging & draggingOL will rapidly switch between true and false at 0.5s interval. Same for the css, show and unshow very rapidly.
I tried a few ways including only one dragenter ONLY, same issue. Perhaps the issue is with v-show, i'm not sure.
Above is the image of DIV tag
Above is image of OL tag
Javascript
var dropFileApp = new Vue({
el: '#dropfile',
data: {
dragAndDropCapable: false,
dragging : false,
draggingOL : false,
files: [],
uploadPercentage: 0
},
// define methods under the `methods` object
mounted(){
/*
Determine if drag and drop functionality is capable in the browser
*/
this.dragAndDropCapable = this.determineDragAndDropCapable();
/*
If drag and drop capable, then we continue to bind events to our elements.
*/
if( this.dragAndDropCapable ){
/*
Listen to all of the drag events and bind an event listener to each
for the fileform.
*/
['drag', 'dragstart', 'dragend', 'dragover', 'dragenter', 'dragleave', 'drop'].forEach( function( evt ) {
/*
For each event add an event listener that prevents the default action
(opening the file in the browser) and stop the propagation of the event (so
no other elements open the file in the browser)
*/
this.$refs.fileform.addEventListener(evt, function(e){
e.preventDefault();
e.stopPropagation();
}.bind(this), false);
}.bind(this));
/*
Add an event listener for drop to the form
*/
this.$refs.fileform.addEventListener('drop', function(e){
/*
Capture the files from the drop event and add them to our local files
array.
*/
for( let i = 0; i < e.dataTransfer.files.length; i++ ){
this.files.push( e.dataTransfer.files[i] );
this.getImagePreviews();
}
console.log((this.files.length))
/*
Instantly upload files
*/
this.submitFiles();
}.bind(this));
}
},
methods: {
/*
Determines if the drag and drop functionality is in the
window
*/
determineDragAndDropCapable(){
/*
Create a test element to see if certain events
are present that let us do drag and drop.
*/
var div = document.createElement('div');
/*
Check to see if the `draggable` event is in the element
or the `ondragstart` and `ondrop` events are in the element. If
they are, then we have what we need for dragging and dropping files.
We also check to see if the window has `FormData` and `FileReader` objects
present so we can do our AJAX uploading
*/
return ( ( 'draggable' in div )
|| ( 'ondragstart' in div && 'ondrop' in div ) )
&& 'FormData' in window
&& 'FileReader' in window;
},
/*
Gets the image preview for the file.
*/
getImagePreviews(){
/*
Iterate over all of the files and generate an image preview for each one.
*/
for( let i = 0; i < this.files.length; i++ ){
/*
Ensure the file is an image file
*/
if ( /\.(jpe?g|png|gif)$/i.test( this.files[i].name ) ) {
/*
Create a new FileReader object
*/
let reader = new FileReader();
/*
Add an event listener for when the file has been loaded
to update the src on the file preview.
*/
reader.addEventListener("load", function(){
this.$refs['preview'+parseInt( i )][0].src = reader.result;
}.bind(this), false);
/*
Read the data for the file in through the reader. When it has
been loaded, we listen to the event propagated and set the image
src to what was loaded from the reader.
*/
reader.readAsDataURL( this.files[i] );
}else{
/*
We do the next tick so the reference is bound and we can access it.
*/
this.$nextTick(function(){
this.$refs['preview'+parseInt( i )][0].src = '/images/file.png';
});
}
}
},
/*
Submits the files to the server
*/
submitFiles(){
/*
Initialize the form data
*/
let formData = new FormData();
/*
Iteate over any file sent over appending the files
to the form data.
*/
for( var i = 0; i < this.files.length; i++ ){
let file = this.files[i];
formData.append('files[' + i + ']', file);
}
/*
Make the request to the POST /file-drag-drop URL
*/
axios.post( '/file-drag-drop',
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: function( progressEvent ) {
//Showing Loading
}.bind(this)
}
).then(function(){
console.log('SUCCESS!!');
})
.catch(function(){
console.log('FAILURE!!');
});
},
/*
Removes a select file the user has uploaded
*/
removeFile( key ){
this.files.splice( key, 1 );
}
}
})
I will continue to test and debug and update this thread.
Upvotes: 3
Views: 4330
Reputation: 1
Maybe you forgot. There are 2 elements, the parent element will wrap the child element. If you drag something onto the parent element @dragenter="..." then the child element will appear with the condition v-show="..." . Then you must attach @dragleave="..." to the child element for it to work. Because now the child element is appearing and covering the parent element
Upvotes: 0
Reputation: 3444
I solved it by adding a transparent overlay to my overlay:
<div style="position: relative"
@dragenter.prevent.stop="dropzone = true"
@dragover.prevent.stop="dropzone = true"
>
<!-- Bunch of other stuff here -->
<div v-if="dropzone" class="dropzone" >
<i class="material-icons">cloud_upload</i>
<div class="dropzone_text">Drop files here</div>
<!-- transparent, catches drop & dragleave events -->
<div style="width: 100%; height: 100%; position: absolute"
@drop.prevent.stop="dropzone = false"
@dragleave.prevent.stop="dropzone = false"
></div>
</div>
Upvotes: 1
Reputation: 401
I fixed the same issue in my code doing the next:
And it worked for me! Hope it helps someone :)
Upvotes: 1
Reputation: 31
I had similar problem. It has been resolved, you need to prevent event bubbling for Vue events: Prevent event bubbling in Vue
<div v-on:dragleave.self="dragLeave($event)">
...
</div>
Upvotes: 3
Reputation: 3755
The Solution is to not use @dragleave
I changed the boolean for draggingOL to false upon firing the post request for the image manually instead of using @dragleave.
Upvotes: 0