How to search through a table and pull the data? - javascript

I'm new to js, I'm working on a chrome extension and am having confusion webscraping a website. Suppose I have a simple table in an html like this
<html>
<body>
<table class="birthdays">
<tbody><tr>
<th>date</th>
<th>month</th>
<th>year</th>
</tr>
<tr class="r0">
<td>Person</td>
<td>1</td>
<td>Jan</td>
<td>77</td>
<td colspan="3"></td>
</tr>
<tr class="r0">
<td>Person</td>
<td>1</td>
<td>Jan</td>
<td>77</td>
<td colspan="3"></td>
</tr>
</tbody></table>
</body>
</html>
In my chrome extension when I do
const x = document.getElementsByTagName("th")[0][0]
alert(x)
It says it found a th object, but doesn't give me the actual data. That's the first issue, my actual goal is to determine if all elements in the tr tags have the same of one property (ex. if everyone has their birthday in Jan, open a tab).

document.getElementsByTagName
returns HTMLCollection https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
it's an array-like object (not real array)
and you can get the value from it calling item() method https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection/item
Seems that you need something like this document.getElementsByTagName("th").item(0).innerHTML to get content of the first TH tag

This is not a complete answer, but in javascript the container is not its contents - i.e. you need document.getElementsByTagName("th")[0][0].innerHTML to get at the 'date' string.

Related

Using JavaScript variables in a Thymeleaf th:each

I am trying to build a table using th:each and have the whole row of the table clickable as a link through JavaScript.
<table>
<th:block th:each='user : ${list}'>
<script th:inline="javascript">
var userid = [[${user.id}]];
</script>
<tr onclick="location.href='user?id='+userid">
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
</tr>
</th:block>
</table>
However, the variable always refers to the latest value and not the one it was when the row was created. Is there a way to do that? Or maybe a different solution to what I'm trying to do?
No need for the th:block, you can simply put the th:each on the tr.
To accomplish the click, I recommend putting the id in a data attribute, and retrieving it in JavaScript. This should work for you:
<table>
<tr th:each="user : ${list}"
th:data-id="${user.id}"
onclick="location.href = 'user?id='+this.getAttribute('data-id')">
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
</tr>
</table>
You can avoid using JavaScript by adding an <a> element to each table cell (Inspired by https://stackoverflow.com/a/17147909/40064):
<table>
<th:block th:each='user : ${list}'>
<tr>
<td><a th:href="#{/user(id=${userid})}" th:text="${user.firstName}"></a></td>
<td><a th:href="#{/user(id=${userid})}" th:text="${user.lastName}"></a></td>
</tr>
</th:block>
</table>

How to i change the class name inside <td>

<table id="results">
<thead>
<tr>
<td>1st</td>
<td class="horse1"></td>
</tr>
<tr>
<td>1st</td>
<td class="horse2"></td>
</tr>
<tr>
<td>1st</td>
<td class="horse3"></td>
</tr>
</thead>
</table>
i used this way it didnt worked .
document.getElementById("result").className=horseId;
horseId is an variable and contains value
and there are multiple classes insede so how do i select a specific class to change.
You missed two things; first, you attempted to target by ID result, when you need results. Second, you need to wrap the desired class names in quotes. You can use a variable for the assignment, assuming the variable maps to a string.
It's also worth mentioning that your existing class horse1 is several nodes down from your target ID results. I assume this is the element you're trying to change.
To change the class of the #results element, you can use document.getElementById('results').className = horseId;.
To change the class of the .horse1 element, you can use document.getElementsByClassName('horse1').className = horseId;.
Here's an example of the latter:
var horseId = 'rainbow_dash';
document.getElementsByClassName('horse1').className = horseId;
console.log(document.getElementsByClassName('horse1').className);
<table id="results">
<thead>
<tr>
<td>1st</td>
<td class="horse1"></td>
</tr>
</thead>
</table>
Hope this helps! :)
It should be "results"
document.getElementById("results").className=horseId;

DataTables: TypeError: i is undefined

