jQuery: skipping first table row - javascript

This is the HTML:
<table id="tblTestAttributes">
<thead>
<tr> <th>Head 1</th> <th>Head 2</th> </tr>
</thead>
<tbody>
<tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
<tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
<tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
</tbody>
</table>
This is the javascript to get the values of each row:
var frequencies = [];
if ($('#tblTestAttributes').length) {
$('#tblTestAttributes tr').each(function () {
var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
alert(t);
frequencies.push(t);
});
}
I want to avoid the first row, which contains th elements which are just display headers and don't contain any data.
So I changed the selector to this:
#tblTestAttributes tr:not(:first-child)
This is skipping the second tr as well. What is happening here?

Simple you can use below code
$('#tblTestAttributes tr:not(:has(th))').each(function () {

In terms of performance, using .find() will be better than resolving the selector with Sizzle.
$('#tblTestAttributes').find('tbody').find('tr').each(function () { ... });
Here's the jsPerf to show it.

use
#tblTestAttributes tr:gt(0)
or
#tblTestAttributes tbody tr
I would recommend the 2nd, because it may take advantage of querySelectorAll and should be the fastes solution.
your approach didn't work as expected, because the 2nd tr is also a first-child(of tbody)

Use tr + tr selector, which gets all tr that appear after another tr, so the first one is skipped.
Also no need to check if table exists, as in that case $.each wouldn't even get executed.
var frequencies = [];
$('#tblTestAttributes tr + tr').each(function () {
var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
alert(t);
frequencies.push(t);
});
After your edit:
Simply select only all tr inside tbody:
$('#tblTestAttributes tbody tr').each(function(){
...
}

It happens because the second row is, in fact, the first child of the tbody just like the first row is the first child of the thead.
To only take the elements you need, I'd suggest something nearer from your need :
#tblTestAttributes tr:has(td)
Don't forget to get rid of those duplicate txtDesc id, this is illegal in HTML, use a class instead.

Related

How to get the <tr> of a clicked element in a table

I have a table with several <tr>s and each one has several <td>s. The content of these columns can be another html element (for example a textbox) or just text.
My question: how I can get the rest of the siblings of one clicked element inside this column? I mean, how I can know to which <tr> this element belongs, to <tr> #3 or <tr> #5?I don't have a index per <tr> to control
Example:
If I click the textbox of column #1 in row #5, I want that the content of column #2 in row #5 change. I don't know how to do it because my <tr> doesn't have an index.
Using jQuery, add this to the event handler. This will provide you with a collection of table cells:
var columns = $(this).closest('tr').children();
// .eq() is 0-based, so this would retrieve the fourth column
columns.eq(3);
You can find the index of a row using the index() function.
$('input').click(function(){
var index = $(this).parents('tr').index();
alert('you click an input on row #' + index);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="text"></td>
<td></td>
</tr>
<tr>
<td><input type="text"></td>
<td></td>
</tr>
<tr>
<td><input type="text"></td>
<td></td>
</tr>
</table>
Use closest to get the parent TR element.
$('your_element').click(function(){
var tr = $(this).closest('tr');
var element1 = $(tr).find('element_to_find');
});
You can also use the :eq operator to find the td.
$('your_element').click(function() {
var tr = $(this).closest('tr');
var col3 = $("td:eq(2)", tr);
}

get the content of one column of each row in the table and then loop on each content

I have a table structure like this (refer below)
<table>
<thead>
<tr><th>id</th><th>name</th><th>address</th></tr>
</thead>
<tbody>
<tr rowid="1">
<td class="columnid">1</td><td class="columnname">name 1</td><td class="columnaddress">address 1</td>
</tr>
<tr rowid="2">
<td class="columnid">2</td><td class="columnname">name 2</td><td class="columnaddress">address 2</td>
</tr>
<tr rowid="3">
<td class="columnid">3</td><td class="columnname">name 3</td><td class="columnaddress">address 3</td>
</tr>
</tbody>
</table>
Now, I want to get the content from each table row that has attr('columnid') and loop each of it. So the code structure would look like this (refer below)
//We have 3 row, get all present rowid (1,2,3)
//count all the row that has rowid attribute
var rowcount = attr('rowid').length();
var i;
for (i = 0; i < rowcount; i++) //I dont know how to make it but assume in this for statement, I have stored the content from each rowid attribute {
//alert each rowid here
}
how to make it? any help, suggestions, recommendations, ideas, clues would be greatly appreciated. Thank you.
You can use tr[rowid] which will find all tr elements with rowid attribute, then use .has() to filter out trs which do not have td with class columnid like
$('tr[rowid]').has('td.columnid').each(function(){
alert($(this).attr('rowid'))
});
Demo: Fiddle
This code will scan all the td's with class columnidand alert the rowid of the row containing it. I hope this is what you want you code to do.
$("tr td.columnid").each(function(){
alert($(this).parent().attr("rowid"));
});
Fiddle

an easy way to get all the table rows from a table without using a loop

Is there an easy way to get all the table rows from a table without using a loop.
I thought that this would work but it only alerts the first row.
http://jsfiddle.net/THPWy/
$(document).ready(function () {
var O = $('#mainTable').find('tr');
//var O = $('#mainTable tr');
alert(O.html());
//alerts <th>Month</th><th>Savings</th>
});
<table id ="mainTable" border="1">
<caption>Monthly savings</caption>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$50</td>
</tr>
<tr>
<td>March</td>
<td>$50</td>
</tr>
<tr>
<td>a</td>
<td>$50</td>
</tr>
<tr>
<td>m</td>
<td>$50</td>
</tr>
<tr>
<td>j</td>
<td>$50</td>
</tr>
<tr>
<td>july</td>
<td>$50</td>
</tr>
<tr>
<td>aug</td>
<td>$50</td>
</tr>
<tr>
<td>sep</td>
<td>$50</td>
</tr>
</table>
Whatever you use will be iterating through each row to get the inner HTML out of it. So no, you cannot do it without a loop.
Here is an alternate method that gets the message in one line if that's what you're after, it's slightly less efficient than going with a loop though as it needs to make a new array.
jsFiddle
$(document).ready(function () {
var rows = $('#mainTable tr');
var message = $.map(rows, function (v) {
return v.innerHTML;
}).join('\n');
alert(message);
});
I would recommend just doing it in a regular loop.
FYI .html() only alerts the first row because that's what it was designed to do as that is what would be most useful.
Description: Get the HTML contents of the first element in the set of matched elements.
What about:
// get all tr (excluding the caption)
var O = $('table#mainTable').children().slice(1);
http://jsfiddle.net/THPWy/7/
What you have in your code already retrieves all table rows as an array of jQuery elements:
var trs = $('#mainTable').find('tr');
If you want to print the html contents of each row then you would have to use a loop:
trs.each(function (index, element) {
alert($(this).html());
});
You can get by using
gt(), lt(),eq()
.gt(index) // will get all the rows greater than specified index
.lt(index) // will get all the rows less than specified index
.eq(index) // will get all the rows equal to specified index
For Example
$('#mainTable tr').eq(1) will give second row
But when you want to know all the table rows data then go with Konstantin D - Infragistics solution

How get the second td innerHTML

Scenario:
I'm using datatable library to display alot of information. That table have the following rows:
Id Type Name Case
What I'm looking for is that when I click the second row Type, that value will be taking and pasted in a textbox
Example
Id Type Name Case
1 text Juan 20001
3 List Pedro 20005
If I click the row that has the id # 1, I need to take the Type innerHTML. Does not matter what apart of the row I click just take the second td's html.
I tried with this code:
$("tr td").click(function () {
alert($(this).html());
})
It worked great, But the problem is that the user have to click exactly the row Name, but would be better if user can click over any of the row and just take the second rows html.
Suggesstions?
myRow.getElementsByClassName('td')[1].innerHTML
should get you the innerHTML of the second table cell of myRow as long as the first table cell does not contain a nested table.
You might try adding the click handler to the rows instead of to the cells too.
Try using eq()
but would be better if user can click over any of the row and just
take the second rows html.
$("tr td").click(function () {
secondrow = $(this).closest('tr').siblings().eq(1);
});
If i click the row that has the id # 1, i need to take the Type
innerHTML. Does not matter what apart of the row i click just take the
second td's html.
$("tr td").click(function () {
secondTd = $(this).siblings().eq(1);
alert(secondTd.html());
});
Try this
$(function () {
$("#thetable tr").click(function () {
if ($(this).index() == 0) return;
$('#tbox').val($('td:nth-child(2)', $(this)).html())
})
});
HTML
<table border="1" cellpadding="4" id="thetable">
<tr>
<td>Id</td>
<td>Type</td>
<td>Three</td>
<td>Four</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
</tr>
</table><br />
<input type="text" name="tbox" id="tbox" />
It method takes into account the first row that contains only labels and doesn't set the textbox value to a label if top row is clicked.

Hide a `tr` based on the values of `td` in the table using jQuery

I have table that is filled with dynamic content from a query from a database on the backend. I want to hide any tr that contains only zeros.
Here is what my table looks like:
<table id="table1" " cellspacing="0" style="width: 800px">
<thead id="tablehead">
</thead>
<tbody id="tabledata">
<tr class="odd">
<td>0</td>
<td>0</td>
<td>0</td>
<td>0.00%</td>
<td>0.00%</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
<td>$0.00</td>
</tr>
</tbody>
Now if the first three td's in tbody are == 0 then I would like to add a class to the tr that will effectively hide that row. How would I go about doing this using jQuery?
EDIT:
Sorry forgot to add what I have tried. The following is a test script I tried to see if I could collect all the td's
$(document).ready(function() {
$("#table1 td").filter(function() {
return $(this).text == 0;
}).css("text-color", "red");
});
You can do this :
$('tr').each(function(){
var tr = $(this);
if (tr.find('td:eq(0)').text()=="0"
&& tr.find('td:eq(1)').text()=="0"
&& tr.find('td:eq(2)').text()=="0"
) tr.addClass('hidden');
});
Demonstration (the hidden class changes the color to red, it's clearer...)
Depending on your need, you might have to trim the texts, or to parse them.
For more complex tests, you might find useful to work directly with an array of the cell contents. You can get it using
var celltexts = tr.find('td').map(function(){return $(this).text()}).toArray();

Categories

Resources