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>