Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Uploader component #238

Closed
amesas opened this issue Mar 20, 2017 · 81 comments
Closed

[Feature Request] Uploader component #238

amesas opened this issue Mar 20, 2017 · 81 comments
Assignees
Labels
C: New Component This issue would need a new component to be developed. T: feature A new feature
Milestone

Comments

@amesas
Copy link

amesas commented Mar 20, 2017

A file uploader component like:

http://element.eleme.io/#/en-US/component/upload

Async, progress, multiple file upload, etc....

@johnleider johnleider added T: enhancement Functionality that enhances existing features T: feature A new feature and removed T: enhancement Functionality that enhances existing features labels Mar 20, 2017
@dohomi
Copy link
Contributor

dohomi commented Mar 21, 2017

Here a proof of concept:

<template>
    <div>
        <v-text-field prepend-icon="attach_file" single-line
                      v-model="filename" :label="label" :required="required"
                      @click.native="onFocus"
                      :disabled="disabled" ref="fileTextField"></v-text-field>
        <input type="file" :accept="accept" :multiple="false" :disabled="disabled"
               ref="fileInput" @change="onFileChange">
    </div>
</template>
<script>
    export default{
        props: {
            value: {
                type: [Array, String]
            },
            accept: {
                type: String,
                default: "*"
            },
            label: {
                type: String,
                default: "Please choose..."
            },
            required: {
                type: Boolean,
                default: false
            },
            disabled: {
                type: Boolean,
                default: false
            },
            multiple: {
                type: Boolean, // not yet possible because of data
                default: false
            }
        },
        data(){
            return {
                filename: ""
            };
        },
        watch: {
            value(v){
                this.filename = v;
            }
        },
        mounted() {
            this.filename = this.value;
        },

        methods: {
            getFormData(files){
                const data = new FormData();
                [...files].forEach(file => {
                    data.append('data', file, file.name); // currently only one file at a time
                });
                return data;
            },
            onFocus(){
                if (!this.disabled) {
                    debugger;
                    this.$refs.fileInput.click();
                }
            },
            onFileChange($event){
                const files = $event.target.files || $event.dataTransfer.files;
                const form = this.getFormData(files);
                if (files) {
                    if (files.length > 0) {
                        this.filename = [...files].map(file => file.name).join(', ');
                    } else {
                        this.filename = null;
                    }
                } else {
                    this.filename = $event.target.value.split('\\').pop();
                }
                this.$emit('input', this.filename);
                this.$emit('formData', form);
            }
        }
    };
</script>
<style scoped>
    input[type=file] {
        position: absolute;
        left: -99999px;
    }
</style>

@abotsi
Copy link

abotsi commented Apr 10, 2017

Input(type=file) sounds like a must have! Doesn't it exists already? What is the link with this repo https://github.com/johnleider/vue-materials/blob/master/src/components/file-input.vue?

@amesas
Copy link
Author

amesas commented Apr 10, 2017

I was thinking about more feature complete solution:

  • Multiple file upload
  • File preview
  • Progress report
  • Drag & Drop
    etc...

Like:
http://demo.geekslabs.com/materialize-v1.0/form-file-uploads.html
https://github.com/shuyu/angular-material-fileinput

@johnleider
Copy link
Member

As of right now, this will not be done for the core of Vuetify.

@Darkside73
Copy link
Contributor

Darkside73 commented Apr 27, 2017

@dohomi Thanks for sharing. I've ended up with the following:

getFormData (files) {
  const data = new FormData()
  for (let file of files) {
    data.append('files[]', file, file.name)
  }
  return data
}

And it plays with multiple nicely

@jannhama
Copy link

Here is small class for selecting file:
https://github.com/jannhama/vuetify-upload-btn

@jofftiquez
Copy link
Contributor

+1M

@johnleider
Copy link
Member

johnleider commented Jun 28, 2017

I should have elaborated on my comment above. This will not be in the core of Vuetify, as far as the extensive functionality. However, we will include something like this in the addon packs that will come after Vuetify's release.

-edit- Forget this

@jofftiquez
Copy link
Contributor

Hi @johnleider may we know the reason why? Coz it seems to be a pretty solid feature to have.

@johnleider
Copy link
Member

Disregard my comment, we'll do it, but after the core components are complete.

@johnleider johnleider reopened this Jun 28, 2017
@jofftiquez
Copy link
Contributor

@johnleider WHOAH! You da real MVP. Thanks 👍

@dohomi
Copy link
Contributor

dohomi commented Jun 28, 2017

@jofftiquez meanwhile you can check this one out: https://gist.github.com/dohomi/2bba9e2905d00cd1cec9c09cfd87bd10

@jofftiquez
Copy link
Contributor

I certainly will @dohomi thanks a lot. :)

@lobosan
Copy link

lobosan commented Jul 27, 2017

I think many of us need this essential component, thanks in advance for adding this feature ;)

@johnleider
Copy link
Member

This will be something that will be included in the front end package development.

@mstaack
Copy link

mstaack commented Jul 27, 2017

i can highly recommend:
this for file/folder handling: https://github.com/silverwind/uppie
and this for generell vue upload needs: https://github.com/thetutlage/vue-clip

