My html code is
I also need to add sez which is in array format and also i need to add multiple images, need to provide add image and when clicking on it, need to add images as needed by the 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>
My vue js code is
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;
},
},
});
This is my code. I have no idea about how to add images in this case.
Can anyone please help me pass this data.
How to pass this data along with images to the backend?
I don't want to use base64 encoding. I need to just pass this image in this ajax post request along with other data
Using axios:
...
<input type="file" name="photo" accept="image/*" @change="setPhotoFiles($event.target.name, $event.target.files) />
...
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With