How can I add multiple images along with other input fields in vue js html? How can I add multiple images along with other input fields in vue js html? vue.js vue.js

How can I add multiple images along with other input fields in vue js html?


Using axios:

Template

...<input type="file" name="photo" accept="image/*" @change="setPhotoFiles($event.target.name, $event.target.files) />...

Code

data () {  return {    ...    photoFiles: [],    ...  }},...methods: {  ...  setPhotoFiles (fieldName, fileList) {    this.photoFiles = fileList;  },  ...  handleSubmit (e) {    const formData = new FormData();    formData.append('name', this.name);    formData.append('alias', this.alias);    formData.append('sex', this.sex);    ...    this.photoFiles.forEach((element, index, array) => {      formData.append('photo-' + index, element);    });    axios.post("http://localhost:4000/save/", formData)      .then(function (result) {        console.log(result);        ...      }, function (error) {        console.log(error);        ...      });  }}


I'm not sure where would you like the extra images to appear, but I added them after this column:

<div class="col-md-4">  <div class="button success expand radius">    <span id="save_image_titlebar_logo_live">Recent Photograph</span>    <label class="custom-file-upload">  <input type="file" name="sign"/>  </label>  </div></div>

And here's the column I added — "add images": (You can try this feature here, with the updates)

<div class="col-md-4">  <ul class="list-group" :if="images.length">    <li class="list-group-item" v-for="(f, index) in images" :key="index">      <button class="close" @click.prevent="removeImage(index, $event)">×</button>      <div class="button success expand radius">        <label class="custom-file-upload">          <input type="file" class="images[]" accept="image/*" @change="previewImage(index, $event)">        </label>      </div>      <div :class="'images[' + index + ']-preview image-preview'"></div>    </li>  </ul>  <button class="btn btn-link add-image" @click.prevent="addNewImage">Add Image</button></div>

And the full Vue JS code (with jQuery.ajax()):

addForm = new Vue({  el: "#addForm",  data: {    name: '',    alias: '',    sex: '',    sez: [{      date: null,      details: null    }],    // I removed `photo` and `sign` because (I think) the're not necessary.    // Add I added `images` so that we could easily add new images via Vue.    images: [],    maxImages: 5,    // Selector for the "Add Image" button. Try using (or you should use) ID    // instead; e.g. `button#add-image`. But it has to be a `button` element.    addImage: 'button.add-image'  },  methods: {    addNewRow: function() {      // I changed to `this.sez.push` because `this.seziure` is `undefined`.      this.sez.push({        date: null,        details: null      });    },    addNewImage: function(e) {      var n = this.maxImages || -1;      if (n && this.images.length < n) {        this.images.push('');      }      this.checkImages();    },    removeImage: function(index) {      this.images.splice(index, 1);      this.checkImages();    },    checkImages: function() {      var n = this.maxImages || -1;      if (n && this.images.length >= n) {        $(this.addImage, this.el).prop('disabled', true);  // Disables the button.      } else {        $(this.addImage, this.el).prop('disabled', false); // Enables the button.      }    },    previewImage: function(index, e) {      var r = new FileReader(),        f = e.target.files[0];      r.addEventListener('load', function() {        $('[class~="images[' + index + ']-preview"]', this.el).html(          '<img src="' + r.result + '" class="thumbnail img-responsive">'        );      }, false);      if (f) {        r.readAsDataURL(f);      }    },    handleSubmit: function(e) {      var vm = this;      var data = new FormData(e.target);      data.append('sez', this.sez);      data.append('name', this.name);      data.append('alias', this.alias);      data.append('sex', this.sex);      // The `data` already contain the Signature and Recent Photograph images.      // Here we add the extra images as an array.      $('[class~="images[]"]', this.el).each(function(i) {        if (i > vm.maxImages - 1) {          return; // Max images reached.        }        data.append('images[' + i + ']', this.files[0]);      });      $.ajax({        url: 'http://localhost:4000/save/',        data: data,        type: 'POST',        dataType: 'json',        success: function(e) {          if (e.status) {            vm.response = e;            alert("success");          } else {            vm.response = e;            console.log(vm.response);            alert("Registration Failed");          }        },        cache: false,        contentType: false,        processData: false      });      return false;    },  },});

Additional Notes

I know you're using Node.js in the back-end; however, I should mention that in PHP, the $_FILES variable would contain all the images (so long as the fields name are properly set); and I suppose Node.js has a similar variable or way of getting the files.

And in the following input, you may have forgotten to wrap book.details in v-model:

<input type="text" class="form-control" book.details><input type="text" class="form-control" v-model="book.details"> <!-- Correct -->

UPDATE

Added feature to limit number of images allowed to be selected/uploaded, and added preview for selected image. Plus the "send images as array" fix.


If you're using HTML5, try with a FormData object ; it will encode your file input content :

var myForm = document.getElementById('addForm');formData = new FormData(myForm);data: formData