@nekosaur nekosaur added this to the Front-end Pack milestone Aug 6, 2017
@Tabrizian
Copy link

When will you add this feature?
A must have.

@johnleider
Copy link
Member

johnleider commented Aug 17, 2017 via email

@spaquet
Copy link

spaquet commented Aug 20, 2017

@mstaack Agre that http://vueclip.adonisjs.com/ is great to consider. It just need a nice UI out of the box.

@arpitprod
Copy link

arpitprod commented Sep 9, 2017

we need to add/update code in 'webpack.base.config.js' file for use vue-clip

module.exports = {
  resolve: {
    alias: {
      'vue': 'vue/dist/vue.js', // add for image upload things for use vue component in vue 2
    }
  },

@Tabrizian
Copy link

Tabrizian commented Sep 28, 2017

vueclip has only one version released? And its last update is 9 months ago! A risk to start using it.

@KaelWD
Copy link
Member

KaelWD commented Sep 28, 2017

@37ch4 @Gab0o777 @Mehtrick @mklemenz @efriedli
Cut it out with the +1 comments please, there's a button for that.

@vuetifyjs vuetifyjs deleted a comment from 37ch4 Sep 28, 2017
@someone1
Copy link

someone1 commented May 7, 2019

Wondering if I could chime in with a small request for the resulting implementation (I'm following the progress by comparing branches here) - my apologies if there was a discussion/spec I could have commented in/on instead.

I always find it difficult/frustrating to properly support an upload target to a cloud provider. The flow would be:

  1. User selects file(s) to upload
  2. For each file -> Do below
  3. Pass the file to a function to get the upload URL (containing the file name, content type, size) - in this case it will call an API to get a signed URL to upload to restricted by the content-type and file-size reported
  4. Upload the file to the URL provided
  5. [Optional] Support resumable uploads

Most uploads fumble on step 3 here for this use-cases: the type for the upload url is usually something like string|Function and not string|Function|Promise<string> (Replace Function with a specific signature if wanted). I'm using fetch for all my API calls, and so I would need support for the Promise addition here.

I'm migrating a project over from AngularJS + AngularMaterial and used ng-upload which supported my use-case in that it would just provide a component that would trigger a function with the file list and I would do steps 2 & 3 on my own, then use their Upload service which would carry out steps 4 & 5.

@MajesticPotatoe
Copy link
Member

@someone1 our uploader will require an upload function to run. It will be up to the user to determine how they will upload the data (be it rest, sockets, etc) as this will give the most flexibility.

general process so far:
1.) select file(s) to upload
2.) for each file:
a.) the file will be uploaded by browser (inputs standard upload function)
b.) file is parsed by requested FileReader format (user sets via prop, Binary, Text, DataURI etc etc)
c.) user upload function runs

straight out of the gate there wont be support for resumable uploads, though all internal file status's are accessible to the upload function so could be easily handled by the user.

@someone1
Copy link

someone1 commented May 7, 2019

Thanks for the quick reply @MajesticPotatoe !

For some uploads I wouldn't want to get a FileReader to read it all into memory only to send it along the pipe for uploading. I may also be mistaken here, but the result from the FileReader omits details like file name, size, and content-type so my flow would be unsupported.

