Skip to content

Instantly share code, notes, and snippets.

@yoyosan
Last active September 3, 2023 01:50
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yoyosan/8dbcbddf70d28d29d32fc5e5e6bd8c1b to your computer and use it in GitHub Desktop.
Save yoyosan/8dbcbddf70d28d29d32fc5e5e6bd8c1b to your computer and use it in GitHub Desktop.
File upload example for Quasar framework
// Component example
/* template part */
<q-file
v-model="files"
label="Load documents"
square
flat
counter
:counter-label="counterLabelFn"
outlined
use-chips
multiple
clearable
accept=".csv,.txt,.xls,.xlsx,.doc,.docx,.pdf,.dbf,.zip,.rar,.7z,.jpg,.png,.gif"
max-files="10"
max-file-size="5120000" // 5 MB
@rejected="onRejected"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
</q-file>
/* script part */
methods: {
onSubmit (evt) {
this.loading = true // add loading state to submit button
const formData = new FormData()
if (this.files && this.files.length > 0) {
for (let i = 0; i < this.files.length; i++) {
formData.append('files[' + i + ']', this.files[i])
}
}
for (const [key, value] of Object.entries(this.form)) {
formData.append(key, value)
}
this.$axios.get('/sanctum/csrf-cookie').then(response => {
this.$axios({
method: 'post',
url: '/api/request',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then((response) => {
this.loading = false
this.$q.notify({
color: 'positive',
position: 'top',
message: 'Request sent! We\'ll contact you soon.',
icon: 'done'
})
})
.catch(() => {
this.loading = false
this.$q.notify({
color: 'negative',
position: 'top',
message: 'An error occurred',
icon: 'report_problem'
})
})
})
},
onRejected (entries) {
if (entries.length > 0) {
switch (entries[0].failedPropValidation) {
case 'max-file-size':
this.$q.notify({
position: 'top',
type: 'negative',
message: 'File exceeds 5MB.'
})
break
case 'max-files':
this.$q.notify({
position: 'top',
type: 'negative',
message: 'You can upload up to 10 files.'
})
break
}
}
}
// Laravel 7 example

namespace App\Http\Controllers;

class Contact extends Controller
{
    // ...

    /**
     * @param Request $request
     */
    public function request(Request $request)
    {
        $data = [];
        $keys = ['name', 'email', 'phone', 'uid'];

        foreach ($keys as $key) {
            if (!$request->has($key)) {
                abort(403, 'Unauthorized action.');
            }

            if (!in_array($key, ['files', 'uid'])) {
                $data[ucfirst($key)] = $request->input($key, '');
            }
        }

        $data['files_path'] = '';
        // store uploaded files if any
        if ($request->files && count($request->files) > 0) {
            $upDir = 'uploads' . DIRECTORY_SEPARATOR . Carbon::now()->toDateString() . DIRECTORY_SEPARATOR . $request->uid;
            Storage::makeDirectory($upDir);
            /** @var UploadedFile $file */
            foreach ($request->files as $file) {
                $file->storeAs($upDir, $file->getClientOriginalName());
            }
            $data['files_path'] = $upDir;
        }
    }
    
    // ...
}
@ASalihov
Copy link

ASalihov commented Aug 1, 2022

<template v-slot:prepend>
            <q-icon name="attach_file" />
          </template>

is this preview of selected image? It doesn't worked for me this way

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment