I use an array of object to display data on a dynamic table I create with javascript
inside the table, there are 2 button delete and edit
when I press the delete I delete the data from the array but for some reason, the data still remains in the table ? can someone give me a clue why?
workers = [{
name: 'Roni',
phone: '0545931252',
nickname: 'RoniBoy',
mail: 'Roni#gmail.com',
},
{
name: 'Lior',
phone: '0545996452',
nickname: 'LiorBoy',
mail: 'Lior#gmail.com',
},
{
name: 'Arman',
phone: '0545886452',
nickname: 'ArmanBoy',
mail: 'Arman#gmail.com',
}
];
function deleteFromList(id) {
workers.splice(id, 1);
console.log(workers);
}
const toAppend = document.getElementById('appendBox');
let markup = '';
for (let x = 0; x < workers.length; x++) {
markup += `<tr>
<td >` + workers[x].name + `</td>
<td>` + workers[x].nickname + `</td>
<td>` + workers[x].phone + `</td>
<td>` + workers[x].mail + `</td>
<td><button onClick="deleteFromList(this.id)" id="` + x + `" class="btn btn-danger">Remove</button> <button class="btn btn-success">Edit</button></td>
</tr>`
}
toAppend.innerHTML = markup;
<table id="appendBox"></table>
You have rerender html every time you update you array
workers = [
{
name: 'Roni',
phone: '0545931252',
nickname: 'RoniBoy',
mail: 'Roni#gmail.com',
},
{
name: 'Lior',
phone: '0545996452',
nickname: 'LiorBoy',
mail: 'Lior#gmail.com',
},
{
name: 'Arman',
phone: '0545886452',
nickname: 'ArmanBoy',
mail: 'Arman#gmail.com',
}
];
function deleteFromList(id){
workers.splice(id,1);
console.log(workers);
renderMarkup();
}
function renderMarkup() {
const toAppend = document.getElementById('appendBox');
let markup = '';
for(let x = 0; x < workers.length; x++){
markup += `
<tr>
<td >`+workers[x].name+`</td>
<td>`+workers[x].nickname+`</td>
<td>`+workers[x].phone+`</td>
<td>`+workers[x].mail+`</td>
<td><button onClick="deleteFromList(this.id)" id="`+x+`" class="btn btn-danger">Remove</button> <button class="btn btn-success">Edit</button></td>
</tr>`
}
toAppend.innerHTML = markup;
}
renderMarkup();
<table id="appendBox"></table>
If you want to remove stuff from your table then you might want to add some sequential IDs to each row so that you can directly delete one. You could also do something like this just grabbing one in the spot it's in and delete it that way. Are you looking to delete rows or are you just trying to delete a column in a row?
var tblBody = document.getElementById("tblBody"); //referencing a <tbody> tag's id
var row = document.getElementsByTagName("tr"); //get every tr element
tblBody.deleteRow(row[i].rowIndex);
Related
I want to populate HTML form input fields with JSON data I get from my API. I can display the data in a table with the following code, but I cannot make it work with a form. I tried to address the form with something like or instead of and , but it doesn't work. Does anyone know if I can transform this code to work with a form?
const url = "/api/contacts/" + localStorage.getItem("paraID");
fetch(url).then((res) => {
res.json().then((data) => {
console.log(data);
if (data.length > 0) {
var temp = "";
data.forEach((itemData) => {
temp += "<tr>";
temp += "<td>" + itemData.studentID + "</td>";
temp += "<td>" + itemData.nachname + "</td>";
temp += "<td>" + itemData.studium + "</td>";
temp += "<td>" + itemData.semester + "</td>";
temp += "<td>" + itemData.deaktiviert + "</td></tr>";
});
document.getElementById("myTable").innerHTML = temp;
}
});
});
The fetch function works, I can see the correct JSON data in the console. It looks like this:
[{…}]
0: {studentID: 1, vorname: 'Marie', nachname: 'Bauer', strasse: '', plz: '', …}
length: 1
[[Prototype]]: Array(0)
I tried all the different options I found at stackoverflow (e.g. with jQuery), but they also don't work with a form.
you can try this code:
<form id="myForm">
<input name="studentID" />
<input name="nachname" />
<input name="studium" />
<input name="semester" />
<input name="deaktiviert" />
</form>
let exampleData = [{
studentID: 'value',
nachname: 'value',
studium: 'value',
semester: 'value',
deaktiviert: 'value',
}]
const myForm = document.getElementById('myForm');
exampleData.forEach((itemData) => {
myForm['studentID'].value = itemData.studentID;
myForm['nachname'].value = itemData.nachname;
myForm['studium'].value = itemData.studium;
myForm['semester'].value = itemData.semester;
myForm['deaktiviert'].value = itemData.deaktiviert;
});
This is how I got it to work:
deleted let = exampleData
replaced exampleData.forEach((itemData) … with data.forEach((itemData) …
fetch(url).then((res) => {
res.json().then((data) => {
console.log(data);
if (data.length > 0) {
const myForm = document.getElementById("myForm");
data.forEach((itemData) => {
myForm["studentID"].value = itemData.studentID;
myForm["nachname"].value = itemData.nachname;
myForm["studium"].value = itemData.studium;
myForm["semester"].value = itemData.semester;
myForm["deaktiviert"].value = itemData.deaktiviert;
});
}
});
});
I have a JSON result where I want to create an accordion menu, I want one value of similar results as title of those similar rows, please check below to see what I did.
Suppose a I have below JSON object
var items = [
{label: "TY2021H", name: "10-Yr T-Notes", value: "TY2021H"},
{label: "TY2020Z-TY2021H", name: "10-Yr T-Notes Spread", value: "TY2020Z-TY2021H"},
{label: "TY2021H-TY2021M", name: "10-Yr T-Notes Spread", value: "TY2021H-TY2021M"},
{label: "TY2020Z-2*TY2021H+TY2021M", name: "10-Yr T-Notes Butterfly", value: "TY2020Z-2*TY2021H+TY2021M"}]
The related part of my JS code is as follow:
var myUL = $("#accordion");
myUL.empty();
var currentName = "";
for (var i = 0; i <= items.length - 1; i++) {
var label = items[i].label;
if (items[i].name != currentName) {
currentName = items[i].name;
list +=
'<a href="#demo' +
i +
'" class="list-group-item list-group-item-info" data-toggle="collapse" data-parent="#accordion">' +
currentName +
' <span id="opnClsSign" class="glyphicon glyphicon-menu-down"></span></a>';
list += '<div class="collapse in" id="demo' + i + '">';
}
list += '' + label + "";
}
list += "</div>";
myUL.append(list);
Part of my HTML div
<div class="list-group panel" id="accordion"></div>
Result I get now
What I expect
Code indentation can help in a situation like this. Your last two lines should be inside the loop for the code to make sense. In every iteration, you must close the div and add the code to myUL:
var items = [
{label: "TY2021H", name: "10-Yr T-Notes", value: "TY2021H"},
{label: "TY2020Z-TY2021H", name: "10-Yr T-Notes Spread", value: "TY2020Z-TY2021H"},
{label: "TY2021H-TY2021M", name: "10-Yr T-Notes Spread", value: "TY2021H-TY2021M"},
{label: "TY2020Z-2*TY2021H+TY2021M", name: "10-Yr T-Notes Butterfly", value: "TY2020Z-2*TY2021H+TY2021M"}]
var myUL = $("#accordion");
myUL.empty();
var currentName = "";
for (var i = 0; i <= items.length - 1; i++) {
var label = items[i].label;
var list = '';
if (items[i].name != currentName) {
currentName = items[i].name;
list +=
'<a href="#demo' +
i +
'" class="list-group-item list-group-item-info" data-toggle="collapse" data-parent="#accordion">' +
currentName +
' <span id="opnClsSign" class="glyphicon glyphicon-menu-down"></span></a>';
list += '<div class="collapse in" id="demo' + i + '">';
}
list += '' + label + "";
list += "</div>";
myUL.append(list);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="list-group panel" id="accordion"></div>
Also, you needed to define list.
I resolved the issue my self, and I have added the final source code into this pen:
[https://codepen.io/rafihaidari/pen/ExyBGVK]
I have data like this one but find hard to loop both objects and get data into one table where th to be company and td to be their drivers
{…}
driver: Array(18) [ {…}, {…}, {…}, … ]
company: "TEST"
{…}
driver: Array(10) [ {…}, {…} ]
company: "TEST 1"
i tried like this one but is do not work properly
$.each(response.allDrivers, function(key, value){
var thead = '';
thead += '<th>'+value.company+'</th>';
$('#table-allDrivers thead tr').append(thead);
$.each(value.driver, function(id,name){
var tbody = '';
tbody = '<tr> <td>'+name.driver+'<td></tr>';
$('#table-allDrivers tbody').append(tbody);
})
});
result im getting is like this one
<thead>
<tr>
<th>TEST</th>
<th>TEST 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>Driver 1</td>
<td></td>
</tr>
<tr>
<td>Driver 2</td>
<td></td>
</tr>
<tr>
<td>Driver 3</td>
<td></td>
</tr>
<tr>
<td>Driver 4</td>
<td></td>
</tr>
</tbody>
Suppose you have 2 driver (driver1 and driver2) but maybe more. Find the one with more elements and iterate from that (I assumed driver1 has more elements);
var markup = "";
for( let i = 0 ; i < driver1.length; i++)
{
if (i < driver2.length)
{
markup += '<tr><td>'+driver1[i].+'</td><td>'+driver2[i]+'</td><tr>';
}
else
{
markup += '<tr><td>'+driver1[i].+'</td><td></td><tr>';
}
}
$('#table-allDrivers tbody').append(markup);
I think this would show the correct result even if this is not the best way but i tried with as much information i got.
It's a little different from how you have it there, but you can try something like this—run the snippet to see the result:
var arr = [
{
driver: ['item1', 'item2', 'item3'],
company: "Company1"
},
{
driver: ['item1', 'item2'],
company: "Company2"
}
]
var thead = document.querySelector('table thead tr')
var tbody = document.querySelector('table tbody')
arr.forEach(function(item) {
thead.innerHTML += '<th>' + item.company + '</th>';
item.driver.forEach(function(driverItem) {
tbody.innerHTML += '<tr></tr>';
})
tbody.querySelectorAll('tr').forEach(function(tr, i) {
tr.innerHTML += item.driver[i] ? '<td>' + item.driver[i] + '</td>' : '<td></td>' //catering for colspan layout
tr.innerHTML === '<td></td>' ? tr.remove() : '' //removing empty <tr> elements
})
})
<table>
<thead>
<tr></tr>
</thead>
<tbody></tbody>
</table>
The right way to use HTML Tables with multiple values for each cell is to use rowspan or colspan attribute, which in your case each company has multiple drivers. To achieve that:
Javascript:
// Your data
const allDrivers = [
{
drivers: ['driverComapnyA-1', 'driverComapnyA-2', 'driverComapnyA-3'],
company: 'Comapny A',
},
{
drivers: [
'driverComapanyB-1',
'driverComapanyB-2',
'driverComapanyB-3',
'driverComapanyB-4',
],
company: 'Comapny B',
},
];
allDrivers.forEach((item, index) => {
if (index == 0) {
// Make sure to setup tbody markup once
$('#table-allDrivers').append('<tbody></tbody>');
}
const tableBody = $('#table-allDrivers').find('tbody');
tableBody.append(
'<tr data-index="' +
index +
'"><th rowspan="' +
item.drivers.length +
'">' +
item.company +
'</th></tr>'
);
item.drivers.forEach((driver, i) => {
if (i == 0) {
// if its the first item in drivers array then add it as a child in <tr>
tableBody
.find('[data-index="' + index + '"')
.append('<td>' + driver + '</td>');
} else {
// otherwise just append it to <tbody>
tableBody.append('<tr><td>' + driver + '</td></tr>')
}
});
});
Markup:
<table id="table-allDrivers"></table>
And here's a working fiddle: https://jsfiddle.net/khzway7u/
I am having trouble saving the new row. When i click on add person I am able to input the data, however, i am not sure how to save it and add a new row.
I know i have to make a function for the save button to work however i am stuck on how to make it work. I have tried a few times but to no avail.
var isNewLineToggled = false;
var isAscending = {
name : false,
lastName: false,
dob: false
};
$(".main").append("<input placeholder='search by name' class='search'/><br/><br/>")
$(".main").append("<button onclick=addPerson()>add a person</button><br/><br/>")
var table = $(".main").append("<table></table>");
var thead = '<thead><tr></tr></thead>';
table.append(thead);
var header = [
{ title: 'Name', sortBy: 'name'},
{ title: 'Last Name', sortBy: 'lastName'},
{ title: 'Date of birth', sortBy: 'dob'}
].map(
function(header) {
var sortButton = '<button id="' + header.sortBy + '" onclick=sortRows("'+ header.sortBy + '")>/\\</button>';
$('thead').append('<th>' + header.title + ' ' + sortButton + '</th>');
}
)
var tbody = "<tbody></tbody>";
var data = [ {name: 'Peter', lastName: 'Petterson', dob: '13/12/1988'},
{name: 'Anna', lastName: 'Jones', dob: '06/02/1968'},
{name: 'John', lastName: 'Milton', dob: '01/06/2000'},
{name: 'James', lastName: 'White', dob: '30/11/1970'},
{name: 'Luke', lastName: 'Brown', dob: '15/08/1999'}
];
$('.search').change(function(event) {
searchedName = event.target.value;
})
table.append(tbody);
data.map(
function(row, i) {
$('tbody').append(
'<tr><td>' + row.name +
'</td><td>' + row.lastName +
'</td><td>' + row.dob +
'</td><td><button onclick=editRow('+i+')>edit</button><button>delete</button></td></tr>'
)
}
)
var editableRow = "<td><input/></td><td><input/></td><td><input type='date'/></td><td><button onclick=saveRow()>save</button></td>";
var addPerson = function() {
isNewLineToggled = !isNewLineToggled;
if (isNewLineToggled) {
$('tbody').prepend('<tr>' + editableRow + '</tr>')
} else {
$('tbody > tr:first-child').remove();
}
}
var editRow = function(rowNumber) {
var name = $('tbody > tr:nth-child('+(rowNumber + 1)+') > td:first-child').text();
var lastName = $('tbody > tr:nth-child('+(rowNumber + 1)+') > td:nth-child(2)').text();
var dob = $('tbody > tr:nth-child('+(rowNumber + 1)+') > td:nth-child(3)').text();
$('tbody > tr:nth-child('+(rowNumber + 1)+')').html(editableRow2);
$('tbody > tr:nth-child('+(rowNumber + 1)+') > td:first-child > input').val(name);
$('tbody > tr:nth-child('+(rowNumber + 1)+') > td:nth-child(2) > input').val(lastName);
}
You can add row like this, two small changes:
$(".main").append("<button class='add'>add a person</button><br/><br/>")
Remove inline event handler, no need for it. And your function could be:
$('body').on('click','.add', function() { //you will need event delegation, because of dynamically added elements
isNewLineToggled = !isNewLineToggled;
if (isNewLineToggled) {
$('tbody').prepend('<tr>' + editableRow + '</tr>')
} else {
$('tbody > tr:first-child').remove();
}
});
Since your editableRow variable isn't defined, i've used just one cell with text for demo:
https://jsfiddle.net/2c97auey/1/
P.S. Your editableRow should have input(s) values, properly placed in cells. Shouldn't be too hard.
Hw to download arr content into the table cells from left to right and from up to down? What is wrong with my code? How to solve the problem? Thanks in advance.
<button onclick="myFunction()></button>
<table id="myTable" border='1px'>
<tr>
<th>N</th>
<th>Name</th>
<th>Surname</th>
<th>tel.</th>
<th>email</th>
</tr>
</table>
var arr=[[1,2,3,4,'a'],[5,6,7,8,'b'],[9,10,11,12,'c']];
function myFunction() {
createTable();
}
function createTable(){
var i,j;
var table = document.getElementById("myTable");
for( i=0; i<arr.length; i++ ) {
var row = table.insertRow(1);
for( j=0,k=0; j<5, k<arr[i].length;j++, k++ ) {
var cell = row.insertCell(0);
cell.innerHTML = arr[i][k];
}
}
}
Well i am not sure about your data structure but if you get your data in the following form.
[ { N: 1, Name: 2, Surname: 3, Tel: 4, email: 'a' },
{ N: 5, Name: 6, Surname: 7, Tel: 8, email: 'b' },
{ N: 9, Name: 10, Surname: 11, Tel: 12, email: 'c' } ]
You can use the following tableMaker function. It will take the properties as headers (if second argument is provided as true) and values as corresponding cells to generate an HTML text. So here it goes as follows;
var tableMaker = (o,h) => {var keys = o.length && Object.keys(o[0]),
rowMaker = (a,t) => a.reduce((p,c,i,a) => p + (i === a.length-1 ? "<" + t + ">" + c + "</" + t + "></tr>"
: "<" + t + ">" + c + "</" + t + ">"),"<tr>"),
rows = o.reduce((r,c) => r + rowMaker(keys.reduce((v,k) => v.concat(c[k]),[]),"td"),h ? rowMaker(keys,"th") : []);
return rows.length ? "<table>" + rows + "</table>" : "";
},
arr = [[1,2,3,4,'a'],[5,6,7,8,'b'],[9,10,11,12,'c']],
tableObj = arr.map(e => ({N: e[0], Name: e[1], Surname : e[2], Tel: e[3], email: e[4]})),
tableHTML = tableMaker(tableObj,true);
document.write(tableHTML);