I'm having a problem in retrieving only the ids of the selected row via a checkbox in my table where the elements are dynamically created.
In the code below I have put only the one of interest.
Specifically I get the following error:
Cannot read properties of null (reading 'textContent')
.
.
.
let child = document.createElement("tr");
child.innerHTML = `
<td>${item.id}</td>
<td><img src=articoli_img/${item.image} width="150" heigth="150"></td>
td>${item.date}</td>
<td>${'<input type="checkbox" id="myCheck">'}</td>`;
table.appendChild(child);
})
}
};
function retrieveID() {
var cbs = document.querySelectorAll('#my-table input[type="checkbox"]:checked');
console.log(cbs.length);
const ids = Array.from(cbs).map(cb => cb.closest('td').nextElementSibling.textContent);
console.log(ids);
}
<table id="my-table" width="90%">
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</table>
<br><br>
<input type="button" value="GetID" onclick="retrieveID()" />
Can you kindly help me?
You can simply store the id in a attribute of the checkbox:
child.innerHTML = `... <td>${`<input type="checkbox" id="myCheck" data-item-id="${item.id}">`}</td>`;
// ...
const ids = Array.from(cbs).map((cb) => cb.getAttribute("data-item-id"));
which will make your code look like this:
let table = document.getElementById("my-table");
const Items = [
{
id: 1,
image: "test1.jpg",
date: "2020-01-01",
},
{
id: 2,
image: "test2.jpg",
date: "2020-01-02",
},
{
id: 3,
image: "test3.jpg",
date: "2020-01-03",
},
];
Items.forEach(function (item) {
let child = document.createElement("tr");
child.innerHTML = `
<td>${item.id}</td>
<td><img src="articoli_img/${item.image}" width="150" heigth="150"></td>
td>${item.date}</td>
<td>${`<input type="checkbox" id="myCheck" data-item-id="${item.id}">`}</td>`;
table.appendChild(child);
});
function retrieveID() {
var cbs = document.querySelectorAll(
'#my-table input[type="checkbox"]:checked'
);
console.log(cbs.length);
const ids = Array.from(cbs).map((cb) => cb.getAttribute("data-item-id"));
console.log(ids);
}
<table id="my-table" width="90%">
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</table>
<br><br>
<input type="button" value="GetID" onclick="retrieveID()" />
You have a lot of small errors in your code. i have rewritten your code a little bit. so that you are able to read out the clicked rows. you can then pull the data from the tr element yourself.
let table = document.getElementById("my-table");
let allart = [];
allart['Items'] = [{id: 1, image: 'xx', date: 2022}]
console.log(allart['Items'][0].id)
allart.Items.forEach(function(item) {
let child = document.createElement("tr");
child.setAttribute("id", "data-" +item.id);
child.innerHTML = `
<td>${item.id}</td>
<td><img src=articoli_img/${item.image} width="150" heigth="150"></td>
<td>${item.date}</td>
<td><input type="checkbox" data-ref="${item.id}" id="myCheck"></td>`;
table.appendChild(child);
})
//xmlhttp.open("GET", url, true);
//xmlhttp.send();
function retrieveID() {
var cbs = document.querySelectorAll('#my-table input[type="checkbox"]:checked');
console.log(cbs.length);
console.log(cbs[0])
let col = [];
cbs.forEach(c => {
let id = c.getAttribute('data-ref');
let data = document.querySelector('#data-' + id)
console.log(data)
// do something
})
}
<table id="my-table" width="90%">
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</table>
<br><br>
<input type="button" value="GetID" onclick="retrieveID()" />
I would suggest that you rework your solution somewhat: do not use the selected state directly from the DOM (HTML). Instead, update the dataset based on an event handler that reacts to some user event.
The snippet below does this:
ItemsItems array.Also, I updated your example as there were some errors.
const table = document.querySelector("#my-table tbody");
const btnGetId = document.getElementById('get-id')
/*.
.
.*/
const allart = {
Items: [{
id: 'id1',
image: 'fakeImage1',
date: Date.now(),
checked: false,
},
{
id: 'id2',
image: 'fakeImage2',
date: Date.now(),
checked: false,
},
],
}
allart.Items.forEach(function(item) {
let child = document.createElement("tr");
child.innerHTML = `
<td>${item.id}</td>
<td><img src="articoli_img/${item.image}" width="150" heigth="150"></td>
<td>${item.date}</td>
<td><input type="checkbox" data-itemid="${item.id}"/></td>`;
table.appendChild(child);
})
// }
// };
// reacting to selection
const updateChecked = (id, items) => {
return items.map(item => {
if (id === item.id) {
return {
...item,
checked: !item.checked
}
}
return item
})
}
// adding event handlers to the checkboxes
const cbs = document.querySelectorAll('tr input[type="checkbox"]')
cbs.forEach(cb => {
cb.addEventListener('change', function(e) {
const id = e.target.getAttribute("data-itemid")
allart.Items = updateChecked(id, allart.Items)
})
})
// xmlhttp.open("GET", url, true);
// xmlhttp.send();
// updating the event handler on GetId click
btnGetId.addEventListener('click', function() {
const selectedItems = retrieveId(allart.Items)
// here you have the items that are selected
// you can use all the data it has
console.log(selectedItems)
})
// returning the items that are selected
function retrieveId(items) {
return items.filter(({ checked }) => checked)
}
<table id="my-table" width="90%">
<thead>
<tr>
<th>Id</th>
<th>Image</th>
<th>Date</th>
<th>Check</th>
</tr>
</thead>
<tbody></tbody>
</table>
<br><br>
<input id="get-id" type="button" value="GetID" />