Tengo un problema al recuperar solo los ID de la fila seleccionada a través de una casilla de verificación en mi tabla donde los elementos se crean dinámicamente.
En el código de abajo he puesto sólo el de interés.
Concretamente me sale el siguiente error:
No se pueden leer las propiedades de null (leyendo '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()" />¿Puedes ayudarme amablemente?
Simplemente puede almacenar la identificación en un atributo de la casilla de verificación:
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"));lo que hará que su código se vea así:
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()" />Tienes muchos pequeños errores en tu código. He reescrito tu código un poco. para que pueda leer las filas en las que hizo clic. luego puede extraer los datos del elemento tr usted mismo.
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()" />Le sugiero que reelabore un poco su solución: no use el estado seleccionado directamente desde el DOM (HTML). En su lugar, actualice el conjunto de datos en función de un controlador de eventos que reaccione a algún evento de usuario.
El siguiente fragmento hace esto:
ItemsItems .Además, actualicé tu ejemplo porque hubo algunos errores.
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" />