JQuery find not working for tr element? - javascript

Just wondering if anyone knows why the following code doesn't work (each() is not executed at all)...it works if i try td elements but not tr elements for some reason?
The html is returned by a php script and looks like
<tr class="my_files_row"><td>bla</td><td>bla</td></tr>
function update(html)
{
$(html).find('tr').each(function()
{
alert('success');
})
}
Thanks in advance!

I think your php should return the tr inside other element (a table perhaps). As the JQuery documentation states, find searches on "descendants" of the element, and tr is not a descendant of tr in your html. You can change the response to:
<table> <tr class="my_files_row"><td>bla</td><td>bla</td></tr> </table>
and that should work.

Find only finds descendants. In your case, tr is the root.

If you're interested in all TR elements and not those of a particular table/tbody/thead/tfoot element, then ask the right question (and don't be more complicated than you need to be). This:
$('tr').each(function(){
var tr = $(this) ;
...
}) ;
should do you. If you need to be more specific table, you just to refine your selector:
$('table#mySpecialTable tbody tr')
The above gives you all elements in the of the table with id mySpecialTable.

Related

How to get nested js selectors like td?

I need to get all selector that match the condition so I can iterate thru it later on. My code does not return any values. Probably syntax is wrong so I would appreciate if you help me (haven't written lots in js).
Here is the html
function restore_hp(){
var percent_restore = document.querySelectorAll("table.table.table-condensed.table-top-spacing > tr > td[2]");
percent_restore.forEach((td)=>{
console.log(td.innerText)
});
}
You are probably looking for td:nth-child(2) at the end of your selector.
Your current td[2] would select such a table cell: <td 2="some-attribute-value">...</td>. Notice that this would be invalid HTML because a) 2 is an invalid attribut identifier (cannot start with a number) and b) even if it in general would be valid syntax it wouldn't be known for HTMLTableCellElement, and thus again, invalid HTML.
2nd issue:
> selects direct children only. tr is not a direct child of your table (it never is, missing tbody is auto-inserted by all browsers).
What you want is something called :nth-child pseudo selector. Learn more from the below link-
https://www.w3schools.com/cssref/sel_nth-child.asp
SO your function may be like-
function restore_hp(){
var percent_restore = document.querySelectorAll("table.table.table-condensed.table-top-spacing tr td:nth-child(2)");
percent_restore.forEach((td)=>{
console.log(td.innerText)
});
}
Codepen: https://codepen.io/ashfaq_haq/pen/WNNOYRR
You can add a HTML class to the elements you want to manipulate and simply query on the class :
...
<tr>
<td>Some text</td>
<td class="my-custom-class">Some other text</td>
</tr>
...
var percent_restore = document.querySelectorAll(".my-custom-class");
percent_restore.forEach((td)=>{
console.log(td.innerText)
});
That way you're not lost in your HTML tree.

how to get number of children in html table using jquery

