Skip to content

Commit ab18e07

Browse files
author
Stephen Herron
committed
Adding base functionality
1 parent e6ea773 commit ab18e07

File tree

3 files changed

+218
-11
lines changed

3 files changed

+218
-11
lines changed

package-lock.json

+11-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"build": "node build/build.js"
1212
},
1313
"dependencies": {
14+
"axios": "^0.18.0",
1415
"vue": "^2.5.2",
1516
"vue-router": "^3.0.1"
1617
},

src/App.vue

+206-5
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,224 @@
1010
line-height: 400px;
1111
border-radius: 4px;
1212
}
13+
div.file-listing{
14+
width: 400px;
15+
margin: auto;
16+
padding: 10px;
17+
border-bottom: 1px solid #ddd;
18+
}
19+
a.submit-button{
20+
display: block;
21+
margin: auto;
22+
text-align: center;
23+
width: 200px;
24+
padding: 10px;
25+
text-transform: uppercase;
26+
background-color: #CCC;
27+
color: white;
28+
font-weight: bold;
29+
margin-top: 20px;
30+
}
31+
div.file-listing img{
32+
height: 20px;
33+
}
34+
div.remove-container{
35+
text-align: center;
36+
}
37+
38+
div.remove-container a{
39+
color: red;
40+
cursor: pointer;
41+
}
42+
progress{
43+
width: 400px;
44+
margin: auto;
45+
display: block;
46+
margin-top: 20px;
47+
margin-bottom: 20px;
48+
}
1349
</style>
1450

1551
<template>
1652
<div id="file-drag-drop">
1753
<form ref="fileform">
1854
<span class="drop-files">Drop the files here!</span>
1955
</form>
56+
57+
<progress max="100" :value.prop="uploadPercentage"></progress>
58+
59+
<div v-for="(file, key) in files" class="file-listing" :key="key">
60+
<img class="preview" v-bind:ref="'preview'+parseInt(key)"/>
61+
{{ file.name }}
62+
63+
<div class="remove-container">
64+
<a class="remove" v-on:click="removeFile(key)">Remove</a>
65+
</div>
66+
67+
</div>
68+
<a class="submit-button" v-on:click="submitFiles()" v-show="files.length > 0">Submit</a>
69+
2070
</div>
2171
</template>
2272

2373
<script>
24-
export default {
25-
data(){
26-
return {
27-
dragAndDropCapable: false,
28-
files: []
74+
import axios from 'axios'
75+
export default {
76+
data () {
77+
return {
78+
dragAndDropCapable: false,
79+
files: [],
80+
uploadPercentage: 0
81+
}
82+
},
83+
methods: {
84+
/*
85+
Determines if the drag and drop functionality is in the
86+
window
87+
*/
88+
determineDragAndDropCapable () {
89+
/*
90+
Create a test element to see if certain events
91+
are present that let us do drag and drop.
92+
*/
93+
var div = document.createElement('div')
94+
95+
/*
96+
Check to see if the `draggable` event is in the element
97+
or the `ondragstart` and `ondrop` events are in the element. If
98+
they are, then we have what we need for dragging and dropping files.
99+
100+
We also check to see if the window has `FormData` and `FileReader` objects
101+
present so we can do our AJAX uploading
102+
*/
103+
return (('draggable' in div) ||
104+
('ondragstart' in div && 'ondrop' in div)) && 'FormData' in window &&
105+
'FileReader' in window
106+
},
107+
/*
108+
Gets the image preview for the file.
109+
*/
110+
getImagePreviews () {
111+
/*
112+
Iterate over all of the files and generate an image preview for each one.
113+
*/
114+
for (let i = 0; i < this.files.length; i++) {
115+
/*
116+
Ensure the file is an image file
117+
*/
118+
if (/\.(jpe?g|png|gif)$/i.test(this.files[i].name)) {
119+
/*
120+
Create a new FileReader object
121+
*/
122+
let reader = new FileReader()
123+
124+
/*
125+
Add an event listener for when the file has been loaded
126+
to update the src on the file preview.
127+
*/
128+
reader.addEventListener('load', function () {
129+
this.$refs['preview' + parseInt(i)][0].src = reader.result
130+
}.bind(this), false)
131+
132+
/*
133+
Read the data for the file in through the reader. When it has
134+
been loaded, we listen to the event propagated and set the image
135+
src to what was loaded from the reader.
136+
*/
137+
reader.readAsDataURL(this.files[i])
138+
} else {
139+
/*
140+
We do the next tick so the reference is bound and we can access it.
141+
*/
142+
this.$nextTick(function () {
143+
this.$refs['preview' + parseInt(i)][0].src = '/images/file.png'
144+
})
145+
}
29146
}
147+
},
148+
removeFile (key) {
149+
this.files.splice(key, 1)
150+
},
151+
/*
152+
Submits the files to the server
153+
*/
154+
submitFiles () {
155+
/*
156+
Initialize the form data
157+
*/
158+
let formData = new FormData()
159+
160+
/*
161+
Iteate over any file sent over appending the files
162+
to the form data.
163+
*/
164+
for (var i = 0; i < this.files.length; i++) {
165+
let file = this.files[i]
166+
167+
formData.append('files[' + i + ']', file)
168+
}
169+
170+
/*
171+
Make the request to the POST /file-drag-drop URL
172+
*/
173+
axios.post('/file-drag-drop',
174+
formData,
175+
{
176+
headers: {
177+
'Content-Type': 'multipart/form-data'
178+
},
179+
onUploadProgress: function (progressEvent) {
180+
this.uploadPercentage = parseInt(Math.round((progressEvent.loaded * 100) / progressEvent.total))
181+
}.bind(this)
182+
}
183+
).then(function () {
184+
console.log('SUCCESS!!')
185+
})
186+
.catch(function () {
187+
console.log('FAILURE!!')
188+
})
189+
}
190+
},
191+
mounted () {
192+
/*
193+
Determine if drag and drop functionality is capable in the browser
194+
*/
195+
this.dragAndDropCapable = this.determineDragAndDropCapable()
196+
197+
/*
198+
If drag and drop capable, then we continue to bind events to our elements.
199+
*/
200+
if (this.dragAndDropCapable) {
201+
/*
202+
Listen to all of the drag events and bind an event listener to each
203+
for the fileform.
204+
*/
205+
['drag', 'dragstart', 'dragend', 'dragover', 'dragenter', 'dragleave', 'drop'].forEach(function (evt) {
206+
/*
207+
For each event add an event listener that prevents the default action
208+
(opening the file in the browser) and stop the propagation of the event (so
209+
no other elements open the file in the browser)
210+
*/
211+
this.$refs.fileform.addEventListener(evt, function (e) {
212+
e.preventDefault()
213+
e.stopPropagation()
214+
}, false)
215+
}.bind(this))
216+
217+
/*
218+
Add an event listener for drop to the form
219+
*/
220+
this.$refs.fileform.addEventListener('drop', function (e) {
221+
/*
222+
Capture the files from the drop event and add them to our local files
223+
array.
224+
*/
225+
for (let i = 0; i < e.dataTransfer.files.length; i++) {
226+
this.files.push(e.dataTransfer.files[i])
227+
}
228+
this.getImagePreviews()
229+
}.bind(this))
30230
}
31231
}
232+
}
32233
</script>

0 commit comments

Comments
 (0)