Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine normal form with filepond vuejs #99

Closed
helderferrari2 opened this issue Jul 28, 2019 · 5 comments
Closed

Combine normal form with filepond vuejs #99

helderferrari2 opened this issue Jul 28, 2019 · 5 comments

Comments

@helderferrari2
Copy link

I am developing using Laravel 5.6 + Vuejs and I am in doubt using Filepond 5.1.

I have a form with user data and would like to send only 1 request to the server, containing the user data with the 5 images loaded, when the user clicks the submit button, is it possible to do this with filepond?

I read some tutorials but found nothing concrete.

The request is sent, but laravel does not recognize the images field when using request->file('images') on controller.

Example:

VUEJS

<form>
<input type="text" name="username">
<input type="text" name="description">
<filepond></filepond>
<button type="submit">Submit</button>
</form>

API Laravel

public function store(Request $request){
dd($request->has('files'); //Get Array Files here
}

FormComponent

 <file-pond
        name="images"
        label-idle="Carregar Imagens ..."
        allow-multiple="true"
        accepted-file-types="image/jpeg, image/png"
        max-files=3
        server="http://localhost:3000/api/images/storeImage"
        @onprocessfiles="handleSubmitImages"
        @updateFiles="updatedFiles"
      />
      ....
      <script>
        data() {
          return {
            formData: {
              username: "",//Some Additional Data
              description: "",//Some Additional Data
              images: [], //Array images HERE
            }
          };
         },
        methods:{
           storeProduct() {
              this.$store.dispatch('storeNewProduct', this.formData)
              .then(response => {
               ...
               })
            .catch(error => {
               ...
             });
          },
         updateFiles(files) {
           this.formData.images = files; //Add Files to array Images on formData
         }
       </script>

VUEX

    storeNewProduct(context, params) {
        return new Promise((resolve, reject) => {
            axios.post('/api/products', params)
                .then(response => {
                    console.log('vuex', response.data.data)
                    context.commit("SET_USER_PRODUCTS",response.data.data)
                    resolve()
                })
                .catch(error => reject())
        })
    },

Capturar1

@rikschennink
Copy link
Collaborator

FilePond will POST each individual file to http://localhost:3000/api/images/storeImage

If you want to send everything together you have to listen to the onupdatefiles event and populate the images array from there.

@helderferrari2
Copy link
Author

ok, so I must remove the server property from the component, Then add something like:

<file-pond>
@onUpdateFiles="onUpdateFiles"
</file-pond>
methods: {
onUpdateFiles (file) {
this.formData.images = file;
}

To send the array, do I need to declare const data = new FormData ()?

@rikschennink
Copy link
Collaborator

I'm not sure how that works in Vue. onUpdate files returns a file items array you'll have to extract the file objects before adding them to your FormData object.

@helderferrari2
Copy link
Author

@rikschennink, thank you for support.
Finally I found a solution, thanks for the amazing package, follows my code:

FormComponent:

<template>
<form @submit.prevent="store" enctype="multipart/form-data">
       
//Normal fields
<input type="text" v-model="formData.username">
<input type="email" v-model="formData.email">

           //Upload Images
          <file-pond
            ref="pond"
            label-idle="Drop files here"
            max-files="4"
            allow-multiple="true"
            instant-upload="false"
            v-on:updatefiles="handleFilePondUpdateFile"
          />

<button type="submit">Send</button>
</form>
</template>

<script>
import vueFilePond from "vue-filepond";

// Import plugins
import FilePondPluginFileValidateType from "filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.esm.js";
import FilePondPluginImagePreview from "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.esm.js";

// Import styles
import "filepond/dist/filepond.min.css";
import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css";

// Create FilePond component
const FilePond = vueFilePond(
  FilePondPluginFileValidateType,
  FilePondPluginImagePreview
);

export default {
  components: {
    FilePond
  },

  data() {
    return {
      myFiles: [],
      formData: {
        username: "",
        email: ""
      }
    };
  },

  methods: {

    //Set Images to Array
    handleFilePondUpdateFile(files){
      this.myFiles = files.map(files => files.file);
    },

    store() {
      //Assign all fields to formData to send via post
      const formData = new FormData();
      formData.append("username", this.formData.username);
      formData.append("email", this.formData.email);
     
    //Set all files to formData
      for (var i = 0; i < this.myFiles.length; i++) {
        let file = this.myFiles[i];
        formData.append("files[" + i + "]", file);
      }

      this.$store
        .dispatch("store", formData)
        .then(response => {
          this.$snotify.success("Success");
        })
        .catch(error => {
          this.$snotify.error("Error");
        });
    },
</script>

Vuex:

        store(context, formData) {
            const config = {
                headers: { 'content-type': 'multipart/form-data' }
            }
            return new Promise((resolve, reject) => {
                axios.post('/api/products', formData, config)
                    .then(response => {
                        console.log(response.data)
                        resolve()
                    })
                    .catch(error => reject())
            })
        },

API Laravel:

//Get all images in array to store in laravel storage
foreach ($request->file('files') as $file) {
        $filename = str_random(5) . '.' . $file->extension(); //Custom Filename
        Storage::put('public/' . $filename, $file); //Store image
}

I will be writing a post in the future to help other devs.

Thank you so much for your help and success.

@ElBeyonder
Copy link

Esto de verdad me interesa mucho no hay mucha información sobre esto, intento hacerlo de la misma
forma pero solo con jQuery, aunque si se puede hacer con Vue y axios estaría bien para mi, ya que también uso Vue en el proyecto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants