Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 297
moses toh Avatar asked Feb 07 '20 07:02

moses toh


2 Answers

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>
like image 119
tony19 Avatar answered Oct 21 '22 22:10

tony19


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;
like image 1
Reinier68 Avatar answered Oct 21 '22 23:10

Reinier68