I have a table generated with data from an array (the array contains more info than what is displayed in the table). I want to click on a row to see all info from the element.
Earlier done it like this:
let rows = document.getElementsByTagName("tr");
for (let row of rows) {
row.onclick = function rowClicked(evt) {
selected = myArray[evt.target.parentElement.rowIndex];
//code (not relevant)
}
But since I added a search feature myArray[1] is not necessarily equal to row number 1 and this method doesn't work.
Is it another way to find the element in the array from clicking on a random row?
The table is generated like this:
function drawTable(data) {
let table = document.getElementById("table");
table.innerHTML = "";
let tableHead = document.createElement("thead");
let colHeads = ["Names"];
for (let header of colHeads) {
let cell = document.createElement("th")
cell.innerHTML = header;
tableHead.appendChild(cell);
}
table.appendChild(tableHead)
for (var i = 0; i < data.length; i++){
let row = document.createElement("tr");
let name = document.createElement("td");
name.innerHTML = data[i].name.first + " " + data[i].name.last;
row.appendChild(name);
table.appendChild(row);
}
}
Any help is greatly appreciated!
You need some way to map a table row to its relevant entry in myArray which isn't dependent on the position of the row in the table. Data attributes wouldn't be affected.
Create a data-index attribute on each table row. Then, when it's clicked use the value of the data-index attribute to access the relevant myArray entry.
A simple version of what you have in mind. The visible line is bound with a click event. As soon as it is triggered, it gets the ref-id from the clicked element and toggles the reference column.
const clickables = document.querySelectorAll('.clickable');
console.log(clickables)
clickables.forEach(tr => {
tr.addEventListener('click', (e) => {
const ref = e.target.parentElement.getAttribute('data-ref');
const row = document.querySelector('#' + ref);
row.classList.toggle('hide');
});
});
td {
text-align: center;
padding: 20px;
}
.hide {
display: none;
}
.clickable {
cursor: pointer;
}
.clickable:hover {
background: #ccc;
}
<table border="1">
<tr class="clickable" data-ref="a">
<td>1</td>
<td>2</td>
</tr>
<tr id="a" class="hide">
<td>a1</td>
<td>b2</td>
</tr>
<tr class="clickable" data-ref="b">
<td>3</td>
<td>4</td>
</tr>
<tr id="b" class="hide">
<td>a3</td>
<td>a4</td>
</tr>
</table>
Related
I want to make a row in a table selectable, however whenever I click the row, the console log shows that it did the right thing, but didn't change its class. Why is that and how can I fix it?
Part of the Code, that generates the select feature:
var tableconn = document.getElementById("connectionsLane"+laneid);
let row = tableconn.insertRow();
row.id = "row"+insertData.id;
row.onclick = function() {
if (row.classList.contains("selected")) {
console.log("unselected");
row.classList.remove("selected");
} else {
console.log("selected")
document.getElementById("row" + insertData.id).classList.add("selected");
}
}
insertData.id gets increased by 1 each time the whole thing is called, whilst laneid is dependent on which part of the website the user is currently refering to (is a int 1-255)
Here is a simple example of how you can select a table row and style it using a function. This function can be used for setting class name on rows in any table in a document.
// for setting the class name on a row in a table
const onrowselect = e => {
let table = e.target.closest('table');
let trs = table.querySelectorAll('tr');
// remove all class=selected
trs.forEach(tr => tr.classList.remove('selected'));
// the current tr
var tr = e.target.closest('tr');
tr.classList.add('selected');
};
// define a table
var table01 = document.getElementById('table01');
// add and eventlistener to the table
table01.addEventListener('click', onrowselect);
tr {
cursor: pointer;
}
.selected {
background-color: silver;
}
<table id="table01">
<tr>
<td>Row</td>
<td>1</td>
</tr>
<tr>
<td>Row</td>
<td>2</td>
</tr>
<tr>
<td>Row</td>
<td>3</td>
</tr>
</table>
so im trying to add a buttons to the end of each row since the table is dynamic I have to use javascript to append it but everytime I try it doesn't work if it does it will just put a button at the end of the last row of the table. Heres an image of what I get linked below
enter image description here
<!--TABLE HEADER SECTION-->
<div class="div0">
<table class="tableHeader">
<thead>
<tr>
<th>Store</th>
<th>Product</th>
<th>Profile</th>
<th>Proxies</th>
<th>Status</th>
<th>ACTION</th>
</tr>
</thead>
</table>
</div>
<!--TABLE SECTION-->
<div class="div1">
<table id = "botTasksTable" class="table table-dark table-sm table-bordered">
<tbody>
<tr>
<td>another name</td>
<td>mockdata</td>
<td>mockdata</td>
<td>mockdata</td>
<td>mockdata</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript">
const tableBody = document.querySelector("#botTasksTable > tbody");
//function to load table into tbody from jsonfile bottable which would be the users given tasks
function loadBotTasksTable() {
const request = new XMLHttpRequest();
request.open("get", "data/botTable.json"); //grabs the data from the json file its in the data file/ and named bottable.json
request.onload = () => {
const json = JSON.parse(request.responseText); //attempts to parse the data it gets
populateTable(json);
};
request.send(); //sends out the request for thr function
}
var btn = document.createElement("BUTTON");
var btn = document.createElement("BUTTON"); // Create a <button> element
btn.innerHTML = "CLICK ME"; // Insert text
function populateTable(json) {
//this while loop clears out existing table data!
//we want to add this back but adding a value to first child even if its a mock value.
while (tableBody.firstChild) { //so basically checking if the table has <tr> <td></td> </tr> so a row and column
tableBody.removeChild(tableBody.firstChild)
}
//now we populate table
json.forEach((row) => { //loops through each row [ SUPREME, Nike SB Dunks, profile1, proxy22, In Progress ]
const tr = document.createElement("tr"); //create the new row
row.forEach((cell) => { //loops through each individual column of the row EX : SUPREME
const td = document.createElement("td");
td.textContent = cell // passes whatever data the json file had in the cell into the text content of the row
tr.appendChild(td);
});
//for each cell in the row get the index and append
tableBody.appendChild(tr); //appends the row into the table body row by row as i runs through the for loop
});
loopTable();
}
//loop through table and add button to the table
function loopTable() {
var table = document.getElementById('botTasksTable');
for (var i = 0, row; row = table.rows[i]; i++) {
//iterate through rows
//rows would be accessed using the "row" variable assigned in the for loop
row.appendChild(btn);
console.log(i);
}
};
You need to create a new button for each row, and put it inside a <td>. You can use cloneNode() to make a copy of an element.
//loop through table and add button to the table
function loopTable() {
var table = document.getElementById('botTasksTable');
for (var i = 0, row; row = table.rows[i]; i++) {
let td = document.createElement('td');
td.appendChild(btn.cloneNode());
row.appendChild(td);
console.log(i);
}
};
I wanna ask that is there any way to insert html content using javascript in such a way like i have a table and inside there is a tbody and inside that i am inserting element using javascript like i am inserting tr and inside that tr i am inserting 5 td and i want that 5 td to have different content and if you try to put all the above stuff in code it will look something like this
for(let i = 1; i< 38; i++){
let swd = {
active: data.statewise[i].active,
confirmed: data.statewise[i].confirmed,
deaths: data.statewise[i].deaths,
recovered: data.statewise[i].recovered
}
let swdb = document.getElementById('swdb');
let swtr = document.createElement('tr');
swdb.appendChild(swtr);
for(let j = 1; j<6; j++){
let swtd = document.createElement('td');
swtr.appendChild(swtd);
}
}
and challenge for me is to insert different content in td inside same tr. And after that final html code should look like this :-
<tr>
<td>Custom content 1</td>
<td id="active"> Custom content 2</td>
<td id="conf">Custom content 3</td>
<td id="deaths">Custom content 4</td>
<td id="recov">Custom content 5</td>
</tr>
and after that i will generate more tr like this.
Hope you understand my problem and help me!
As I undrestood you just need innerText for adding content inside td:
you can make an array of object like this:
const customContent = [
{id:"",content:"Custom content 1"},
{id:"active",content:data.statewise[i].active},
{id:"confirmed",content:data.statewise[i].confirmed},
{id:"deaths",content:data.statewise[i].deaths},
{id:"recov",content:data.statewise[i].recovered},
]
And use them like this:
customContent.forEach(item => {
let swtd = document.createElement('td');
swtd.id = item.id;
swtd.innerText = item.content;
swtr.appendChild(swtd);
});
Actually the same example as #b3hr4d but u shouldn't use .innerHTML on plain text, choose between .textContent and .innerText. Good luck =)
const contentList = [
{ id: "", text: 'Custom content 1' },
{ id: 'active', text: 'Custom content 2' },
];
const tr = document.createElement('tr');
contentList.forEach(({ id, text }) => {
const td = document.createElement('td');
if (id) td.setAttribute('id', id);
td.textContent = text;
tr.appendChild(td);
});
const root = document.querySelector('#root');
root.appendChild(tr);
result
<div id="root">
<tr>
<td>Custom content 1</td>
<td id="active">Custom content 2</td>
</tr>
</div>
I have existing table where I would like to add/append tbody element. Here is example of my HTML table:
<div id="myDiv">
<table class="myTable">
<thead>
<tr>
<th>ID</th>
<th>Last</th>
<th>First</th>
<th>DOB</th>
<th>Nickname</th>
</tr>
</thead>
</table>
</div>
Here is my JavaScript/JQuery code:
var divID = $('#myDiv table.myTable');
var tbl = "<tbody>";
for(var i=0; i < numRecs; i++){
var jsRec = obj.DATA[i];
tbl += "<tr id='lookup_"+i+"'>";
tbl += "<td>"+decodeURIComponent(jsRec.ID)+"</td>";
tbl += "<td>"+decodeURIComponent(jsRec.LAST)+"</td>";
tbl += "<td>"+decodeURIComponent(jsRec.FIRST)+"</td>";
tbl += "<td>"+decodeURIComponent(jsRec.DOB)+"</td>";
tbl += "<td>"+decodeURIComponent(jsRec.NICKNAME)+"</td></tr>";
}
tbl += "</tbody>";
divID.append(tbl);
$.alert(divID,'Main Menu',1000,600); //JQuery dialog box that takes html variable, title, width and height
I'm getting blank content in my dialog box with this code. If anyone can help or see where is my code breaking please let me know. Thank you.
It looks like you're not closing the <tr> in your loop, making a series open-ended table-rows. jQuery validates HTML before appending into the DOM so it's likely silently failing when trying to append.
I would separate the creation of elements in small chunks a shown in the following example. That way it would be easier to separate were things are going south. You´ll probably only need to replace sampleData[i]["id"] with decodeURIComponent(jsRec.ID), etc. I only created the sampleData Array for the examples sake. It might also be possible to execute decodeURIComponent() for each of the properties of your object inside a loop.
(function($) {
$(document).ready(function() {
var sampleData = [{
id: 1,
last: "lst",
first: "first",
DOB: "IDK",
nickname: "nick"
}];
var divID = $('#myDiv table.myTable tbody');
var current, row, cell;
for (var i = 0; i < sampleData.length; i++) {
row = $("<tr></tr>"); //Create a row
cell = $("<td></td>").html(sampleData[i]["id"]); //Create a cell
row.append(cell); //Append The cell
cell = $("<td></td>").html(sampleData[i]["last"]);
row.append(cell);
cell = $("<td></td>").html(sampleData[i]["first"]);
row.append(cell);
cell = $("<td></td>").html(sampleData[i]["DOB"]);
row.append(cell);
cell = $("<td></td>").html(sampleData[i]["nickname"]);
row.append(cell);
divID.append(row); //Add Row to the Table
}
});
})(jQuery);
td,
th,
tr {
border: 1px solid gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="myDiv">
<table class="myTable">
<thead>
<tr>
<th>ID</th>
<th>Last</th>
<th>First</th>
<th>DOB</th>
<th>Nickname</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
At the end you might have trouble with $.alert(divID,'Main Menu',1000,600); but all you might need is to add a toString() or something like that.
I would like to split this entire table into three sub tables using Javascript. Each table should retain it's header information.
I cannot adjust the id's or classes as they are generated by a web application, so I need to make do with what is available.
I've been trying to crack this with Jfiddle for quite awhile and am getting frustrated. I'm pretty new to Javascript, but can't image this would require a lot of code. If anyone knows how to split this apart by row size as well (i.e. Split Table up, but selectively), that would be appreciated as well.
I'm limited to Javascript and Jquery 1.7.
<div id="serviceArray">
<table border="1" class="array vertical-array">
<thead>
<tr>
<th>#</th>
<th>Savings</th>
<th>Expenses</th>
<th>Savings</th>
<th>Expenses</th>
<th>Savings</th>
<th>Expenses</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sum</td>
<td>$180</td>
<td>$500</td>
<td>$300</td>
<td>$700</td>
<td>$600</td>
<td>$1000</td>
</tr>
<tr>
<td>Home</td>
<td>$100</td>
<td>$200</td>
<td>$200</td>
<td>$300</td>
<td>$400</td>
<td>$500</td>
</tr>
<tr>
<td>Work</td>
<td>$80</td>
<td>$300</td>
<td>$100</td>
<td>$400</td>
<td>$200</td>
<td>$500</td>
</tr>
</tbody>
</table>
</div>
Did you mean like this?
var tables = $('#serviceArray table tbody tr').map(function () { //For each row
var $els = $(this).closest('tbody') //go to its parent tbody
.siblings('thead').add( //fetch thead
$(this) //and add itself (tr)
.wrap($('<tbody/>')) //wrapping itself in tbody
.closest('tbody')); //get itself with its tbody wrapper
return $els.clone() //clone the above created steps , i.e thead and tbody with one tr
.wrapAll($('<table/>', { //wrap them all to a new table with
'border': '1', //attributes.
'class': 'array vertical-array'
})
).closest('table'); //get the new table
}).get();
$('#serviceArray table').remove();
$('body').append(tables); //append all to the table.
Demo
Or just simply clone the table and remove all other trs from tbody except this one and add it to DOM (Much Shorter Solution).
var tables = $('#serviceArray table tbody tr').map(function (idx) {
var $table = $(this).closest('table').clone().find('tbody tr:not(:eq(' + idx + '))').remove().end();
return $table;
}).get();
Demo
Each of the methods used has documentation available in web and you can use this to work out something yourself to what you need.
You can use simple Javascript for table creation and it will generate rows according to your returned response from api.
var tableHeader = this.responseJsonData.Table_Headers;
var tableData = this.responseJsonData.Table_Data;
let table = document.querySelector("table");
function generateTableHead(table, data) {
//alert("In Table Head");
let thead = table.createTHead();
let row = thead.insertRow();
for (let key of data) {
let th = document.createElement("th");
let text = document.createTextNode(key);
th.appendChild(text);
row.appendChild(th);
}
}
function generateTable(table, data) {
// alert("In Generate Head");
for (let element of data) {
let row = table.insertRow();
for (key in element) {
let cell = row.insertCell();
let text = document.createTextNode(element[key]);
cell.appendChild(text);
}
}
}