I have a table like the following
the table as rowspans because for some users I need to have 2 lines (Like you see at column 'D')
I am trying to use datatables:
<table class="table table-bordered table-hover table-striped" id="myTable">
(...)
</table>
And I call this at the begining of the code:
<script>
$( document ).ready(function() {
$('#myTable').DataTable();
});
</script>
But I have this error:
TypeError: i is undefined
And the table is not like a datatable type!
Maybe it doesn't work with rowspans?
Any idea??
FWIW you can also get this error if you don't have the same number of <td></td> elements in every row. Make sure you aren't adding any rows with nav buttons or links or anything like that that may not be formatted the same way as the other rows.
jQuery DataTables plug-in doesn't support ROWSPAN attribute by default. However there is a RowsGroup plugin for jQuery DataTables that groups cells together to make them look like as if ROWSPAN attribute is used.
See this example for code and demonstration.
See jQuery DataTables – ROWSPAN in table body TBODY for more details.
For future referer.
It is because you are using Rowspan or colspan which is not supportable.
If you want to use colspan you can use it outside </tbody>.
Thanks.
This problem happens if your table is not well formed, for example you should have
<table>
<thead>
<th>
<tbody>
<tr>
<td>
And then the id of the table should not overlap with id of any thing else on the same page. Other wise you will get errors like i is udefined or c is undefined.
I'd say your table is not a data table because you have undefined data and the 'i' referred to is the internal iterator of the DataTable loop, the use of rowspans is the problem - I would redesign your table to have an entire row for each piece of data (in your example 250 would require an entire row with duplicate values for all other columns except D) - it is wholly possible to use css to hide values that are duplicated for the same visual effect, this would allow datatable filtering to still work on those rows (although you may need some hooks to reveal hidden data when these 'extra' rows are filtered).
I was facing the same issue. The main reason for the error is due to using the colspan & rowspan. Because the jQuery DataTables plug-in does not support them and hence causing the error.
TypeError: i is undefined
So, If you are using any colspan or rowspan within any <tr></tr> inside the <tbody></tbody> then make sure that each <tr></tr> having the same no of <td></td> for each row. If not, then repeat the <td style='display:none'></td> to match the same no e.g
<table border='1' cellspacing='2'>
<thead>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td rowspan="2">name</td>
<td>200</td>
<td style='display:none'></td>
<td style='display:none'></td>
</tr>
<tr>
<td >300</td>
<td style='display:none'></td>
<td style='display:none'></td>
</tr>
</tbody>
</table>
I think by following the above suggestion will help you sure.

Get a specific column in a table

What I want is to get a specific table column using jquery, so far what I have is this, that selects the first column:
table.find(tr > td:first-child)
But I want to be able to select any column so I can copy it to another table, is there a way to do this for example :
td:n-child
so I can send it the number of column and get all the data from that specific column.
Try this:
for instance for selecting the 2nd element, you would:
table.find("tr > td:nth-child(2)");
table.find("tr > td").eq(n);
I just wrote this from the heart, so I can't confirm if it works, but I think this is the syntax to do this.
:eq() Selector : Description: Select the element at index n within the matched set.
You could use :eq() Selector, e.g :
$('tr > td:eq(n)')
Hope this helps.
$('td:eq(2)').css('background-color','green')
$('tr:eq(2) td:eq(0)').css('background-color','red')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border=1>
<tr>
<td>1</td>
<td>A1</td>
<td>B1</td>
</tr>
<tr>
<td>2</td>
<td>A2</td>
<td>B2</td>
</tr>
<tr>
<td>3</td>
<td>A3</td>
<td>B3</td>
</tr>
</table>

Replace text in an element in HTML from another element (table) using jQuery

I want to replace a particular text in an HTML with another text from another element, which in this case is a table data.().
Here is my table:
<table id="hftable">
<tr>
<td id="hfpn1">V.Sehwag</td>
<td id="hfp1">DNB</td>
<td id="hfp1b">.-.-..-.</td>
</tr>
<tr>
<td id="hfpn2">G.Gambhir</td>
<td id="hfp2">DNB</td>
<td id="hfp2b">.-.-..-.</td>
</tr>
<tr>
<td id="hfpn3">A.Arora</td>
<td id="hfp3">DNB</td>
<td id="hfp3b">.-.-..-.</td>
</tr>
</table>
where batsman1 is the id of the element where the replacement is to take place or more specifically the table looks like:
<table id="current">
<tr>
<td id="batsman1">Batsman 1</td>
<td id="currentbat1"></td>
</tr>
<tr>
<td id="batsman2">Batsman 2</td>
<td id="currentbat2"></td>
</tr>
<tr>
<td>Bowler</td>
<td></td>
</tr>
</table>
I want to replace Batsman 1 (in the table with id="current") with V.Sehwag (in the table with id="hftable") (when someone clicks on a specific button on the page)
I have tried:
$("#batsman1").text($("#hfpn1").val());
This isn't working. Apart of showing "V.Sehwag" in place of "Batsman 1", it is showing me a blank space.
Any ideas where I am wrong? What is the correct and easy way to do this?
Thank You.
Try to use .text() in this context, You are invoking .val() function over a non-input element, obviously it wont work. And do remember that, .val() only works on input elements on which user can input something via the UI.
$("#batsman1").text($("#hfpn1").text());
The TD element does not have a value, it has text. Modify your code as follows:
$("#batsman1").text($("#hfpn1").text());
Here's the jsFiddle
Use the below, I hope this will help you out to fix the problem.
$("#batsman1").html($("#hfpn1").text());

Categories