Reputation: 1448
I gave this question the title 'jQuery removing DOM elements not working as expected'. But I'm not sure if the remove-function is the real problem. To be honest I have absolutely no clue as to where to look for a solution.
I want to upload a selection of images that is present in the DOM. As soon as an image is uploaded, I want to remove the parent of that image from the DOM, so that the parent and the picture along with it are no longer visible. The images and their parent were added to the DOM dynamically.
When I click a button this JavaScript is called:
$('#StartUpload').on('click', function () {
if (inputIsComplete()) {
const imgs = document.querySelectorAll('.pic')
for (let i = 0; i < imgs.length; i++) {
const img = imgs[i].getAttribute('src')
uploadImage(imgs[i], img, i + 1)
}
}
})
This the uploadImage
function:
function uploadImage (img, file, order) {
const d = new Date()
const data = {
file: file,
traject: $('select').eq(2).val(),
filename: d.getTime().toString(),
order: order,
}
$.ajax({
method: 'POST',
url: 'save-pictures.php',
data: data,
success: function () {
console.log(`${data.order} - ${data.filename} uploaded succesfully.`)
$('.img-canvas').eq(data.order - 1).remove()
},
error: function (err) {
console.log(err)
},
})
}
The problem is in the success-method of the AJAX-call. All the images are logged to the console. All the images are effectively uploaded to the server and for all the images a record is created in the database. But NOT all the images are removed from the DOM. Approximately half them are and half of them are not.
Any ideas are hugely appreciated.
Upvotes: 1
Views: 46
Reputation: 42736
You are removing elements which is going to affect the order of the other elements. When the next call to eq()
happens it is going to be targeting the wrong element.
For instance
<input id="0"> <!-- index 0 -->
<input id="1"> <!-- index 1 -->
<input id="2"> <!-- index 2 -->
<input id="3"> <!-- index 3 -->
Now if the element at index 1 was removed the order changes for the last two elements. Elements 2 and 3 are no longer going to be located by using indexes 2 and 3 but rather by 1 and 2 respectively:
<input id="0"> <!-- index 0 -->
<input id="2"> <!-- index 1 -->
<input id="3"> <!-- index 2 -->
Your code does not account for that change between calls.
You could simply determine the element beforehand and pass it to the function that way it has a reference to that element before any removals happen:
for (let i = 0; i < imgs.length; i++) {
const img = imgs[i].getAttribute('src')
let imgCanvas = $('.img-canvas').eq(i);
uploadImage(imgs[i], img, i + 1, imgCanvas)
}
/*...*/
function uploadImage (img, file, order, imgCanvas) {
/*...*/
success:function(){
imgCanvas.remove();
}
You could also target elements directly by giving them a unique id when they are created:
<input id="pic0">
<input id="pic1">
<input id="pic2">
<input id="pic3">
And then target by their id:
success:function(){
$("#pic"+(order-1)).remove();
}
Upvotes: 2