With how the branch currently is coded (I realize it's a WIP), it looks like the user supplied uploader function is not given details to the file at all, just the data received by the FileReader, and progress is tracked by the FileReader progress. For large files, the entire file would be loaded into memory before being handed off to the uploader function, this wouldn't be suitable for large files.

From the docs it appears onLoad is only called once the entire file is read.

@MajesticPotatoe
Copy link
Member

Yes it's still WIP, FileReader is totally optional. It's just the current feature I'm working on ATM. At its basic level everything will be handled by users upload function. Initial release wont please everyone, its merely a staring point to cover as much ground as possible with little maintenance.

@annymosse
Copy link

currently im using this lib
https://github.com/pqina/vue-filepond
take a look at it ☝️

@yoldar
Copy link

yoldar commented May 13, 2019

currently im using this lib
https://github.com/pqina/vue-filepond
take a look at it ☝️

Great! But last time I used this lib there was memory leak when using in mobile browser(when using images from camera ~10-15mb) so I decided to switch to Uppy. I liked Uppy because it uses it's own modal panel to manage uploads and you decide yourself how uploaded files will be shown on your webpage.

@yannanna0920
Copy link

Disregard my comment, we'll do it, but after the core components are complete.
Let's just do it quickly we really need this component who wants somebody to say ok it turns out that the components aren't all that nice and they're not pretty so what can we do about it

@yannanna0920
Copy link

Here is an uploader component I create which inspired by v-text-field

uploader
can you share with us?

@softwareguy74
Copy link

So I guess this never made it? Seems like such a basic and universally needed feature for almost any type of app.

@johnleider
Copy link
Member

Just an update to everyone. This is currently in progress and will ship with v2.0 https://github.com/vuetifyjs/vuetify/tree/feat/%23238-file-upload

Thank you for your patience.

@hainuo
Copy link

hainuo commented Jun 20, 2019

Just an update to everyone. This is currently in progress and will ship with v2.0 https://github.com/vuetifyjs/vuetify/tree/feat/%23238-file-upload

Thank you for your patience.

How do I use this unreleased feature?

@softwareguy74
Copy link

Just an update to everyone. This is currently in progress and will ship with v2.0 https://github.com/vuetifyjs/vuetify/tree/feat/%23238-file-upload
Thank you for your patience.

How do I use this unreleased feature?

Um, not sure you can. Still being worked on.

@hainuo
Copy link

hainuo commented Jun 20, 2019

Just an update to everyone. This is currently in progress and will ship with v2.0 https://github.com/vuetifyjs/vuetify/tree/feat/%23238-file-upload
Thank you for your patience.

How do I use this unreleased feature?

Um, not sure you can. Still being worked on.

alright, i'll wait for the version 2.0

@Mikilll94
Copy link
Contributor

Is File Upload component available in v2.0.0-beta.3 ?

@chojnicki
Copy link

Is File Upload component available in v2.0.0-beta.3 ?

Nope.

johnleider added a commit that referenced this issue Jul 12, 2019
* feat(VFileInput): new component

closes #238

* feat(VFileInput): extend v-text-field, minor clean-up

* refactor(VFileInput): re-use available props and clean-up interactions

instead of hardcoding values, using the available props and overriding methods

* feat(VFileInput): improve counter support

* feat(VFileInput): add file icon to mdi-svg preset

* feat(VFileInput): add file icon to md preset

* feat(VFileInput): add file icon to fa and fa4 icon packs

* refactor(VFileInput): use stronger type for internalValue

* revert: refactor(VFileInput): use stronger type for internalValue

This reverts commit af3f3ae.

* feat(VFileInput): add fileValue prop with .sync modifier support

* feat(VFileInput): add progress prop

* feat(VFileInput): move counter to locale, add Russian variant

* feat(VFileInput): add displaySize prop to show files' size

* feat(VFileInput): add accept prop

* test(helpers): add test for humanReadableFileSize

* test(VFileInput): add tests

* feat(helpers): support base 1000 (si) for human readable file size

* feat(VFileInput): support 1000 base (si)

* chore: fix various errors

* fix(helpers): fix file size conversion

* test(VFileInput): full coverage

* feat(VFileInput): add chips support

* feat(VFileInput): add selection scoped slot

* fix(VFileInput): center only chips

* test(VFileInput): test chips prop

* fix(VFileInput): make fileValue watcher immediate

* feat(VFileInput): add smallChips prop

* refactor(VFileInput): clean up code, convert to use value, improve styles

* test(VFileInput): fix tests

* refactor(VFileInput): normalize prop name to match v-select

* docs(VFileInput): setup baseline doc page

* docs(VFileInput): add kitchen sink pan

* chore(VFileInput): change icon to cloud upload

* docs(VFileInput): add more examples to kitchen

* chore(VFileInput): correct typo in kitchen

* docs(VFileInput): add validation example to kitchen

* docs(VFileInput): add API generator map

* refactor(VFileInput): refactor and clean-up code

* chore(VFileInput): remove VNode import

* style(VFileInput): remove spaces in arrays

* docs(VFileInput): add multiple example

* docs(VFileInput): add accept example

* docs(VFileInput): add chips example

* docs(VFileInput): add small-chips example

* docs(VFileInput): add size example

* docs(VFileInput): add counter example

* chore(VFileInput): use multiple in chips examples

* docs(VFileInput): add custom-selection

* docs(VFileInput): add placeholder example

* docs(VFileInput): add custom-icon example

* docs(VFileInput): add validation example

* docs(VFileInput): add avatar example

* docs(VFileInput): clean up avatar example

* fix(VFilePicker): drop progress prop

* fix(VFileInput): drop deletableChips prop

* refactor(VFileInput): clean-up functionality, clean-up examples and language

* docs(VFileInput): update pan

Co-Authored-By: Dmitry Sharshakov <d3dx12.xx@gmail.com>

* Update pl.ts

* docs(VFileInput): update language

* chore(VFileInput): updates from feedback

* chore(VFileInput): even more updates from feedback

* docs(VFileInput): fix example

* fix(VFileInput): resolve mobile issues

* docs(VFileInput): add missing api language

* test(VFileInput): fix broken tests

* refactor(VFileInput): update default icon

* style: update snapshots
@johnleider johnleider self-assigned this Jul 12, 2019
@johnleider johnleider modified the milestones: Front-end Pack, v2.0.0 Jul 12, 2019
@forresthopkinsa
Copy link

🎉

@softwareguy74
Copy link

Can we get drag drop support where we can drag files from local computer to upload component?

@softwareguy74
Copy link

Can the chips have a close icon to remove specific file from list?

@jacekkarczmarczyk
Copy link
Member

v-file-input is the replacement for the native <input type=file> which doesn't support removing files, so the current status is that chip are not going to be deletable
Probably same for dragndrop support.
Anyway this issue is closed, if you have additional feature requests or found bugs please create a new issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: New Component This issue would need a new component to be developed. T: feature A new feature
Projects
None yet
Development

No branches or pull requests