I try to get a column number of a td by selecting the td by its class name. But it always returns -1. What is wrong?
js fiddle
HTML
<table >
<tbody>
<tr>
<td >apple</td><td class="current">banana</td><td>cherry</td>
</tr>
</tbody>
JS
console.log($("td.current:first").parent().parent().children().index($(this)));
You can use the variant of .index() that does not take any arguments, to get the index based on its sibling elements
console.log($("td.current:first").index());
Demo: Fiddle
Simply do:
console.log($("td").index($("td.current:first")));
As you have it, $(this) is pointing to the window object, and not the scope you think it is, which has not been defined in the context of the call.
Also note that index() works thusly: collection.index(member).
you don't neet to get parent then parent, Simply do this
$("td.current:first").index();
Related
I have a dynamically generated table, with (currently) a set rule that the first column has to be an unique identifier of some sort. The table is generated based on a json file, altought i don't think that's really important here.
Each table row has a anchor tag added with class="delete". when i click that anchor tag, i execute the following code:
e.preventDefault();
var idCell = $(this).closest('tr').find('td')[0];
If i console.log(idCell),i get <td>01</td> in my console.
If i console.log(typeof idCell) i get object.
If i console.log the type of a random element from the DOM, i get object as well.
My issue is: I cannot get the .val() from idCell, while i can access the .val() from any element directly filtered from the DOM.
My primary concern is why this is(n't) happening, and if there is a fix existing for this type of problem, i would be most gratefull if you would share it with me.
EDIT 1:
Here you have an example table.
<table>
<tr>
<th>
id
</th>
<th>
delete
</th>
</tr>
<tr>
<td>
01
</td>
<th>
delete
</th>
</tr>
</table>
please try to get me the ID of the table, when i click on the delete link, preferably using jQuery.
As JJJ and
Daniel A. White mentioned, The solution is:
1) To use .eq(0) instead of [0] to keep the selector a jQuery element.
2) To use .text() instead of .val() since only input fields have values, and table cells don't.
here's the script (works fine by me)
$(".delete").bind("click",function(e) {
e.preventDefault();
var idCell = $(this).closest('tr').find('td');
idCell.html("");
});
I have DOM like this:
<div class="parent">
<button class="add-tr">Add</button>
<table class="child">
<tr data="0"></tr>
<tr data="1"></tr>
...
</table>
</div>
<div class="parent">
<button class="add-tr">Add</button>
<table class="child">
<tr data="0"></tr>
<tr data="1"></tr>
...
</table>
</div>
...
When I click on the Add button, I would like to get the value of the data attribute from the last of it own parent class.
I am using this method to get the last element,but it doesn't work.
$('.add-tr').click( function() {
var last = $(this).parent().find('.child:last').attr('data');
alert(last);
})
Any idea why? Or any other suggestion to get the last element in the table?
UPDATE
Yes, I found the problem, turn out is I forgot the 'tr'. Thanks for your guys answer. All your guys giving the correct answer, I wish I can accept all your answers. Thanks
Try this
var last = $(this).parent().find('.child').find('tr').last().attr('data');
In your example you get last table, but you need get last tr
Example
'.child:last' selector will select the last element having child class. As child class is applied to <table>, this selector will select table element, while you want to select last <tr>.
As there is no data attribute on <table>, .attr('data') on it will return undefined.
To get the value of data attribute on last <tr> use the selector tr:last.
var value = $(this) // Button that is clicked
.parent() // Direct parent element i.e. div.parent
.find('.child tr:last') // Get the last <tr> inside .child
.attr('data'); // Get value of data attribute
As the .child element is next to the button, next() can be used to get the table.child element.
var value = $(this) // Button that is clicked
.next('.child') // Next element i.e. table
.find('tr:last') // Get last <tr>
.attr('data'); // Get value of "data" attribute
I'll recommend to use data-* attribute to store data in custom attribute.
<tr data-num="0">Foo</tr>
<tr data-num="1">Bar</tr>
And to get the value of custom data attribute use data()
.data('num')
If you just want to get the index of the last tr, there is no need to store that on element. You can get the index by using the index().
.index()
This will return index of an element. Note that this is zero-based index which is exactly how you want.
$(".parent").click(function(){
$(this + " tr:last-child").attr("data");
});
should do.
Your code was almost correct, you missed tr:last , i.e.:
var last = $(this).parent().find('.child tr:last').attr('data');
DEMO
http://jsfiddle.net/tuga/vr1knxqq/3/
$('.add-tr').click( function(event) {
var last = $(event.target).next().find("tr").last().attr("data");
alert(last);
})
fiddle-example
You can get an array of the tr elements by using find('.child tr')
and to get the last element in that array you can use last().
Putting it all together you have this:
$('.add-tr').click( function() {
var lastTr = $(this).parent().find('.child tr').last(),
lastData = $(lastTr).attr('data');
alert(lastData);
});
I have setup a codepen here http://codepen.io/anon/pen/aOzmKg to show this working.
I want select first row from any cell so I just wrote javascript like.
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).parents("table tbody tr:first");
alert($(firsttd).text());
And my table is below
<table id="idTable_1" border="1px" width="97%" class="tblDragTable" data-numberofrows="2" data-numberofcolumns="2">
<tbody>
<tr id="trno_10">
<td class="tblCell" id="cellno_100">0</td>
<td class="tblCell" id="cellno_101">0</td>
</tr>
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
</tbody>
</table>
when I use find() it giving me correct result
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).parents("table tbody").find("tr:first");
But I just want to know why the above code return second tr instead of first tr
HERE IS MY JSBIN http://jsbin.com/lisozuvade/1/watch?html,js,output
The reason why it fails is because calling parents with a filter of table tbody tr will only match the immediate parent TR. The other TR falls outside of the ancestors so :first will match the only TR it finds.
If you try this you will see what is going on:
alert($(curcontrol).parents('table tbody tr')[0].outerHTML);
returns this:
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
then try this:
alert($(curcontrol).parents('table tbody')[0].outerHTML);
which returns this:
<tbody>
<tr id="trno_10">
<td class="tblCell" id="cellno_100">0</td>
<td class="tblCell" id="cellno_101">0</td>
</tr>
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
</tbody>
JSFiddle: http://jsfiddle.net/TrueBlueAussie/j28g27m1/
So your first example only looks at the ancestors (one TR) and returns the first match. The second example looks further back up the tree, then finds all TRs in the tbody then chooses the first one.
A preferred, slightly faster, way would be to use closest() and find()
e.g.
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr:first");
or faster yet (as selectors are evaluated right-to-left):
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr").first();
e.g. http://jsfiddle.net/TrueBlueAussie/j28g27m1/1/
You're asking for parents of #cellno_111, only that tr is.
Also keep in mind that :first is like .first() as it filters to the first element in the set of matched elements, it has nothing to do with being the first child of something. If you want multiple elements, which are first children you should use :first-child.
.parents(table tbody tr:first): query the parents of the element for a tr which is inside of table and tbody, then pick the first
.parents("table tbody").find("tr:first"): query the parents of the elements for a tbody which is inside a table, then find all trs inside of it, then pick the first of them
PS: I suggest using closest instead of parents as the go-to DOM navigation method for ancestors; most of the times it's way more practical and easier to understand.
Actually, you need to understand what each selector is doing. Try with several console.log, you'll see:
$(curcontrol).parents();
This return a set of elements. In this set, there is only 1 tr, the parent of your curcontrol td tag.
You can indeed filter this specific set by adding a extra filter :
$(curcontrol).parents("table tbody tr:first");
But as I just explained, the original set only contains a single TR, so the first one returned is actually the only one returned.
Your find() approach is different, you specify a specific (parent) element and with the find() you search trough children, which explains in this case the correct behaviour.
If I'm not mistaken, the parent hierarchy of cellno_111 is:
trno_11 -> tbody -> table
In your first example, the first tr parent cellno_111 finds is trno_11 and not trno_10. It does not have a trno_10 parent.
The reason it does work with find(), is because you select the tbody and then search for the first tr child the tbody has.
<table>
<tr>
<td>me</td>
<td>you</td>
<td>we</td>
</tr>
</table>
Using Jquery i want to know which childrin was clicked and get the number of this childrin. like, if I click you, i want to get 2 and if we, then 3.. if me, then 1.
is there something like .nthchild(); in Jquery?
here is my fiddle to test: http://jsfiddle.net/vfp9x/
Simply use $(this).index(), you also have wrong id for table in live demo, it should be table1
Remember the index is zero based so you will get zero 0 for first element and 1 for second element and so on.
Live Demo
$('#table1').on('click', 'td', function () {
$('#out').text($(this).index()+1);
});
.index()
If no argument is passed to the .index() method, the return value is
an integer indicating the position of the first element within the
jQuery object relative to its sibling elements.
Try,
$('#table1').on('click','td',function(){
var child_number = $(this).closest('tr').find('td').index(this);
$('#out').text(child_number);
});
DEMO
Simply use .index() as per the other answer provider suggested, and also keep this way of getting the index also. it would helpful for you in some other contexts, like getting the index of the current element from a collection of elements (not siblings to each other)
Try Like
$("#ul").on('click', 'td', function () {
debugger;
alert(this.id);
});
Demo
I've been at this for a while and want to know the best way of achieving my goal if anyone has any ideas!
Example:
<table>
<tbody>
<tr>
<td>Hello</td>
<td>Hello (I want to check this column)</td>
</tr>
<tr>
<td>Hello 2</td>
<td class="active">Hello 2 (this column)</td>
</tr>
</tbody>
</table>
jQuery I've got so far (I'm traversing from a clicked element):
var length = $(self).closest("tbody").find("tr").find("td.active").length;
Obviously this gets all the active classes of td, when I only want the second column. I've tried:
var length = $(self).closest("tbody").find("tr").find("td:eq(1).active").length;
This does not work.
Any ideas?
If I'm understanding correctly, you want to get the table cells in the second column (not the first as indicated in the question) which have the class active on them. If that's the case, you can use the following:
var length = $(self).closest('tbody').find('tr').find('td:eq(1)').filter('.active').length;
http://jsfiddle.net/mikemccaughan/g6mnn/
I think your selector isn't doing what you expect it to. I would have expected what you're expecting, but check out this paragraph from the eq() documentation (emphasis mine):
Note that since JavaScript arrays use 0-based indexing, these
selectors reflect that fact. This is why $('.myclass:eq(1)') selects
the second element in the document with the class myclass, rather than
the first. In contrast, :nth-child(n) uses 1-based indexing to conform
to the CSS specification.
So you're going to want to use td:eq(1) without the class selector, then filter your results, and then count them:
var length = $(self).closest("tbody").find("td:eq(1)").filter(".active").length;
Hope that helps!