Add button to a dynamically created table row - javascript

so Iam trying to add this button to a dynamically created table row. But I honestly don't know how to get this working. The code is a mess, because Iam trying so many things in order to get this going.
I need to append this button (element) to the table row where the function is called, is there any smart way to do this. If i change my structure of the table, thats okay.
function getPerson(){
//addButton.value = "+";
//addButton.class = "btn btn-success";
$("#output1 tbody tr").remove();
fetch(url)
.then(res => res.json())
.then(data => {
console.log(data);
var temp = "";
data.forEach((person) => {
temp += "<tr>";
temp += "<td>" +person.id+"</td>";
console.log(person.id);
temp += "<td>" +person.vorname+"</td>";
temp += "<td>" +person.nachname+"</td>";
temp += "<td>"
person.projectList.forEach((project) => {
temp += project.name+"<br>";
});
temp += "</td>"
temp += "<td>"
person.technoList.forEach((techno) => {
temp += techno.name+"<br>";
});
temp += "</td>"
temp += "<td id='addButton" + x + "' >" + addButton(person.id)+ "</td>"
//this.parentElement.appendChild(this)
x++;
//document.getElementById('personDetail_Button').addEventListener('click', this.personDetail(person.id));
temp += "</tr>"
});
document.getElementById("tableOutput").innerHTML= temp;
});
}
function addButton(person_id){
var person_id_onclick = person_id
var element = document.createElement("input");
element.type = 'button';
element.value = 'test123';
element.onclick = function(){
personDetail(person_id_onclick);
}
$(element).addClass('btn btn-primary');
//$(this).appendChild(element);
document.body.appendChild(element);
}
<table class="table" id="output1">
<thead class="thead-dark">
<tr>
<th scope="">ID</th>
<th scope="col">Vorname</th>
<th scope="col">Nachname</th>
<th scope="col">Projekte</th>
<th scope="col">Technologien</th>
<th scope="col">Button</th>
</tr>
</thead>
<tbody id="tableOutput">
</tbody>
</table>

You can try replacing document.body.appendChild(element); with return element; I also updated the function to remove the random jquery class.
function addButton(person_id){
var element = document.createElement("input");
element.type = 'button';
element.value = 'test123';
element.setAttribute("data-person_id",person_id);
element.setAttribute("class","btn-viewdetail btn btn-primary");
var _wrap = document.createElement("div");
_wrap.appendChild(element);
return _wrap.innerHTML;
}
var _btns = document.querySelectorAll(".btn-viewdetail");
_btns.forEach(function(el){
el.addEventListener("click",function(evt){
personDetail(evt.target.getAttribute("data-person_id"));
});
});
document.body.innerHTML += addButton(4);

Related

Sorting table using only Javascript

