You can use class
selector instead of id's
to have a more dynamic approach of what you are trying to achieve. Also with class
you will be writing less code
and getting the same results.
You can still use the id's increment
system to make sure the id's are unique in the DOM
.
Add class
to your input
image and input
file and and watch a change
on those classes. You can use prev()
method you select the previous input of which the change was made on using $(this)
//Load preview image on each answer
$(document).on('click', '.add_image', function(e) {
e.preventDefault()
//add file to input / trigger click
$(this).next('input').click();
})
//Watch the change on select file
$(document).on('change', '.select_file', function(e) {
e.preventDefault()
//get the sibling img src of the change file
var prevInput = $(this).prev('input')
//Call read file preview
previewFile(this, prevInput);
});
Pass your input
and prev
input image where the change happened to your previewImage
function so that the file
can be previewed
in the image location using file Reader
API.
//Preview img
function previewFile(input , previewSrc) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
//load file into actual preview img
$(previewSrc).attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]); // convert to base64 string
}
}
I have added the functionality of adding more answers
as well and you can upload image and preview images on those new answers as well using event Delegation
as the elements
are being append dynamically.
Complete Working Demo:
//row with incremented ids
var counter = 2
//Add more
$('#add_more').click(function() {
//add new answer
var newRow = `<div class="another-div">
<div class="image-answer">
<input type="image" class='add_image' name="answers_images[]" id="test-` + counter + `" src="https://img.icons8.com/dotty/80/000000/upload.png">
<input type="file" class='select_file' name="answers_images[]" id="file-` + counter + `" style="display: none;">
</div>
<label class="text-answer">
<input type="text" name="answers[]" id="answer-` + counter + `" placeholder="Type here your answer">
</label>
<button class="remove_answer"><i class="fas fa-window-close"></i></button>
</div>`
//append new answers
$('.row').append(newRow)
counter++ //increare counter
})
//remove answer
$(document).on('click', '.remove_answer', function() {
//remove the answer div
$(this).parent().remove()
counter-- //decrease counter
})
//Load preview image on each answer
$(document).on('click', '.add_image', function(e) {
e.preventDefault()
//add file to input / trigger click
$(this).next('input').click();
})
//Watch the change on select file
$(document).on('change', '.select_file', function(e) {
e.preventDefault()
//get the sibling img src of the change file
var prevInput = $(this).prev('input')
//Call read file preview
previewFile(this, prevInput);
});
//Preview img
function previewFile(input, previewSrc) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
//load file into actual preview img
$(previewSrc).attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]); // convert to base64 string
}
}
.add_image {
width: 80px;
height: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
<div class="row">
<div class="another-div">
<div class="image-answer">
<input type="image" class='add_image' name="answers_images[]" id="test-1" src="https://img.icons8.com/dotty/80/000000/upload.png">
<input type="file" class="select_file" name="answers_images[]" id="file-1" style="display: none;">
</div>
<div id="preview_img"></div>
<label class="text-answer">
<input type="text" name="answers[]" id="answer-1" placeholder="Type here your answer">
</label>
</div>
</div>
<br>
<button id="add_more">
Add New Answer
</button>