I'm trying to append items from a 2D array into a table, but everything is appearing in the one column on the left. How can I separate tableDataArr[1] to start loading into the next column across?
Javascript
let names = []; //populated dynamically
let language = []; //populated dynamically
let tableDataArr = [names, language];
function renderData() {
for (let i = 0; i < tableDataArr.length; i++) {
tableDataArr[i].forEach(j => {
let newRow = document.createElement("tr");
newRow.className = "row";
newRow.innerHTML = `<td class='cell'>${j}</td>`;
leftTable.appendChild(newRow);
});
}
}
HTML
<div class='left-tbl-wrap'>
<table class='table' id='left-table'>
<tr class='row'>
<th class='th'>Name</th>
<th class='th'>Language</th>
<th class='th'>Latest tag</th>
<th class='th'><span class='delete'></span></th>
</tr>
</table>
</div>
For each iteration add name and language to the same row, then insert that row into table.
I added some elements in names and languages array to demostrate
let names = ["name1", "name2", "name3"]; //populated dynamically
let language = ["language1", "language2", "language3"]; //populated dynamically
let tableDataArr = [names, language];
const leftTable = document.querySelector("#left-table");
function renderData() {
tableDataArr[0].forEach((j, i) => {
let newRow = document.createElement("tr");
newRow.className = "row";
newRow.innerHTML = `<td class='cell'>${j}</td><td class='cell'>${tableDataArr[1][i]}</td>`;
leftTable.appendChild(newRow);
});
}
renderData();
<div class='left-tbl-wrap'>
<table class='table' id='left-table'>
<tr class='row'>
<th class='th'>Name</th>
<th class='th'>Language</th>
<th class='th'>Latest tag</th>
<th class='th'><span class='delete'></span></th>
</tr>
</table>
</div>
It should be like that
function renderData() {
for (let i = 0; i < tableDataArr.length; i++) {
let newRow = document.createElement("tr");
tableDataArr[i].forEach(j=> {
newRow.className = "row";
newRow.innerHTML = `<td class='cell'>${j}</td>`;
leftTable.appendChild(newRow);
});
}
}
Because you may do not need to iterate table row in the second loop. If you do like that it will be add each row with only one table data.
Related
I am fetching data from a server, I would like to iterate through the values and display them into the first column of the table. Any help that can steer me in the right direction would be appreciated.
Javascript
fetch(_____,{
}).then(data => {
var mstone = data.MilName;
var table = document.getElementById("milestone-table");
var row = table.insertRow(table.rows.length);
// var cell1 = row.insertCell(0);
//var cell2 = row.insertCell(1);
//cell1.setAttribute("style", "text-align:center");
//cell2.setAttribute("style", "text-align:center");
//Iterating through data values and trying to display onto table
for(var i = 0; i < mstone.length; i++){
var cell = row.insertCell(0);
cell.setAttribute("style", "text-align:center");
cell.innerHTML = mstone[i];
}
}).catch(function(err){
console.log("Fetch Problem: " + err);
});
You can set up the table in HTML without any of rows added, loop through the response data and add a row and cell for each item.
const data = ['foo', 'bar', 'baz'] // Dummy response data
const tbody = document.querySelector('tbody');
data.forEach(item => {
const tr = tbody.insertRow();
tr.insertCell().innerText = item
})
<table>
<thead>
<tr>
<th>Column Heading</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Try some thing like below. Have nested loops (1 for rows and 1 for columns)
fetch("https://swapi.dev/api/planets/")
.then((res) => res.json())
.then((resp) => {
const results = resp.results;
var table = document.getElementById("table");
for (let j = 0; j < 4; j++) {
var row = table.insertRow(j);
for (var i = 0; i < 4; i++) {
var cell = row.insertCell(0);
cell.setAttribute("style", "text-align:center; border: 1px solid blue;");
cell.innerHTML = Object.values(results[j])[i];
}
}
});
<table id="table" style="border: 1px solid grey"></table>
I would like to create a table with row count. Currently with the code I have now the row count is not update after delete in the middle row. I found this and try to apply on my code but it doesn't work for updating row count.
Here is the snippet that able to add and delete.
function add(addrow){
var id=document.getElementById('addrow').getElementsByTagName('tbody')[0];
var count=id.rows.length;
var newrow=id.insertRow();
newrow.innerHTML='<td>'+count+'</td><input type="text" name="textbox"><td></td><td><div onclick="del(this)">Delete</div></td>';
}
function del(btn) {
var deleterow = btn.parentNode.parentNode;
deleterow.parentNode.removeChild(deleterow);
}
<button type="button" onclick="add('addrow')">Add</button>
<table id="addrow">
<thead>
<tr>
<th>No</th>
<th>Text</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
You can get the last row's id as max_id, then assign new row's value to max_id + 1.
Pseudo-code:
let last_row = table.rows[table.rows.length] - 1;
let max_id = last_row.id;
// create new_row
new_row.id = max_id + 1;
You will need to loop over all rows after the removed row and decrement their counts by one.
var id=document.getElementById('addrow').getElementsByTagName('tbody')[0];
function add(addrow){
var count=id.rows.length;
var newrow=id.insertRow();
newrow.innerHTML='<td>'+count+'</td><input type="text" name="textbox"><td></td><td><div onclick="del(this)">Delete</div></td>';
}
function del(btn) {
var deleterow = btn.parentNode.parentNode;
var num = +deleterow.querySelector("td").textContent;
deleterow.parentNode.removeChild(deleterow);
for(let i = num; i < id.rows.length; i++){
id.rows[i].querySelector("td").textContent--;
}
}
<button type="button" onclick="add('addrow')">Add</button>
<table id="addrow">
<thead>
<tr>
<th>No</th>
<th>Text</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
try this
function add(addrow){
var id=document.getElementById('addrow').getElementsByTagName('tbody')[0];
var count=id.rows.length+1;
var newrow=id.insertRow();
newrow.innerHTML='<td>'+count+'</td><input type="text" name="textbox"><td></td><td><div onclick="del(this)">Delete</div></td>';
}
function del(btn) {
var deleterow = btn.parentNode.parentNode;
deleterow.parentNode.removeChild(deleterow);
let i = 1;
Array.from(document.querySelector('tbody').children).map(child =>{
child.children[0].innerHTML = i;
i++;
})
}
<button type="button" onclick="add('addrow')">Add</button>
<table id="addrow">
<thead>
<tr>
<th>No</th>
<th>Text</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
You need to update the No column of the table when any row is deleted.
Heres' one way of doing it:
const btn = document.querySelector('button');
const tbody = document.getElementById('addrow').querySelector('tbody');
btn.addEventListener('click', () => {
// add new row in table body
const newRow = tbody.insertRow();
// get the length of rows after adding the new row
const count = tbody.rows.length;
// add columns in the newly added row
const newCell = newRow.insertCell(0);
newCell.textContent = count;
const newCell2 = newRow.insertCell(1);
newCell2.innerHTML = '<input type="text" name="textbox">';
const newCell3 = newRow.insertCell(2);
newCell3.innerHTML = `<button id="del" data-row="${count}">Delete</button>`;
});
// listen for click event on delete button of all the rows
tbody.addEventListener('click', (e) => {
if (e.target.matches('#del')) {
// delete the row using the value of 'data-row' attribute of the delete button
tbody.parentElement.deleteRow(e.target.dataset.row);
updateTableRowCount();
}
});
// update row count when any row is deleted
function updateTableRowCount() {
[...tbody.children].forEach((row, idx) => {
// update 'No' column value
row.firstElementChild.textContent = idx + 1;
// update `data-row` attribute of the delete button
row.lastElementChild.firstElementChild.setAttribute('data-row', idx + 1);
});
}
<button>Add</button>
<table id="addrow">
<thead>
<tr>
<th>No</th>
<th>Text</th>
<th>Action</th>
</tr>
</thead>
<tbody></tbody>
</table>
I have the following code to create a table of employees which allows me to filter through them based on a query term:
I want to add html buttons that would be included along with the employee in the table so I can add a
<button onclick="myFunction()">Click me</button>
which would allow me to then create and add employees to a new list of selected employees Image of elements I want to add I am not sure if this is possible to do so I'm asking for some help here. Alternatively, if it is not possible to add this HTML element into the table how would I go about modifying the code so if I clicked on a row of the filtered table it would allow me to select that row and then add it to the new list of selected employees.
Thanks so much!
<style>
th{
cursor: pointer;
color:#fff;
}
</style>
<div class="row">
<div class ="col">
<div class="card card-body">
<input id="search-input" class="form-control" type="text">
</div>
</div>
</div>
<table class="table table-striped">
<tr class="bg-info">
<th class="bg-info" data-colname="name" data-order="desc">Name ▲</th>
<th data-colname="age" data-order="desc">Age ▲</th>
<th data-colname="birthdate" data-order="desc">Birthday ▲</th>
</tr>
<tbody id="myTable">
</tbody>
</table>
<script>
var myArray = [
{'name':'Michael', 'age':'30', 'birthdate':'11/10/1989'},
{'name':'Mila', 'age':'32', 'birthdate':'10/1/1989'},
{'name':'Paul', 'age':'29', 'birthdate':'10/14/1990'},
{'name':'Dennis', 'age':'25', 'birthdate':'11/29/1993'},
{'name':'Tim', 'age':'27', 'birthdate':'3/12/1991'},
{'name':'Erik', 'age':'24', 'birthdate':'10/31/1995'},
]
$('#search-input').on('keyup', function(){
var value= $(this).val()
console.log('value:', value)
var data = searchTable(value, myArray)
buildTable(data)
})
buildTable(myArray)
function searchTable(value, data){
var filteredData = []
for (var i = 0; i < data.length; i++){
value = value.toLowerCase()
var name = data[i].name.toLowerCase()
var age = data[i].age.toLowerCase()
var birthdate = data[i].age.toLowerCase()
if(name.includes(value)){
filteredData.push(data[i])
}
else if(age.includes(value)){
filteredData.push(data[i])
}
else if(birthdate.includes(value)){
filteredData.push(data[i])
}
}
return filteredData
}
$('th').on('click', function(){
var column = $(this).data('colname')
var order = $(this).data('order')
var text = $(this).html()
text = text.substring(0, text.length - 1);
if (order == 'desc'){
myArray = myArray.sort((a, b) => a[column] > b[column] ? 1 : -1)
$(this).data("order","asc");
text += '▼'
}else{
myArray = myArray.sort((a, b) => a[column] < b[column] ? 1 : -1)
$(this).data("order","desc");
text += '▲'
}
$(this).html(text)
buildTable(myArray)
})
function buildTable(data){
var table = document.getElementById('myTable')
table.innerHTML = ''
for (var i = 0; i < data.length; i++){
var colname = `name-${i}`
var colage = `age-${i}`
var colbirth = `birth-${i}`
var row = `<tr>
<td>${data[i].name}</td>
<td>${data[i].age}</td>
<td>${data[i].birthdate}</td>
</tr>`
table.innerHTML += row
}
}
</script>
I have an html table that I want to read from and create a new table underneath it from reading the first table. The first table looks like this:
ID | Value
100 | 3
200 | 2
400 | 7
100 | 4
and should output this
ID | Total
100 | 7
200 | 2
400 | 7
I'm having trouble creating the new rows after the first row and adding them based on ID, heres what I have so far
var id = document.getElementByID("total");
var td = document.createElement('td');
var eleName = document.getElementsByName('initValue');
var total = 0;
for (var i = 1; i < eleName.length; i++) {
total += parseInt(eleName[i].value);
}
td.textContent = total;
id.appendChild(td);
Right now its just adding all the values
The ID can only increase by 100 and can have more than just 100-400 and more entries. The inital table is made with php
original table html
<table>
<tr><th>ID</th><th>Value</th></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">3</td></tr>
<tr><td name="itin" id="itin">200</td><td id="initValue" name="initValue">2</td></tr>
<tr><td name="itin" id="itin">400</td><td id="initValue"name="initValue">7</td></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">4</td></tr>
</table>
As a few people have said in the comments an element's ID, <el id="something">, must be unique and there cannot be any duplicates of it on the page. If you want to "group" similar elements use a class.
For solving your problem, since the value of your ID is is a direct sibling we only need one selector to get the ID and Value:
const itin = document.querySelectorAll('[name="itin"]');
With this we can loop over every ID element, name="itin", and get the value with el.nextElementSibling.textContent. We're going to be keeping track of our IDs and Values in an object since javascript doesn't have key/value pair arrays: let values = {}.
We use .nextElementSibling to ignore white spaces and only get the next element.
We check if values already has a record of our ID with hasOwnProperty, if it does, we add the values together, if not we create a property in values with our ID and give it a value:
if (values.hasOwnProperty(inner)) {
values[inner] = values[inner] += parseInt(next);
} else {
values[inner] = parseInt(next);
}
Next we create a second loop to iterate over all properties in values and build our new table with that and the rest is pretty straight forward.
The two loops could likely be combined into one with a bit more logic to search for matching IDs.
const itin = document.querySelectorAll('[name="itin"]');
let values = {};
itin.forEach(item => {
const inner = item.textContent;
let next = null;
/* For direct sibling use this */
//const next = item.nextElementSibling.textContent;
/* For an unknown sibling use this */
for ( let a = 0; a < item.parentElement.children.length; a++ ) {
const n = item.parentElement.children[a];
if ( n.getAttribute('name') === 'initValue') {
next = n;
}
}
next = next.textContent;
/****/
if (values.hasOwnProperty(inner)) {
values[inner] = values[inner] += parseInt(next);
} else {
values[inner] = parseInt(next);
}
});
const table_two = document.querySelector('.table-two tbody');
for (let prop in values) {
const val = values[prop];
let tr = document.createElement('tr');
let td1 = document.createElement('td');
let td2 = document.createElement('td');
td1.innerHTML = prop;
td2.innerHTML = val;
tr.appendChild(td1);
tr.appendChild(td2);
table_two.appendChild(tr);
}
<table>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
<tr>
<td name="itin">100</td>
<td name="initValue">3</td>
</tr>
<tr>
<td name="itin">200</td>
<td name="initValue">2</td>
</tr>
<tr>
<td name="itin">400</td>
<td name="initValue">7</td>
</tr>
<tr>
<td name="itin">100</td>
<td name="initValue">4</td>
</tr>
</table>
<table class="table-two">
<thead>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
</thead>
<tbody></tbody>
</table>
An entirely javascript solution based on what you have provided is available on this jsfiddle
var tds = document.getElementsByName("itin");
var tdDict = {};
var keys = [];
for(var i=0;i<tds.length;i++){
var tdId = tds[i];
var tdVal = tds[i].nextSibling;
if(tdId.textContent in tdDict){
var curTotal = tdDict[tdId.textContent];
var newTotal = curTotal + parseInt(tdVal.textContent);
tdDict[tdId.textContent] = newTotal;
}
else{
tdDict[tdId.textContent] = parseInt(tdVal.textContent);
keys.push(tdId.textContent);
}
}
var totalDiv = document.getElementById("totals");
var totalTable = document.createElement("table");
totalDiv.append(totalTable);
var hrow = document.createElement("tr");
var idHeader = document.createElement("th");
idHeader.textContent = "ID";
var totalHeader = document.createElement("th");
totalHeader.textContent = "Total";
totalTable.append(hrow);
hrow.append(idHeader);
hrow.append(totalHeader);
for(var i=0;i<keys.length; i++){
var newRow = document.createElement("tr");
var idVal = keys[i];
var valVal = tdDict[idVal];
var idValTd = document.createElement("td");
idValTd.textContent = idVal;
var valValTd = document.createElement("td");
valValTd.textContent = valVal;
newRow.appendChild(idValTd);
newRow.appendChild(valValTd);
totalTable.appendChild(newRow);
}
<table>
<tr><th>ID</th><th>Value</th></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">3</td></tr>
<tr><td name="itin" id="itin">200</td><td id="initValue" name="initValue">2</td></tr>
<tr><td name="itin" id="itin">400</td><td id="initValue"name="initValue">7</td></tr>
<tr><td name="itin" id="itin">100</td><td id="initValue" name="initValue">4</td></tr>
</table>
<div id="totals">
</div>
I have a two webpages. eventsCreated and createAnEvent. In createAnEvent, a form is used to allow users' inputs. The inputs are then stored to local storage with the following function:
document.addEventListener("DOMContentLoaded",docIsReady);
var createEvent;
function docIsReady(){
createEvent=localStorage.getItem("createEvent");
if (createEvent==null){
CreateEvent=[];
}
else {
createEvent=JSON.parse(createEvent);
}
}
function saveToStorage() {
var one;
var nameofevent=document.getElementById("name").value;
var pList=document.getElementsByName("pos");
var positions=[];
for (i=0; i<pList.length; i++){
positions.push(pList[i].value);
console.log(pList[i].value);
}
localStorage["X"]=JSON.stringify(positions);
var r=localStorage["X"];
r=JSON.parse(r);
//for (i=0; i<positions.length; i++){
//console.log(positions[i].value);
//}
var venue= document.getElementById("venue").value;
var date=document.getElementById("date").value;
var starttime=document.getElementById("timeStart").value;
var endtime=document.getElementById("timeEnd").value;
var contact=document.getElementById("contact").value;
var email=document.getElementById("email").value;
var desc=document.getElementById("desc").value;
one={"name":nameofevent,"pos":r,"venue":venue,"date":date,"timeStart":starttime,"timeEnd":endtime,"contact":contact,"email":email,"desc":desc};
createEvent.push(one);
localStorage.setItem("createEvent",JSON.stringify(createEvent));
//alert(JSON.stringifys(one));
//alert(one.pos[0]); //to get one position
return false;
}
I made createEvent an array so as to store the multiple inputs because there cannot be only one event created. In the eventsCreated page, I need to display the user inputs in a table that looks something like this :
<table border="1px" id="list">
<tr>
<th>Name of event</th>
<th>Positions</th>
<th>Venue</th>
<th>Date</th>
<th>Start Time</th>
<th>End Time</th>
<th>Points Awarded</th>
</tr>
</table>
I am not sure how to use javascript to get the event details that the user has entered in the createAnEvent page and display it in the table.
This is the javascript:
function addRow() {
var table = document.getElementById("list");
var one = JSON.parse(localStorage["createEvent"]);
for (var i=0; i<one.length; i++) {
var row = table.insertRow(i);
for (var j=0; j<=6; j++) {
var cell = row.insertCell(j);
}
cell[0].innerHTML = "one[0]";
cell[1].innerHTML = "one[1]";
cell[2].innerHTML = "one[1]";
cell[3].innerHTML = "one[3]";
cell[4].innerHTML = "one[4]";
cell[5].innerHTML = "one[5]";
cell[6].innerHTML = "one[6]";
}
}
I would use jquery to add elements to your page.
But you can use the dom if you like.
function addRow() {
var table = document.getElementById("list");
var one = JSON.parse(localStorage["createEvent"]);
for (var i = 0; i < one.length; i++) {
var this_tr = document.createElement("tr");
for (var j=0; j < one[i].length; j++) {
var this_td = document.createElement("td");
var text = document.createTextNode(one[i][j]);
this_td.appendChild(text);
this_tr.appendChild(this_td);
}
table.appendChild(this_tr);
}
This should work for you or close to it. You table is also wrong please correct it to this.
<table border="1px">
<thead>
<tr>
<th>Name of event</th>
<th>Positions</th>
<th>Venue</th>
<th>Date</th>
<th>Start Time</th>
<th>End Time</th>
<th>Points Awarded</th>
</tr>
</thead>
<tbody id="list">
</tbody>
</table>
See for examples:
http://www.w3schools.com/jsref/met_node_appendchild.asp