How can I validate the maximum file size is 2 mb per file for multiple files? (vuetify)
Asked Answered
T

2

7

I'm trying to setup a validation rule on Vuetify's v-file-input to limit file sizes to 2MB, but the validation incorrectly fails (and the input error appears) when I select files under 2MB.

Excerpt of my Codepen:

<v-file-input
  multiple
  :rules="rules"
  accept="image/jpg, image/jpeg, application/pdf"
  placeholder="Pick an avatar"
  prepend-icon="mdi-camera"
  label="Avatar"
></v-file-input>

<script>
  //...
  data: () => ({
    rules: [
      value => !value || value.size < 2000000 || 'Avatar size should be less than 2 MB!',
    ],
  }),
  //...
</script>

How do I solve this problem?

Topliffe answered 7/2, 2020 at 7:6 Comment(0)
R
19

The problem is your v-file-input accepts multiple files, so the argument of the validation rule is actually an array of File object(s) (even if only one file selected). The rule function should look similar to this:

files => !files || !files.some(file => file.size > 2e6) || 'Avatar size should be less than 2 MB!'

The rule uses Array.prototype.some on the files array to determine if any of the file sizes are over 2 * 10^6. However, since file sizes are in terms of bytes, I recommend comparing to 2MiB instead (i.e., 2 * 1024 * 1024 = 2_097_152).

Demo:

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: () => ({
    rules: [
      files => !files || !files.some(file => file.size > 2_097_152) || 'Avatar size should be less than 2 MB!'
    ],
  }),
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/vuetify.min.css">
<link rel="stylesheet" href="https://unpkg.com/@mdi/[email protected]/css/materialdesignicons.min.css">

<div id="app">
  <v-app id="inspire">
    <v-file-input
      multiple
      :rules="rules"
      accept="image/jpg, image/jpeg, application/pdf"
      placeholder="Pick an avatar"
      prepend-icon="mdi-camera"
      label="Avatar"
    ></v-file-input>
  </v-app>
</div>
Rufusrug answered 7/2, 2020 at 8:8 Comment(0)
W
2

Well, I haven't tested it, but something like this should work. In your upload method, loop through the input files and check wether they're all below 2mb:

const input = event.target
let files = input.files
//loop through this to check all the file sizes.
const isLt2M = files[0].size / 1024 / 1024 < 2;
Wireman answered 7/2, 2020 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.