dunhilblack
dunhilblack

Reputation: 305

How to turn multiple files into filebase64 in Vue?

I have a form input with multiple file input for png,pdf,jpg,jpeg. How can I turn them into base64 string?

I have tried this this is the HTML:

<div class="form-group">
            <label for="npwp">NPWP</label>
            <input type="file" 
            class="form-control-file" 
            id="npwp"
            accept="application/pdf/png/jpg/jpeg"
            @change="updateFormData($event)">
          </div>
          <div class="form-group">
            <label for="NIB">NIB</label>
            <input type="file" 
            class="form-control-file" 
            id="NIB"
            accept="application/pdf/png/jpg/jpeg"
            @change="updateFormData($event)">
          </div>
          <div class="form-group">
            <label for="Logo">Logo</label>
            <input type="file"
            class="form-control-file"
            id="Logo"
            accept="application/pdf/png/jpg/jpeg"
            @change="updateFormData($event)">
          </div>
          <div class="form-group">
            <label for="Others">Others</label>
            <input type="file"
            class="form-control-file"
            id="Others"
            accept="application/pdf/png/jpg/jpeg"
            @change="updateFormData($event)">
          </div>

javascript:

data() {
return {
   files: [
    {
    selectedFile: null 
   },{
    selectedFile: null 
   },{
    selectedFile: null 
   },{
    selectedFile: null 
   },
  ]
 } 
}

methods:
updateFormData(event) {
      const reader = new FileReader();

      const file = event.target.files[0];

      reader.readAsDataURL(file);
      reader.onload = () => {
        const fileBase64 = reader.result.split(',')[1];
        this.files.selectedFile = fileBase64;
      };
      this.shown = false;
    },

But the code above only is for a single input only. How do I make them loop through the input?

Upvotes: 0

Views: 228

Answers (1)

Harshal Patil
Harshal Patil

Reputation: 21030

Since, you have limited files, it should be very trivial. In you HTML template, pass fileId to the @change event handler. Your template would be:

<div class="form-group">
    <label for="npwp">NPWP</label>
    <input type="file" 
    class="form-control-file" 
    id="npwp"
    accept="application/pdf/png/jpg/jpeg"
    @change="updateFormData('npwp',$event)">
</div>

<div class="form-group">
    <label for="NIB">NIB</label>
    <input type="file" 
    class="form-control-file" 
    id="NIB"
    accept="application/pdf/png/jpg/jpeg"
    @change="updateFormData('nib', $event)">
</div>

<div class="form-group">
    <label for="Logo">Logo</label>
    <input type="file"
    class="form-control-file"
    id="Logo"
    accept="application/pdf/png/jpg/jpeg"
    @change="updateFormData('logo', $event)">
</div>

<div class="form-group">
    <label for="Others">Others</label>
    <input type="file"
    class="form-control-file"
    id="Others"
    accept="application/pdf/png/jpg/jpeg"
    @change="updateFormData('others', $event)">
</div>

In your JS file, add the read file into corresponding field like:

new Vue({
    data() {
        return {
            files: {
                'npwp': '',
                'nib': '',
                'logo': '',
                'others': '',
            }
        };
    },

    methods: {
        updateFormData(fileId, event) {
            const reader = new FileReader();

            const file = event.target.files[0];

            reader.readAsDataURL(file);

            reader.onload = () => {
                const fileBase64 = reader.result.split(',')[1];
                this.files[fileId] = fileBase64;
            };
            this.shown = false;
        }
    }

});

If you have multiple files with unknown length, then files should be an array and instead of passing fileId as constant value, use index as a first argument to the handler.

Upvotes: 1

Related Questions