yukashima huksay
yukashima huksay

Reputation: 6238

Give initial file name value to Vuetify v-file-input

I have this html in my template:

        <v-file-input
          :label="label"
          accept="image/*"
          prepend-icon="mdi-camera"
          @change="uploadImage"
          hide-details
          outlined
        />

My component also has a prop called current which contains a text which is the name of the current file.

When the component is displayed the v-file-input is empty but I want it to include the name of the current file name. I've tried :value="current" and v-model="current" to no avail.

What should I do?

Upvotes: 5

Views: 8226

Answers (4)

Austyn Wilson
Austyn Wilson

Reputation: 362

Workaround:

DOM:

<v-file-input v-model="file" class="v-file-input"></v-file-input>

CSS:

/**/
.v-file-input label {
    /**/
    transform: translateY(-6px) scale(.75) !important;
    /**/
}

JS:

/**/
new Vue({
    /**/
    el: "#app",
    /**/
    vuetify: vuetify,
    /**/
    data: () => ({
        /**/
        default: {
            /**/
            name: null,
            /**/
            size: null,
            /**/
        },
        /**/
        file: null,
        /**/
    }),
    /**/
    updated(){
        /**/
        $(".v-file-input").find(".v-file-input__text").html(this.file ? `<div>${this.file.name} (${this.readableBytes(this.file.size)})</div>` : this.default.name ? `<div>${this.default.name} (${this.readableBytes(this.default.size)})</div>` : "");
        /**/
    },
    /**/
    methods: {
        /**/
        readableBytes: function(x){
            /**/
            const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
            /**/
            var i = 0, n = parseInt(x, 10) || 0;
            /**/
            while(n >= 1024 && ++i){
                /**/
                n = n / 1024;
                /**/
            }
            /**/
            return n.toFixed(n < 10 && i > 0 ? 1 : 0) + " " + units[i];
            /**/
        },
    }
});

Upvotes: 0

Arno van Oordt
Arno van Oordt

Reputation: 3510

You can use the placeholder attribute for this:

<v-file-input label="File input" :placeholder="current" ></v-file-input>

The style might be a bit different than the "normal" text but a bit of css can probably fix that.

Upvotes: 1

Michal Lev&#253;
Michal Lev&#253;

Reputation: 37773

You can use value prop. But it doesn't accept strings. From the docs:

value - A single or array of File objects

So for example this works:

data() {
    return {
      current: new File(["foo"], "foo.txt", {
                  type: "text/plain",
                })
    }
  }
<v-file-input label="File input" :value="current" ></v-file-input>

Whether it's a good idea to do this is different question :) You know, what you have is not just file name, its whole file including content. What if user submits your form like this? Also support for File() constructor is not that great....will not work on Edge for example...

Upvotes: 8

Md. Jahidul Islam
Md. Jahidul Islam

Reputation: 316

Instead use a computed property, since props are immutable and use value for data binding v-model="value"

computed () {
    value: {
      get () {
        return this.current
      },
      set (val) {
        this.value = val
      }
    }
  }

Upvotes: 0

Related Questions