I have this table in which I read the tbody contents from a JSON API and now I need to make it sortable by columns and using only javascript and no Jquery.
Any help would be appreciated
i have found this code which is exactly what i want, but i don't know how to refer to tbodies from my api
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
var myData = JSON.parse(myRequest.responseText);
dataTable(myData);
};
myRequest.send();
function dataTable(data) {
if (data.length > 0) {
var temp = '';
data.forEach((u) => {
temp += '<tr>';
temp += "<td style='text-align: center'>" + u.userId + '</td>';
temp += "<td style='text-align: center'>" + u.id + '</td>';
temp += '<td>' + u.title + '</td>';
temp += "<td style='text-align: center'>" + u.completed + '</td></tr>';
document.getElementById('data').innerHTML = temp;
});
}
}
<table class="table_id">
<thead>
<tr>
<th>UserID</th>
<th>ID</th>
<th>Title</th>
<th>Completion</th>
</tr>
</thead>
<tbody id="data">
</tbody>
</table>
var myData, asc = {'userId':true, 'id':true, 'title':true, 'completed':true};
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
myData = JSON.parse(myRequest.responseText);
dataTable(myData);
};
myRequest.send();
function sortTable(key){
myData.sort(function(a, b) {
if(asc[key]){
return a[key] > b[key]? 1:-1;
}
else{
return a[key] > b[key]? -1:1;;
}
});
asc[key] = !asc[key];
document.getElementById('data').innerHTML = '';
dataTable(myData);
}
function dataTable(data) {
if (data.length > 0) {
var temp = '';
data.forEach((u) => {
temp += '<tr>';
temp += "<td style='text-align: center'>" + u.userId + '</td>';
temp += "<td style='text-align: center'>" + u.id + '</td>';
temp += '<td>' + u.title + '</td>';
temp += "<td style='text-align: center'>" + u.completed + '</td></tr>';
document.getElementById('data').innerHTML = temp;
});
}
}
<table class="table_id">
<thead>
<tr>
<th onclick="sortTable('userId');">UserID</th>
<th onclick="sortTable('id');">ID</th>
<th onclick="sortTable('title');">Title</th>
<th onclick="sortTable('completed');">Completion</th>
</tr>
</thead>
<tbody id="data">
</tbody>
</table>
Here is a quick class I made.
You first load your data with dt.load(), then when someone clicks one of the headers, you can add an event that does:
elm.addEventListener("click", (e) => {
prop = e.target.textContent.trim();
dt.sort(prop);
dt.render();
})
class DataTable{
load(arr){
if(arr) this.data = arr;
}
sort(prop){
this.data.sort((a, b) => a[prop] - b[prop]);
}
render(selector="#data"){
if(data.length){
html = data.map(u => {
return [
"<tr>",
`<td style='text-align: center'>${u.userId}</td>`,
`<td style='text-align: center'>${u.id}</td>`,
`<td>${u.title}</td>`,
`<td style='text-align: center'>${u.completed}</td></tr>`
].join("");
}).join("");
document.querySelector(selector).innerHTML = html;
}
}
}
Important - are you wanting to be able to sort multiple columns at the same time or just one column at a time?
Initialize myData outside of onload first. You'll want to be able to access those results outside of onload to sort them. The actual sort function JS offers is a pretty confusing but it's really the only way to go about vanilla JS array sorting.
function sortData(col, asc = true) {
//JS sort function
myData = myData.sort((first, second) => {
//sort logic
if (first[col] == second[col]) {
return 0;
}
if (asc) {
if (first[col] > second[col]) {
return 1;
}
else {
return -1;
}
}
else {
if (first[col] > second[col]) {
return -1;
}
else {
return 1;
}
}
});
//Re-Create table
dataTable(myData);
}
EDIT:
I added in sort logic, but it's definitely possible I messed up. I can't actually test this right now and I haven't touched the sort function in years.

Creating a table through local storage data?