I am not able to understand the behavior of jquery method children. I am able to count the number of <p> in a <div> using :
var abc = $("div").children("p");
alert(abc.length);
But the same thing when applied to <tr> within <table> results in 0 (zero) count.
var abc = $("table").children("tr");
alert(abc.length);
why is it so?
Try this
$("table tr").length;
If you only want to get tr within tbody
$("table tbody tr").length;
children() will return direct children (traverses single level) of <table> but not the grand-child(ie, children's children).
If you wish to search in descendants of an element, use find().
Here is how then you can get the <tr> of <table>:
var trs = $('table').find('tr');
And, to get the count/length
alert($('table').find('tr').length);
No nested table
If there is no nested tables, then
alert($('table').find('tr').length);
or
alert($('table tr').length);
will give you a proper result.
Nested tables
If you are having some nested tables i.e <table> inside a <table>,
Above code won't give you correct result, if you need <tr>s of parent <table>, but not of children <table>.
Here is how then you can get it:
alert($('table>tbody>tr').length);
or
alert($('table').children('tbody').children('tr').length);
Hope it helps.
Here is your answer.
alert($("table tr").length);
Use selector that will select all the rows and take length.
var tableRowCount = $('table tr').length;
This approach also used for get counts all trs of every nested table
Use this
var childrensCount = $('table tr').length;
OR
var childrensCount = $('#tableId tr').length;

JQuery: how to select parent table for parsing

I have JS function which parses through a table:
// id contains a message id, activeRow is "this" from onClick on tr
function doSomething ( id, activeRow ) {
// AJAX calling using id as parameter
$("#searchResultTable > tbody > tr").each(function(index) {
$(this).removeClass("bold");
});
}
This works perfectly fine (thanks to Ariel # other post), but I was thinking that there should be another possibility, like:
var table = $(activeRow).parent();
$("tbody > tr", table).each(function(index) {
// .. do something
});
// The above clearly doesn't work, but should document what I'm looking for.
This would allow the usage of the same table ID while the function would work on each of them separately.
Many, many thanks!
jQuery's parents() method makes getting the parent table a snap:
$(activeRow).parents('table')[0];
What about:
$(activeRow).siblings().andSelf().removeClass("bold")
That'll take the <tr> in activeRow, grab its sibling <tr>s too, and remove the "bold" class from all of them.
It may be better to use closest as follows:
$(activeRow).closest('table')[0];
From here: http://api.jquery.com/closest/
closest: Travels up the DOM tree until it finds a match for the supplied selector.
parents: Travels up the DOM tree to the document's root element, adding each ancestor element to a temporary collection; it then filters that collection based on a selector if one is supplied.
In this scenario it may well be that parents gets the top most table where there are more than one in the DOM tree, where as closest gets the one you are actually trying to work on.
Close, you would want to use a class on the table
$("table.className tbody tr").each(function() {
// .. do something
});

How can I elegantly select a parent including its set of direct descendents?

I'm working with a mess of HTML markup. In order to get reliable matches I have resorted to explicitly querying a chain of elements using the '>' operator.
For this question I am attempting to select the parent of an explicit chain of descendents.
For example, I'd like to select the table element with class 'toolbar' in the following HTML:
<table class='toolbar'>
<tbody>
<tr>
<td class='button'>
...
</td>
</tr>
</tbody>
</table>
Here is what I've tried:
1. Use 'has'
$("table.toolbar:has(tbody > tr > td.button)")
Here elements are matched even if tbody isn't a direct descendent of table so this doesn't reliably work.
2. Use '>' and parent()
$("table.toolbar > tbody > tr > td.button").parent().parent().parent()
This works but is messy. Also have to make sure the correct number of parent() calls are included.
3. ???
Due to the crap HTML, it is critical that elements are explicitly given in the query as one direct descendent beneath another.
Can anyone please help with the nicest way of doing this? Thanks!
$("table.toolbar > tbody > tr > td.button").closest("table.toolbar")
Still a bit messy but should work.
closest(expr) documentation
$("td.button").parents("table.toolbar")
seems the easiest way.
I think:
$("td.button").closest("table.toolbar")
Updated:
you can use:
$("table.toolbar:has(tbody:has(td.button))")

slideToggle table row using Jquery

I have been trying for over a week now to slideToggle a table row when the 'more info' button is clicked but nothing seems to be working at all.
I'm new to Jquery so if anyone ca help me slideToggle the 'more-info-1', 'more-info-2', 'more-info-3' tr tags. the main problem is that those id's are created dynamically through php and I don't understand how to select them in Jquery - like using 'more-info-' or something.
I would like it to work like this example:
Here minus the iframes of course.
The user will click the 'more info' button and then the 'more-info-' tr will slide down.
Here is the page source: (I don't know how to insert HTML properly on Stack OverFlow, is there a special way of doing it - the code button does not work properly with HTML)
html
div id="output-listings"
div class="main-info"
table class="listings"
tbody
tr id="more-info-1" class="mi-1"
td
div id="more-1" class="more-information"/div
/td
/tr
tr id="main-info-1"
tdLeftlane News/td
tdwww.leftlanenews.com//td
tda id="link-1" class="more-info-link" href="#"More info/a/td
/tr
tr id="more-info-2" class="mi-2"
td
div id="more-2" class="more-information"/div
/td
/tr
tr id="main-info-2"
tdMotor Authority/td
tdwww.motorauthority.com/ /td
tda id="link-2" class="more-info-link" href="#"More info/a/td
/tr
tr id="more-info-3" class="mi-3"
td
div id="more-3" class="more-information"/div
/td
/tr
tr id="main-info-3"
tdAutoblog/td
tdhttp://www.autoblog.com//td
tda id="link-3" class="more-info-link" href="#"More info/a/td
/tr
/tbody
/table
/div
/div!--end output-listings--
/html
I would greatly appreciate the help.
Though craig's response works, you can limit your code and allow jquery to grab all of your TR elements within a certain scope, and parsing out the id as he suggested, etc.
$(".listings tbody tr").each(function(index) {
// hide by default
$(this).css({'display': 'none'});
// set the onclicks
$(this).click(function() {
// your dosomething can change your appearance
dosomething(the_id_you_parse_out);
});
});
Not sure if thats working code, I just threw it together so you could get the gist of how to use jquery's selector.
From a quick glance it looks like you want something like this.
$('#link-1').click(function(){
$('#more-info-1').slideToggle()
})
You can also generalize this script to work with all three by changing how the classes are set up, or by having the inner function parse the number of th link that is clicked and feed that into the inner jQuery call:
$('.more-info-link').click(function(){
var id = $(this).attr('id');
var num = id.substr(id.length-1,1);
$('#more-info-'+num).slideToggle();
})
To keep the trs from being visible add style='display:none' to them.
Depending on whether you need to assign a specific id to your elements for another purpose, you can actually do this without needing to give individual id's.
In this example, on load we first hide any tr that have the class toggleable. Then we tell jQuery to jump up the dom a couple of levels, and hide the next tr - this removes the need to call an id.
Example jQuery for this:
$(document).ready(function(){
$("#tableToggle tr.toggleable").hide();
$("#tableToggle .tableToggleButton").click(function(){
$(this).parent().parent().next('tr').slideToggle();
});
});
Example modified table:
<table id="tableToggle">
<tbody>
<tr>
<td><div class="tableToggleButton">More info 1</div></td>
</tr>
<tr class="toggleable">
<td>Main info 1</td>
</tr>
<tr>
<td><div class="tableToggleButton">More info 1</div></td>
</tr>
<tr class="toggleable">
<td>Main info 1</td>
</tr>
</tbody>
</table>
Since jquery code usually executes only when the DOM is ready, you'll always see the TR's even if only for a millisecond until your js code hides it if you don't use CSS initially to hide it.
So most of the contributors here probably answered your question. I'd just like to add that you could initially hide the TR's using CSS and then use JS to do the rest.
A good rule of thumb is to try and get your "default" pageview by only using CSS, and then add the rich functionality with the jquery code. Or at least that's what I'd do.

Categories

Resources