Jquery clone a table with specific row class - javascript

Hey how can I clone the table named teamselectiontable with just the table rows that have the class "chosen", and modify another table and replace its contents with the table rows found. But keeping the class names of "row" in the appended table.
<table id="teamselectiontable">
<tr class="chosen">content</tr>
<tr class="something">content</tr>
<tr class="something">content</tr>
<tr class="something">content</tr>
<tr class="something">content</tr>
<tr class="chosen">content</tr>
<tr class="chosen">content</tr>
</table>
To a table like below.
<table id="talentselection">
<tr class="row"></tr>
<tr class="row"></tr>
<tr class="row"></tr>
</table>
Thanks for any help.

$(".chosen").clone().attr("class","row").appendTo("#talentselection")
or if you want to replace the whole contents of the target table
$("#talentselection").html($(".chosen").clone().attr("class","row"));
Please note you need tds in your table markup for this to work
<tr><td class="chosen">content</td></tr>

Assuming I've understood what you're trying to do, you can use the clone method to clone the selected elements, and the appendTo method to append the clones into another element:
$("#teamselectiontable .chosen").clone().appendTo("#talentselection");
The elements in the original selection will be unaffected. Note that in its current form the above code will not clone any events bound to the matched elements. If you wanted to clone the elements with their events, just pass true into the clone method.
Update (see comments)
To change the class name on the cloned elements, you can use the removeClass and addClass methods:
$("#teamselectiontable .chosen")
.clone()
.appendTo("#talentselection")
.removeClass("chosen")
.addClass("row");

Related

Apply selector to elements that have already been selected

I feel like I am asking something really dumb but perhaps it's not my day. If I have a selected element already, e.g:
let tables = $('table');
But now I want to apply another selector like .some-class on top of those tables, but without creating a new jQuery object like this
$('table.some-class')
How would I do it?
You need to use .filter() to adding filter to variable selector.
let tables = $('table');
tables = tables.filter('.some-class');
tables.css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>table</td>
</tr>
</table>
<table class="some-class">
<tr>
<td>table has .some-class</td>
</tr>
</table>
With the following code you would find all elements with class .some-class under the elements with tag name table.
let tables = $('table').find('.some-class');
Of course, it is just for the example, otherwise you can simply do:
let tables = $('table .some-class');
In your question it is not clear if you want children elements or just filter the elements. If you want the tables with a given class, you would do:
let tables = $('table').filter('.some-class');

Jquery :first selector give second element instead of first

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.

prepend a row to a table but after two tr's

I am prepending a row to a table. However, my table has couple of TR's on the top which act has column names etc. When I prepend a new row I want to prepend it AFTER those two TR's. Is this doable?
I am prepending the new row like this:
var newrow = "<tr><td>...</tr></td>";
var grid = $('mygrid');
grid.prepend(newrow); I want this prepend to be after two TR's of the grid
Why not wrap your headers inside a <thead> and the table body inside a <tbody> then you can add the row as the first element inside the <tbody>. This would keep your jQuery simple, and your HTML more semantically correct as well.
You can use the nth-of-type selector to find the second row of myGrid, then jQuery's insertAfter() function to add the new row after the second row in the table:
$('#mygrid tr:nth-of-type(2)').insertAfter(newRow);
$(newrow).insertAfter("tr:nth-child(2)",grid); //assuming grid is the table
Anthony,
Why not use thead and tbody tags to separate out your table head and table body. Then you can prepend the rows to the children of tbody. See the following.
<table>
<thead>
<tr><th>aaa</th><th>bbb</th></tr>
<tr><th>xxx</th><th>yyy</th></tr>
</thead>
<tbody>
<tr><td>stuff</td><td>things</td></tr>
<tr><td>stuff</td><td>things</td></tr>
</tbody>
<tfoot>
</tfoot>
<table>
Regards,
Peter

Show/hide table row if a child DIV is empty

I have a table with multiple entries. After each entry table row is an edit table row, with a column spanned cell, inside of which is a DIV which HTML is dynamically loaded into. The problem is that having all these empty table rows causes a lot of extra whitespace to appear on the page when it's rendered.
I understand I can't dynamically load HTML directly into the cell, so I have a DIV in it which I load the content into.
I want to hide any table row while the child DIV in it is empty, and show that table row once information has been dynamically loaded into the child DIV. This dynamically loaded information can also removed so I need it to be hidden again once it's empty again.
<table width="100%">
<tbody>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr style="display: none;">
<td colspan="3"><div></div></td>
</tr>
</tbody>
</table>
$("tr").each(function() {
if (this.children().filter(":empty").length) {
this.hide();
} else {
this.show();
}
});
The div isn't a child, it's a grandchild, thus children() won't find the divs. Use the context or find instead.
You are operating hide and show on the DOM element, not the jQuery element. You need to wrap it in jQuery first.
Therefore, run this code everytime you load something:
//find empty divs and hide it's tr
$("div:empty").closest('tr').hide();
//find non-empty divs and show it's tr
$("div:not(:empty)").closest('tr').show();
And look ma! No loops! No each! :D
You should use $(this) instead of this.
Reason being: $(this) is a JQuery object, which allows you to call JQuery methods like .children() and .filter(":empty") on it, whereas this is only a Javascript object...

How to display two tr's with its id in the same row by its id

I have a table with its tr tags. I want to display two tr tags side by side by its class. How can i able to do that using jquery.
<table>
<tr class='1'>
<td>First</td>
</tr>
<tr class='1'>
<td>second</td>
</tr>
<tr class='2'>
<td>third</td>
</tr>
<tr class='3'>
<td>fourth</td>
</tr>
<tr class='3'>
<td>fifth</td>
</tr>
</table>
Then in the output i want to display
First Second
Third
Fourth Fifth
I want to set those dynamically how can i do that using jquery or javascript. I want to use the class declared for the tr tag. I know want to use <td> tag for that.
Any help is appreciated
Here's the first way that came to mind:
var $tds = $("td"); // get all the tds
[].reverse.call($tds); // reverse the order so we can easily loop backwards
$tds.each(function() {
var $parentRow = $(this).parent(),
// find the first row with the same class that isn't this row
$firstTrSameClass = $("tr").filter("." +$parentRow.attr("class"))
.not($parentRow).first();
if ($firstTrSameClass.length > 0) { // if there is such a row
$firstTrSameClass.append(this); // move the td
$parentRow.remove(); // delete the original row
}
});
Demo: http://jsfiddle.net/pgcdq/
I can't really see a use case here but I guess the eaisiest would be to create new rows and move cells to them. You will find information on moving elements here:
How to move an element into another element?

Categories