How can I populate my table with an array of local storage data?
function savePlayer() {
let Player = {player,score};
localStorage.setItem("Player", JSON.stringify(Player));
let getPlayerScore = Player;
let text = document.getElementById("topScores");
for(let i = 0; i <Player.length; i++){
text += "<tr>";
text += "<td>" + getPlayerScore[i].player + "</td>";
text += "<td>" + getPlayerScore[i].score + "</td></tr>";
}
Here's the HTML:
<body>
<table id = "topScores">
<tr>
<th>Username</th>
<th>Score</th>
</tr>
</table>
</body>
What am I doing wrong?
The Player.toString() isn't what you think it is.
var player = "Mario";
var score = 1000;
var Player = {
player,
score
};
// Print Player
console.log(JSON.stringify(Player));
console.log(Player.toString());
You can't just add text to an element; you need to set it though
innerHTML. Sadly, however, you can't set it for each row, because the DOM will try to end the tr tag, so you need to set everything at the same time through a string.
I couldn't get localStorage to work in the snippet so I commented out the code without testing it.
Another solution would be to append the elements, and honestly, that's what I would prefer, but I didn't want to steer to far away from your original solution, and I didn't want fix the "feature" where the DOM is autocompleting tr tags.
function savePlayer() {
// This wasn't an array to begin with, so I fixed that.
let Player = [{"player": "player","score": 10}];
// It's usually preferred to refer to a public constant when accessing localStorage.
let localStorageKey = "player";
/* localStorage.setItem(localStorageKey, JSON.stringify(Player));
let getPlayerScore = JSON.parse(localStorage.getItem(localStorageKey));*/
let getPlayerScore = Player;
let text = document.getElementById("topScores");
var playerRow = "";
for(let i = 0; i < getPlayerScore.length; i++){
playerRow = "<tr>";
playerRow += "<td>" + getPlayerScore[i].player + "</td>";
playerRow += "<td>" + getPlayerScore[i].score + "</td></tr>";
}
text.innerHTML += playerRow;
}
<body onload="savePlayer()">
<table id="topScores">
<tr>
<th>Username</th>
<th>Score</th>
</tr>
</table>
</body>

Using Firestore's snapshot.forEach to create a table

I'm trying to output an array filled with Firestore objects onto a table, but just displays the last object above the table
<table class="darkTable">
<thead>
<tr>
<th>List of Available Shows</th>
</tr>
</thead>
<tbody>
<tr>
<div id="showList"></div>
</tr>
</tbody>
</table>
<script>
firebase.firestore().collection('TV Shows').get().then(snapshot => {
var i = 0;
var array = [];
snapshot.forEach(doc => {
array[i] = doc.data().show.name;
//console.log(doc.data().show.name);
//showList.innerHTML = array[i] + "<br />";
showList.innerHTML = '<td>' + array[i] + '</td>';
i++;
});
});
</script>
Is it the way I'm going about the td code lines?
assuming this markup:
<div id="showList"></div>
then it works about like this:
firebase.firestore().collection('TV Shows').get().then(snapshot => {
var showList = document.getElementById('showList');
var html = '<table class="darkTable"><thead><tr>';
html += '<th>List of Available Shows</th>';
/* add further columns into here, alike the one above. */
html += '</tr></thead><tbody>';
snapshot.forEach(doc => {
html += '<tr>';
html += '<td>' + doc.data().show.name + '</td>';
/* add further columns into here, alike the one above. */
html += '</tr>';
});
html += '</tbody></table>';
showList.append(html);
});
You're resetting the entire showList element with every iteration of the loop:
showList.innerHTML = '<td>' + array[i] + '</td>';
I suspect you mean to append to it each time instead or resetting it entirely each time. Maybe try building a string with each iteration, then set the whole thing after the loop is over.

How can I insert a <tr> element into a dynamic table?

I hope someone has a clue for me. I am new to javascript and I am trying to build this structure with a dynamically generated table.
<table>
<tr>
<td>value1</td>
<td>value2</td>
<td>value3</td>
<td>value4</td>
</tr>
<tr>
<td>value5</td>
<td>value6</td>
<td>value7</td>
<td>value8</td>
</tr>
<tr>
<td>value9</td>
<td>value10</td>
<td>value11</td>
<td>value12</td>
</tr>
<tr>
<td>value13</td>
<td>value14</td>
<td>value15</td>
<td>value16</td>
</tr>
</table>
What I tried to do is to echo a <tr> after every 4th pair of <td>.
Like this:
var tbody_el = $("#somevalue_id"); //is the id of the table, which needs to be filled with `<tr>` and `<td>`.
var counter = 0;
$.each(TonsOfData.getValues(), function(index, somevalue) {
//var tr_el = $("<tr></tr>");
var td_checkbox_el = $("<td></td>");
var cbName = "cb_" + somevalue.displayName + "_name";
var cbId = "cb_" + somevalue.displayName + "_id";
var inputEl = $("<input type='checkbox' name='" + somevalue.displayName + "' id='" + cbId + "'/>");
inputEl.data("somevalueId", somevalue.id);
inputEl.attr("checked", "checked");
inputEl.change(valueChoicesClick);
var div_value_id = "div_value_" + somevalue.id + "_id";
var div_value_el = $("<div id='" + div_value_id + "' align='left'></div>");
var td_value = $("<td></td>");
td_checkbox_el.append(inputEl);
if(counter == 0 || (counter +1)%4 == 0){
echo "<tr>";
}
td_value.append(td_checkbox_el, "<br> Displayname: " + somevalue.displayName,"<br> Unit: "+ somevalue.unitstring," <br>",div_value_el);
if((counter +1)%4 == 0) {
echo "</tr>";
}
//tbody_el.append(tr_el);
}
);
Is this even possible?
Or am I going a totally wrong way?
Big thanks for any suggestions!!
EDIT:
I found a solution that worked for me. I doubt anyone will have the same issue, but I'd like to share it anyway.
I created a counter that gets incremented in the loop and gave the <td> parts a class-id.
if(counter<4){
td_value = $("<td class='select1'></td>");
}
if(counter>3 && counter <8){
td_value = $("<td class='select2'></td>");
}
if(counter>7 && counter <12){
td_value = $("<td class='select3'></td>");
}
if(counter>11 && counter <16){
td_value = $("<td class='select4'></td>");
}
if(counter>15 && counter <20){
td_value = $("<td class='select5'></td>");
}
After that I used the JQuery wrapAll()-function to add my <tr>. That did the trick.
$('#somevalue_id td.select1').wrapAll('<tr/>');
$('#somevalue_id td.select2').wrapAll('<tr/>');
$('#somevalue_id td.select3').wrapAll('<tr/>');
$('#somevalue_id td.select4').wrapAll('<tr/>');
$('#somevalue_id td.select5').wrapAll('<tr/>');
I know, it is not the most elegant solution but it works.
Thanks again to everyone that gave me hints, you helped me solve this!
You can use jquery and using .each for iterating and getting the fourth element in each iteration using .nth-child and inserting after using .insertAfter
Please find the example to mainuplate the table accordingly.
this is one way you can do it
<table class="test_table" id="test_table">
</table>
var tableEl = $(".test_table");
var noOfRows = 4;
var noOfColumns = 4;
//Empty the table in case there is anything already there
tableEl.each(function(){
var tableElObject = $(this);
for(i=0;i<noOfRows;i++)
{
rowStart = "<tr>";
for(j=0;j<noOfColumns;j++)
{
rowStart +="<td>"+"Test"+i+j+"</td>";
}
tableElObject.append(rowStart+"<tr/>");
}
});
http://jsfiddle.net/qg5hG/
if you want to create tables trs and tds dynamically this way can be better for you....
var table = document.createElement('table');
table.setAttribute('border','0');
table.setAttribute('cellspacing','5');
table.setAttribute('cellpadding','5');
table.setAttribute('width','100%');
var tr = table.insertRow(-1);// "-1"s meaning add tr to end of table if you want to add top of table you must use "0"
tr.id = 'Tr1 ID';
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 1';
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 2';
var tr = table.insertRow(-1);
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 1';
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 2';

How to add image in table cell

Hi I want to add image in table cell according to condition in table. I am using dynamic table as follow:
$.get('http://myDomain.com/RIA/topIndiaDetails.asp', function(data)
{
console.log("####"+data);
var up = new Image();
var down = new Image();
up.src = "../../jquery.mobile/images/up.png";
down.src = "../../jquery.mobile/images/down.png"
substr = data.split('$');
//alert(substr.length);
//var theader = '<table border="1">\n';
//<table id="auditOverview" border="1">
var theader = '<table border="1" id=\"tableId\">\n';
var tbody = '';
for (var out = 1;out<substr.length-1;out++)
{
//alert(substr[out]);
tbody += '<tr>';
var pra = substr[out].split('|^');
//alert('pra.length is: '+pra.length);
for (var i=0;i<pra.length-1;i++)
{
tbody += '<td>';
if (pra[i]=="Red")
{
pra[i].append("<img id='theImg' src='../../jquery.mobile/images/down.png'/>");
}
else if (pra[i]=="Green")
{
pra[i].append("<img id='theImg' src='../../jquery.mobile/images/up.png'/>");
}
tbody += pra[i];
tbody += '</td>'
}
tbody += '</tr>\n';
}
var tfooter = '</table>';
document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
});
Now I am checking condition as if (pra[i]=="Green") then I want to add image in cell insted of "Green" string and same for Red string. Any help will be appreciated. Thanks in advance.
instead of :
pra[i].append("<img id='theImg' src='../../jquery.mobile/images/up.png'/>");
do
pra[i] = "<img id='theImg' src='../../jquery.mobile/images/up.png'/>";

Categories

Resources