pqina / vue-filepond

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

filepond multiple instance on the same page #42

Closed SoGooDFR closed 6 years ago

SoGooDFR commented 6 years ago

Hi,

I would like to known how make multiple filepond instance with different options on the same page ? Actually i've two vue compoment, and one compoment override filepond options for all filepond input/instance.

rikschennink commented 6 years ago

The setOptions method should override everything globally, but setting different attributes to the components should work. Does it not? Can you provide an example implementation?

icangku commented 5 years ago

no one was able to solve this?

rikschennink commented 5 years ago

@icangku not without the requested information

gregsherrid commented 5 years ago

@icangku I wasn't able to figure this out for a while either. The solution I'm using right now is the @init handler on the FilePond object:

    <file-pond
        name="test"
        ref="pond"
        label-idle="Drop files here..."
        v-bind:allow-multiple="true"
        accepted-file-types="image/jpeg, image/png"
        server="/api"
        v-bind:files="myFiles"
        v-on:init="handleFilePondInit"/>

and

    handleFilePondInit: function() {
      this.$refs.pond.maxFiles = 10;
      this.$refs.pond.server = {
        process: (fieldName, file, metadata, load, error, progress, abort) => {
          console.log("Processing")
        }
      }
    }

This does, however, cause the [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. to fire. @rikschennink is there a better way to do this?

icangku commented 5 years ago

i use laravel as backend, so my problem was solved by disable csrf token, so i don't need to setup setOptions, but i don't think its the best solution.

themodernpk commented 4 years ago

anyone found solution to this??

rikschennink commented 4 years ago

@gregsherrid @modernpk I don't understand why you wouldn't use a bind? Like how the files property is set in the vue example on the readme?

themodernpk commented 4 years ago

@rikschennink that's what I have already tried https://gist.github.com/modernpk/5821b0a0ea131e051282bb74ccbf5ec5. The function I am trying to call in onload is being replaced by last fond-pond component on the same page:

this.server = {
                    ...
                    process:{
                        ...
                        onload: function (data) {
                            data = JSON.parse(data);
                            if(data && data.data)
                            {
                                self.afterUpload(data.data); //THIS FUNCTION
                            }
                        },
                       ...
                    }
                };

So, multiple instances on the same page replace the server configuration even if we use v-bind.

themodernpk commented 4 years ago

It may work fine for 2 instances, as soon as you add 3 or more it overwrite the server configurations.

rikschennink commented 4 years ago

@modernpk this does seem to work: https://codesandbox.io/s/vue-filepond-multiple-instances-8fl1d?file=/src/components/FilePondDemo.vue

logs A, B, C when dropping a file in each of the filepond instances

themodernpk commented 4 years ago

Nothing to do with filepond, I created a Vue Component and called incorrectly which actually was not overriding the server props.

sentiasa commented 3 years ago

I had the same problem with multiple filepond instances (on different components) on the same page.

Before, I was using setOptions like so:

 <file-pond
      checkValidity="false"
      @init="handleFilePondInit"
      credits="false"
      ref="pond"
      :allow-multiple="allowMultiple"
      :accepted-file-types="getMimeTypes()"
      :required="required"
 />

handleFilePondInit() {
      let config = {
        allowRevert: false,
        allowFileSizeValidation: true,
        maxFileSize: this.maxFileSize,
        allowFileTypeValidation: true,
      }

      if (this.url) {
        config.server = this.handleServerProcess();
      } else {
        config.onaddfile = this.onFileAdded;
        config.onremovefile = this.onFileRemoved;
      }

      setOptions(config);
}

I removed server/manual approaches to relevant event handler on the component rather than setOptions. Here is the working way for me:

 <file-pond
      checkValidity="false"
      @init="handleFilePondInit"
      credits="false"
      ref="pond"
      :allow-multiple="allowMultiple"
      :accepted-file-types="getMimeTypes()"
      :required="required"
      :server="url ? handleServerProcess() : null"
      @addfile="onFileAdded"
      @removefile="onFileRemoved"
 />

 handleFilePondInit() {
      let config = {
        allowRevert: false,
        allowFileSizeValidation: true,
        maxFileSize: this.maxFileSize,
        allowFileTypeValidation: true,
      }

      setOptions(config);
 },

handleServerProcess() {
      return {
        process: (fieldName, file, metadata, load, error, progress, abort) => {
             // POST implementation
        }
      }
}

onFileAdded(error, file) {
      if (this.url) return;
      this.$emit('added', file);
},

onFileRemoved(error, file) {
      if (this.url) return;
      this.$emit('removed', file);
},

(url is prop that helps to decide if it's server or manual upload).

And it worked 🎉

Jobayer-Tuser commented 2 years ago

I have created a dynamic file pond instance in pure javascript anyone can try this with a PHP project.

//Default Html input for Filepond 
 <input id="pond1" type="file" class="filepond d-none imageOptions" name="image_options[]" data-allow-reorder="true" data-max-file-size="2MB" data-max-files="4" accept="image/png, image/jpeg, image/gif" />

 //wrapper where the new input field will appear
 var wrapper = $('.multipleOptions');

 //Once add button is clicked create new filepond image upload option
 $(addButton).click(function(){
     optionCount++;
     var fieldHTML =`<input id="pond${optionCount}" type="file" class="filepond imageOptions" name="image_options[]" data-allow-reorder="true" data-max-file-size="2MB" data-max-files="4"/>`;
     $(wrapper).append(fieldHTML);

     let pondId = "pond" + optionCount;
     loadFilepond(pondId);
 });

 //call first instance of filepond
 loadFilepond('pond1');

 //create and load multiple filepond instance dynamically on addButton click
 function loadFilepond( filePondId ){
     console.log('input#' + filePondId);
     let inputElement = document.querySelector('input#' + filePondId);
     FilePond.create(inputElement);
     FilePond.setOptions({
         allowMultiple: true,
         server: {
             url :  "/uploads/tmp",
             headers: {
                 'X-CSRF-TOKEN' : '{{ csrf_token() }}'
             }
         }
     })
 }