0

In my vuejs application, I have a modal to insert some user data with a file upload.

I should be able to clear all the form fields once when an user successfully upload any content.

All my fields get reset apart from the file upload field.

It will remained as it is.

Inside my form.vue, for the file upload I have

<div class="mb-1">
            <dashboard-input-label
              identifier="document"
              :settings="{ help: true, helpDirection: 'left' }"
            >
              Upload document
              <template slot="helpText">
                Maximum filesize is 5 MB. The default allowed file extensions
                are: pdf, jpeg and png.
              </template>
            </dashboard-input-label>
            <validator-v2
              :identifier="identifier"
              name="document_file"
              :rules="{ required: { message: 'Document is required.' } }"
            >
              <custom-file-upload
                ref="documentDocument"
                v-model="documentFile"
                :max-upload-file-size="5"
                name="document_file"
              ></custom-file-upload>
            </validator-v2>
          </div>

and following is my button

<loading-button ref="submitBtn" size="normal">
              Save & Add new
            </loading-button> 

This is my submitBtn method,

storeDocumentAndAddNew() {
      this.isAddNew = true
      const loader = this.$refs.submitBtn
      this.storeDocument(loader)
    },

And for the field reset I have followings,

reset() {
      this.documentName= null
      this.dateOfIssue= null
      this.expiryDate= null
      this.documentNumber = null
      this.doesNotHaveDocumentNumber = false
      this.doesNotExpire = false
      this.documentFile = null
      this.doesOptIn = false
      this.isAddNew = false
      this.documentFile = ''
      this.$refs.documentDocument.value = null
    },

Once I hit submit, every field get reset except this file upload field.

Following is my custom-file-upload.vue component

<template>
    <div>

        <div class="flex items-center flex-wrap">

            <div @click="selectFile" class="flex items-center cursor-pointer w-full form-input custom-file-upload ">

                <p class="flex justify-between items-center w-full overflow-hidden">
                    <span class="font-regular text-base flex items-center justify-center">
                        <span v-if="filename !== null">{{ filename | limitString }} </span>
                        <span class="cs--file-upload-current-file overflow-hidden inline-block" v-else><slot
                            name="currentFile"></slot></span>
                    </span>

                    <span class="text-certstyle-text-light ">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                             stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                             class="feather feather-upload"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline
                            points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
                    </span>

                </p>

                <input @change="showFileName" ref="fileInput" type="file" :name="name">
                <div class="flex flex-col fixed top-0 right-0 z-50">
                    <toastr-alert @hidden="resetToastrMessage" v-if="message !== ''" :message="message"
                                  :type="type"></toastr-alert>
                </div>
            </div>
        </div>

    </div>

</template> 

Even though I've used, this.$refs.documentDocument.value = null it's not clearing my file upload field....

Update

I have used @wendt88's answer and then the file is removed. But the previously uploaded, document's name will be remained there as it is..As an example, if I tried to upload a document called, dummy.pdf, it'll show the dummy.pdf text even after a successful submission...

Now my reset looks likes this,

reset() {
      this.documentName= null
      this.dateOfIssue= null
      this.expiryDate= null
      this.documentNumber = null
      this.doesNotHaveDocumentNumber = false
      this.doesNotExpire = false
      this.documentFile = null
      this.doesOptIn = false
      this.isAddNew = false
      this.$refs.documentDocument.$refs.fileInput.value = null
    },

Following is my complete custom-file-upload.vue

<template>
    <div>

        <div class="flex items-center flex-wrap">

            <div @click="selectFile" class="flex items-center cursor-pointer w-full form-input custom-file-upload ">

                <p class="flex justify-between items-center w-full overflow-hidden">
                    <span class="font-regular text-base flex items-center justify-center">
                        <span v-if="filename !== null">{{ filename | limitString }} </span>
                        <span class="cs--file-upload-current-file overflow-hidden inline-block" v-else><slot
                            name="currentFile"></slot></span>
                    </span>

                    <span class="text-certstyle-text-light ">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                             stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                             class="feather feather-upload"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline
                            points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
                    </span>

                </p>

                <input @change="showFileName" ref="fileInput" type="file" :name="name">
                <div class="flex flex-col fixed top-0 right-0 z-50">
                    <toastr-alert @hidden="resetToastrMessage" v-if="message !== ''" :message="message"
                                  :type="type"></toastr-alert>
                </div>
            </div>
        </div>

    </div>

</template>
<style lang="scss" scoped>
.custom-file-upload input {
    position: absolute;
    cursor: pointer;
    height: 0;
    width: 0;
    opacity: 0;
}

.cs--file-upload-current-file {
    max-width: 220px;
}

label {
    font-weight: 400 !important;
}


</style>
<script>
// Mixins
import HasToastrMessage from '@/Mixins/HasToastrMessage.js';

// Helper
import Helper from '@/Support/Helper.js';

export default {
    mixins: [HasToastrMessage],
    props: ['name', 'value', 'maxUploadFileSize'],

    data() {
        return {
            file: null,
            filename: null,
            message: "",
            type: "",
            fileSize: 0,
            maxFileSize: 10,
            validFileTypes: [
                'application/pdf',
                'image/jpeg',
                'image/png'
            ]
        }
    },

    mounted() {
        if (Helper.isset(this.maxUploadFileSize)) {
            this.maxFileSize = this.maxUploadFileSize;
        }
    },

    methods: {


        showFileName(e) {
            this.filename = collect(e.target.value.split('\\')).last();
            let file = e.target.files[0];
            let fileSize = file.size / 1000000;

            if (fileSize > this.maxFileSize) {
                this.showToastrErrorMessage(`The uploaded file is too big. Max size: ${this.maxFileSize} MB.`);
                this.$refs.fileInput.value = null
                this.filename = null
            } else if (!this.validFileTypes.includes(file.type)) {
                this.showToastrErrorMessage(`The uploaded file is invalid. Please upload valid type.`);
                this.$refs.fileInput.value = null
                this.filename = null
            } else if (this.filename) {
                this.file = file
                this.showToastrSuccessMessage(`Your file is successfully uploaded.`);
                this.$emit('uploaded')
            } else {
                this.showToastrErrorMessage(`Your file could not be uploaded. Please try again.`);
            }
        },

        resetToastrMessage() {
            this.message = "";
            this.type = "";
        },

        selectFile() {
            this.$refs.fileInput.click();
        },
    }

}

</script>
Volka Dimitrev
  • 337
  • 4
  • 15
  • 38

1 Answers1

1

this.$refs.documentDocument is a vue component, to clear it´s value property use this.$set(this.$refs.documentDocument, 'value', null) -> https://v2.vuejs.org/v2/guide/reactivity.html otherwise documentDocument does not know that you have changed it´s value

but if you want to clear the file input value, run (https://stackoverflow.com/a/16222877/1826106):

this.$refs.documentDocument.$refs.fileInput.value = null;
this.$set(this.$refs.documentDocument, 'filename', null);
wendt88
  • 544
  • 5
  • 22