web-dev-qa-db-fra.com

Comment puis-je ajouter plusieurs images avec d'autres champs de saisie en vue js html?

Mon code html est

J'ai également besoin d'ajouter sez qui est au format tableau et j'ai également besoin d'ajouter plusieurs images, je dois ajouter une image et lorsque je clique dessus, je dois ajouter des images selon les besoins du client

<form method="POST" enctype="multipart/form-data" v-on:submit.prevent="handleSubmit($event);">
  <div class="row">
    <div class="col-md-4">
      <div class="form-group label-floating">
        <label class="control-label">Name</label>
        <input type="text" class="form-control" v-model="name">
      </div>
    </div>
    <div class="col-md-4">
      <div class="form-group label-floating">
        <label class="control-label">Alias</label>
        <input type="text" class="form-control" v-model="alias">
      </div>
    </div>
    <div class="col-md-4">
      <div class="form-group label-floating">
        <label class="control-label">Sex</label>
        <select class="form-control" v-model="sex" id="level">
        <option value="Male">Male</option>
        <option value="female">Female</option>
        </select>
      </div>
    </div>
  </div>
  <div class="row" v-for="(book, index) in sez" :key="index">


    <div class="col-md-4">
      <div class="form-group label-floating">
        <label class="control-label">Date </label>
        <input type="date" class="form-control" v-model="book.date">
      </div>
    </div>
    <div class="col-md-8">
      <div class="form-group label-floating">
        <label class="control-label"> Details</label>
        <input type="text" class="form-control" book.details>
      </div>
    </div>

  </div>
  <a @click="addNewRow">Add</a>

  <div class="card-content">
    <div class="row">
      <div class="col-md-4">
        <div class="button success expand radius">
          <span id="save_image_titlebar_logo_live">Signature</span>
          <label class="custom-file-upload"><input type="file" name="photo" accept="image/*"  />
        </label>
        </div>
      </div>
      <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>
    </div>
  </div>
</form>

Mon vue code js est

addForm = new Vue({
  el: "#addForm",
  data: {
    name: '',
    alias: '',
    sex: '',
    sez: [{
      date: null,
      details: null,

    }, ],
    photo: '',
    sign: '',
  },
  methods: {
    addNewRow: function() {
      this.seziure.Push({
        date: null,
        details: null,
      });
    },

    handleSubmit: function(e) {
      var vm = this;
      data = {};
      data['sez'] = this.sez;
      data['name'] = this.name;
      data['alias'] = this.alias;
      data['sex'] = this.sex;
      //how to add images
      $.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")
          }
        }
      });
      return false;
    },
  },
});

Ceci est mon code. Je n'ai aucune idée de la façon d'ajouter des images dans ce cas.

Quelqu'un peut-il m'aider à transmettre ces données?.

Comment transmettre ces données avec des images au backend?

Je ne veux pas utiliser l'encodage base64. Je dois juste passer cette image dans cette demande de publication ajax avec d'autres données

24
Wanderer

Je ne sais pas où aimeriez-vous que les images supplémentaires apparaissent, mais je les ai ajoutées après cette colonne:

<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>

Et voici la colonne que j'ai ajoutée - "ajouter des images": (Vous pouvez essayer cette fonctionnalité ici , avec les mises à jour)

<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)">&times;</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>

Et le code complet Vue JS (avec 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;
    },
  },
});

Notes supplémentaires

Je sais que vous utilisez Node.js dans le back-end; cependant, je dois mentionner qu'en PHP, la variable $_FILES contiendrait toutes les images (tant que les champs name sont correctement définis); et je suppose que Node.js a une variable ou un moyen similaire d'obtenir les fichiers.

Et dans le input suivant, vous avez peut-être oublié d'encapsuler book.details Dans v-model:

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

[~ # ~] mise à jour [~ # ~]

Ajout d'une fonctionnalité pour limiter le nombre d'images pouvant être sélectionnées/téléchargées et ajout d'un aperçu pour l'image sélectionnée. De plus, le correctif "envoyer des images en tant que array".

9
Sally CJ

En utilisant axios :

Modèle

...
<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);
        ...
      });
  }
}
10
Marco Pantaleoni

Si vous utilisez HTML5, essayez avec un objet FormData ; il encodera le contenu d'entrée de votre fichier:

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

Utilisez le modèle ci-dessous pour afficher/télécharger l'image:

 <div v-if="!image">
    <h2>Select an image</h2>
    <input type="file" @change="onImageUpload">
  </div>
  <div v-else>
    <img :src="image" />
    <button @click="removeImage">Remove image</button>
  </div>

Code Js:

data: {
    image: '',
    imageBuff: ''
},
methods: {
    onImageUpload(e) {
        var files = e.target.files || e.dataTransfer.files;
        if (!files.length)
            return;
        this.createImage(files[0]);
    },
    createImage(file) {
        var image = new Image();
        var reader = new FileReader();
        this.imageBuff = file;

        reader.onload = (e) => {
            this.image = e.target.result;
        };
        reader.readAsDataURL(file);
    },
    removeImage: function(e) {
        this.image = '';
    },
    handleSubmit(e) {
        const formData = new FormData();

        formData.append('name', this.name);
        formData.append('alias', this.alias);
        formData.append('sex', this.sex);
        formData.append('image', this.imageBuff);
        ...

        // Ajax or Axios can be used
        $.ajax({
            url: 'http://localhost:4000/save/',
            data: formData,
            processData: false, // prevent jQuery from automatically transforming the data into a query string.
            contentType: false,
            type: 'POST',
            success: function(data) {
                console.log(data);
                ...
            }
        });

    }
}
2
Karthik S