How to detect if a table contains a table? - javascript

I have multiple tables need to be nested with divs
Like this:
<table>
<tr>
<td>
<table>
<tr>
<td>EEE</td>
<td>EEE</td>
</tr>
</table>
</td>
</tr>
</table>
Then, I get each table with the code below:
var isert = inn.getElementsByTagName("table");
for(var i = 0 ;i<isert.length;i++)
{
var div = document.createElement("div");
var _t = isert[i];
var parent = _t.parentNode;
div.className = "extra";
parent.replaceChild(div, _t);
div.appendChild(_t);
}
}
So the table becomes:
<div class="extra">
<table>
<tr>
<td>
<div class="extra">
<table>
<tr>
<td>EEE</td>
<td>EEE</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
</div>
However, after I adding css styles to class "extra", they are overlapped. So what I need is a method like below to detect whether this table contains a table inside.
if( ! 'table' contains 'table'){
...adding the div...
}
I hope this could be solve by pure JavaScript. Thanks!

I don't know what kind of themes you're working with, but you would conceivably be able to solve this with pure CSS
table { some theme style; }
table table { revert to default style; }
EDIT
From what I understand after your update, you want to turn the following code int something that doesn't rely on jQuery, correct?
var curr = $(this);
if(!curr.has('table').length) {
getElementsByTagName is available on all tag nodes and will only yield child elements, so you could do that check as follows:
if(!curr.getElementsByTagName('table').length) {

Related

How To Grab Data In Any Table Row (HTML/JavaScript) Using Tree Traversal Methods

I have a table that looks like this -->
<table>
<tr style="display: none";><td class="index">index_value</td></tr>
<tr><td>section header</td></tr>
<tr>
<td class="name>Steven</td>
<td class="height">6 ft.</td>
<td><button class="add">Add</button></td>
</tr>
</table
and a js script that looks like this -->
<script>
$(".add").on('click', function(){
var the_name = $(this).closest("td").siblings(".name").text();
var the_type = $(this).closest("td").siblings(".type").text();
var the_index = $(this).parent().find("td.index").text();
}
</script>
As you can probably tell, I'm trying to get the values of certain td within this table. The first two variables work just fine because they are within the same table row; however, the last variable is not capturing the data I want (inside the index class).
I'm having some trouble understanding these methods of tree traversal and how I can grab data within a table row that is not the one which contains the button that is clicked. Any advice would be appreciated, thank you.
There were a few syntax errors in your code that you need to clean up, but the issue you're having with getting the value in the index cell is that you're not going far enough up the DOM tree to run the .find() command.
$(".add").on('click', function(){
var the_name = $(this).closest("td").siblings(".name").text();
var the_type = $(this).closest("td").siblings(".type").text();
var the_index = $(this).closest("table").find("td.index").text();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr style="display: none";><td class="index">index_value</td></tr>
<tr><td>section header</td></tr>
<tr>
<td class="name">Steven</td>
<td class="height">6 ft.</td>
<td><button class="add">Add</button></td>
</tr>
</table>

javascript get external table row on click

I have a button:
<button id="external-list-row">Test</button>
in which I would like to change with a row from an external table on click. The external table is structured like this;
<table id="table_id">
<thead>
<tr>
<th>X</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Row 1</p>
</td>
</tr>
<tr>
<td>
<p>Row 2</p>
</td>
</tr>
<tr>
<td>
<p>Row 3</p>
</td>
</tr>
</tbody>
</table>
So my question is this; how can I replace "Test" in the button with the content of Row 1 with javascript?
As for the javascript, I'm not sure how I can get the content from row 1, and replace the button with it.
<script>
var rows = document.getElementById('table_id').getElementsByTagName("tr");
for (var i=0; i<rows.length; i++) {
$('#external-list-row').onclick = function() {
}};
</script>
Post comments:
I can access table data from other tables within the same html file, but I still don't know how to access data from tables in other html files. For example, if I try to access a videos liquid file from another liquid file, like photos, nothing happens when I press the button.
Fiddle of current code. It can replace the content of a list with the content of another, but the lists need to be on the same html file.
https://jsfiddle.net/hgnymydL/
Well, the first thing you should understand, is that a table element has a rows property, so getting the first row is trivial.
var table = document.getElementById("table_id");
var firstRow = table.rows[0];
From there, you can use textContent to get the text content of the row. I believe that's what you were looking for.
You can also select the first row of a table with a CSS selector like so:
var firstRow = document.querySelector("#table_id tbody tr");
$('#external-list-row').on('click', function() {
$(this).text($('#table_id tbody tr:first').text());
});
If you want to replace the button text with contents of the First Row ONLY then:
$('#external-list-row').html($('tr:first-child').html);
Of course you could wrap this in any event, so for example, on clicking the button:
$('#external-list-row').on('click', function() {
$(this).html($('tr:first-child').text());
});
BUT, based on the code you have given, I'm assuming you want to change the text after each click in which case you could do this:
var clickNumber = -1;
$('#external-list-row').on('click', function(event) {
clickNumber = clickNumber + 1;
//console.log('\n\nclickNUmber' + clickNumber);
$('tbody tr').each(function(index, el) {
//console.log('index: ' + index);
var block = $(el).find('td p');
if(index == clickNumber) {
//console.log('entered if')
//console.log(block.text());
//console.log('----clickNUmber' + clickNumber);
//console.log('index: ' + index);
//console.log(el);
$('#external-list-row').html(block.text());
}
});
});
jsFiddle: https://jsfiddle.net/zmb2b37t/
Hope that helps!
If you are wanting to replace the visible text "Test" in the button with the content of the cell clicked:
var tbl = document.getElementById('table_id');
var btn = document.getElementById('external-list-row');
tbl.onclick = function(ev){
var trgt = ev.target;
if(trgt.tagName === 'P' ||trgt.tagName === 'TD'){
btn.textContent = trgt.textContent;
}
};
Only one event handler is attached in this scenario.
Via event delegation we determine if it was a TD or P element that was clicked. If the rows are modified the function will still work.
Here is jquery code of do this
$('#table_id tr td').on('click', function(){
$('#external-list-row').html($(this).html());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="external-list-row">Test</button>
<table id="table_id">
<thead>
<tr>
<th>X</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Row 1</p>
</td>
</tr>
<tr>
<td>
<p>Row 2</p>
</td>
</tr>
<tr>
<td>
<p>Row 3</p>
</td>
</tr>
</tbody>
</table>

How to append td element in the same column of th element in a table?

I need to append data to a table dynamically from a JSON object.
After adding the titles as th elements, I am finding it difficult to add tr elements in the same column as the corresponding th element. Please help me.
{
"Category2":"Item2",
"Category1":"Item1",
"Category3":"Item3"
}
<table>
<th>Category1</th>
<th>Category2</th>
<th>Category3</th>
</table>
Now, I need to add items in td tags in the columns same as their corresponding th elements. like:
<table>
<th>Category1</th>
<th>Category2</th>
<th>Category3</th>
<tr>
<td>Item1</td>
</tr>
<tr>
<td>Item2</td>
</tr>
<tr>
<td>Item3</td>
</tr>
</table>
How can I do this using jQuery? (My problem is bigger than this. I simplified it so that it can be understood. Thank you!)
Here you go, Press Run code snippet and check if this works for you.
var nodes = {
"Category2":"Item2",
"Category1":"Item1",
"Category3":"Item3"
};
$(function(){
var th_elements = $('table').find('th'); // find <th> in HTML
th_elements.each(function(){ // Loop as much <th> found
var html = $.trim($(this).html()); // get HTML and compare with nodes key
$('table').append('<td>'+nodes[html]+'</td>'); // append data to table
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<table>
<th>Category1</th>
<th>Category2</th>
<th>Category3</th>
</table>

Multiple elements with same Id in Javascript

I have a case where a html file contains multiple elements with the same ID name.
The table row contains 5 columns of which I need to consider 2,3,4,5 columns data.
<tr id='total_row'>
<td>Total</td>
<td>%(count)s</td>
<td>%(Pass)s</td>
<td>%(fail)s</td>
<td>%(error)s</td>
<td> </td>
</tr>
I have the above code at several places in the file. I need to add the respective values using javascript.
An ID is unique in an html page. You can call it THE ID as well wrt a page. You cannot have same ID for two different tags in a single page. But you can use class instead of and ID. Know about it here
So your HTML can be like
<tr class='total_row'>
<td>Total</td>
<td>%(count)s</td>
<td>%(Pass)s</td>
<td>%(fail)s</td>
<td>%(error)s</td>
<td> </td>
</tr>
As an example with jquery you can do something like this,
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<table>
<tr class="one">
<td></td>
<td></td>
</tr>
<tr class="one">
<td></td>
<td></td>
</tr>
<tr class="one">
<td></td>
<td></td>
</tr>
</table>
<script src="jquery-1.11.0.min.js"></script>
<script>
$(document).ready(function() {
$(".one").eq(0).find('td').eq(0).html("I'm tracked");
// get 1st tr and get first td
$(".one").eq(1).find('td').eq(1).html("I'm tracked");
// get 2nd tr and get second td
$(".one").eq(2).find('td').eq(0).html("I'm tracked");
// get 3rd tr and get first td
});
</script>
</body>
</html>
But I guess this approach can be tedious.
Id should be unique and if you use the same id, javascript code refers only the first element. but if you still want to use same id than you may try the below code:
$(function(){
$('[id="total_row"]').each(function(){//run for every element having 'total_row' id
var $this = $(this);
$this.find('td').eq(1).text() //to get second column data
$this.find('td').eq(1).text('dummy text') //to set second column data
});
});
You can use XHTML:
<p id="foo" xml:id="bar">
Through XHTML you can apply similar ID to multiple Controls.
Similar questions can be found here:
http://www.c-sharpcorner.com/Forums/
While duplicate IDs are invalid, they are tolerated and can be worked around. They are really only an issue when using document.getElementById.
I'll guess that the table looks like:
<table id="t0">
<tr>
<td>-<th>count<th>Pass<td>Fail<td>Error<td>
<tr>
<td>-<td>1<td>1<td>0<td>0<td>
<tr>
<td>-<td>1<td>1<td>0<td>0<td>
<tr id='total_row'>
<td>Total<td><td><td><td><td>
<tr>
<td>-<td>1<td>1<td>0<td>0<td>
<tr>
<td>-<td>1<td><td>1<td>0<td>
<tr>
<td>-<td>1<td><td>0<td>1<td>
<tr id='total_row'>
<td>Total<td><td><td><td><td>
</table>
<button onclick="calcTotals();">Calc totals</button>
If that's correct, then a function to add each sub–section can be like:
function calcTotals(){
var table = document.getElementById('t0');
var rows = table.rows;
var row, totals = [0,0,0,0];
// For every row in the table (skipping the header row)
for (var i=1, iLen=rows.length; i<iLen; i++) {
row = rows[i];
// If it's a total row, write the totals and
// reset the totals array
if (row.id == 'total_row') {
for (var j=0, jLen=totals.length; j<jLen; j++) {
row.cells[j+1].innerHTML = totals[j];
totals[j] = 0;
}
// Otherwise, add values to the totals
} else {
for (var k=0, kLen=totals.length; k<kLen; k++) {
totals[k] += parseInt(row.cells[k + 1].innerHTML) || 0;
}
}
}
}
In addition to using classes, which works but feels kind of icky to me, one can also use data-* attributes.
<tr class='total_row' data-val-row-type="totals-row">
<td>Total</td>
<td>%(count)s</td>
<td>%(Pass)s</td>
<td>%(fail)s</td>
<td>%(error)s</td>
<td> </td>
</tr>
Then, in your script (jQuery syntax -- querySelectorAll has a similar syntax)
var $totalsRows = $("[data-val-row-type='totals-row']);
When you are in a team with a separate UI designer, this keeps the UI guy from ripping out and changing your class names to fix the new design layout and it makes it quite clear that you are using this value to identify the row, not just style it.

Remove parent element and keep the content

Suppose I have already get the table with JavaScript like this:
var isert = inn.getElementsByTagName("table");
and I've got a structure like this:
<table width="100%">
<tbody>
<tr>
<td><div class="extra"></div>
</td>
</tr>
<tr>
<td><div class="extra"></div>
</td>
</tr>
<tr>
<td><div class="extra"></div>
</td>
</tr>
</tbody>
</table>
Here, how can I remove the outside Table structure, and keep the content only, so that result of the extracted code should be:
<div class="extra"></div>
<div class="extra"></div>
<div class="extra"></div>
Thanks!
I'd suggest:
function removeTo(from, what) {
if (!from || !what) {
return false;
}
else {
els = from.getElementsByTagName(what);
while (els[0]) {
from.parentNode.insertBefore(els[0],from);
}
from.parentNode.removeChild(from);
}
}
removeTo(document.getElementsByTagName('table')[0], 'div');
JS Fiddle demo.
Incidentally:
var isert = inn.getElementsByTagName("table");
Doesn't give you a reference to the table element, it gives you a nodeList of all the table elements within the inn variable (whatever that might be). To act on a particular table you need to specify which particular table you want to act upon, which is why, above, I've used document.getElementsByTagName('table')[0].

Categories