pqina / vue-filepond

🔌 A handy FilePond adapter component for Vue
https://pqina.nl/filepond
MIT License
1.92k stars 128 forks source link

Cannot append a Vue-FilePond instance to a DOM element. #228

Closed majortom64 closed 2 years ago

majortom64 commented 2 years ago

Is there an existing issue for this?

Have you updated Vue FilePond, FilePond, and all plugins?

Describe the bug

I am trying to make a DIV be a FilePond Element. I followed the in the documentation with the following code:

    handleFilePondInit: function() {
      console.log('FilePond has initialized')

      // example of instance method call on pond reference
      let pondDiv = this.$el.querySelector('#ctFilePond1a')
      this.$refs.ctPond.appendTo(pondDiv)
    },
                <div
                  id="ctFilePond1a"
                  ref="ctFilePond1a"
                  class="filepond--root mt-1 border-2 bg-red-300 border-gray-300 border-dashed rounded-md px-6 pt-5 pb-6 flex justify-center "
                  @dragover.prevent
                  @drop.prevent
                >
                  <div class="space-y-1 text-center">
                    <svg
                      class="mx-auto h-12 w-12 text-gray-400"
                      stroke="currentColor"
                      fill="none"
                      viewBox="0 0 48 48"
                      aria-hidden="true"
                    >
                      <path
                        d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
                        stroke-width="2"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                      />
                    </svg>

                    <span>Upload a file </span>
                    <FilePond
                      id="ctFilePond1a"
                      ref="ctPond"
                      name="ctUploads"
                      accepted-file-types="*"
                      label-idle=""
                      allow-multiple="true"
                      instant-upload="false"
                      :files="ctFiles"
                      @init="handleFilePondInit"
                      @updatefiles="handleUpdateFiles"
                    />

                    <p class="text-xs text-gray-500">
                      PNG, JPG, GIF up to 15MB
                    </p>
                  </div>
                </div>

The error I get is: TypeError: this.$refs.ctPond.appendTo is not a function. (In 'this.$refs.ctPond.appendTo(pondDiv)', 'this.$refs.ctPond.appendTo' is undefined)

Reproduction

<template>
  <div>
    <div class="shadow sm:rounded-md sm:overflow-hidden">
      <form action="#" method="POST">
        <div class="shadow sm:rounded-md sm:overflow-hidden">
          <div class="bg-white py-6 px-4 space-y-6 sm:p-6">
            <div class="grid grid-cols-6 gap-6">
              <div class="col-span-6">
                <!-- <div class="col-span-3"> -->
                <div
                  id="ctFilePond1a"
                  ref="ctFilePond1a"
                  class="filepond--root mt-1 border-2 bg-red-300 border-gray-300 border-dashed rounded-md px-6 pt-5 pb-6 flex justify-center "
                  @dragover.prevent
                  @drop.prevent
                >
                  <div class="space-y-1 text-center">
                    <svg
                      class="mx-auto h-12 w-12 text-gray-400"
                      stroke="currentColor"
                      fill="none"
                      viewBox="0 0 48 48"
                      aria-hidden="true"
                    >
                      <path
                        d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
                        stroke-width="2"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                      />
                    </svg>
                    <span>Upload a file </span>
                    <FilePond
                      id="ctFilePond1a"
                      ref="ctPond"
                      name="ctUploads"
                      accepted-file-types="*"
                      label-idle=""
                      allow-multiple="true"
                      instant-upload="false"
                      :files="ctFiles"
                      @init="handleFilePondInit"
                    />
                    <p class="text-xs text-gray-500">
                      PNG, JPG, GIF up to 15MB
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
            <button
              type="submit"
              class="bg-indigo-600 border border-transparent rounded-md shadow-sm py-2 px-4 inline-flex justify-center text-sm font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
            >
              Save
            </button>
          </div>
        </div>
      </form>
    </div>
  </div>
</template>

<script>
import { useStore } from 'vuex'
import { computed } from 'vue'

import vueFilePond from 'vue-filepond'
import 'filepond/dist/filepond.min.css'

import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css'
//const myFilePond = filePond(FilePondPluginImagePreview)
const FilePond = vueFilePond(FilePondPluginImagePreview)

export default {
  name: 'DocMin',
  components: {
    FilePond
  },
  setup() {
    const store = useStore()
    const email = computed(() => store.getters['user/email'])

    return {
      //   navigation,
      email
    }
  },

  data: () => ({
    isSending: false
  }),
  methods: {
    handleFilePondInit: function() {
      console.log('FilePond has initialized')

      // example of instance method call on pond reference
      let pondDiv = this.$el.querySelector('#ctFilePond1a')
      this.$refs.ctPond.appendTo(pondDiv)
    },

    startUpload: function() {
      console.log('upload begins')
    }
  }
}
</script>

<style scoped lang="postcss">
:deep(.filepond--panel-root) {
  background-color: indianred;
}

:deep(.filepond--drop-label) {
  background-color: indianred;
}
</style>

The goal is to make the light red area the drop zone, not just the dark red (what is the current Vue-FilePond object). Screen Shot 2021-12-20 at 10 00 49 AM

Environment

MacMini 2018
macOS 12.1
Browser: FireFox 95.0.1 and Safari 15.2
Vue: 3.2.6
TailwindCSS V3.0
rikschennink commented 2 years ago

If you want to use FilePond like this (append it to another element) then I'd advise not to use the Vue FilePond wrapper but instead use the core library.

Alternatively you can adjust the FilePond styles to enlarge the drop area.

majortom64 commented 2 years ago

Is there a list of which methods are available on Vue-FilePond vs those that are not?

rikschennink commented 2 years ago

There is not, for the most part you should not use the functions that interact with the DOM, that's what the components are for.