Toggle table rows with jquery - javascript

I have a normal html table.
Each <tr> has attributes data-id and data-parent-id.
I want to toggle underlying <tr> when I click on a <tr>.
I have made a short bad solution:
$("tr[data-id]").click(function () {
var id = $(this).attr("data-id"); // get id from clicked tr
$(this).siblings('tr[data-parent-id="' + id + '"]').each(function () { // iterate through all tr under clicked tr
$(this).toggle(); // toggle first level under clicked tr
var id = $(this).attr("data-id"); // get id from first level under clicked tr
$(this).siblings('tr[data-parent-id="' + id + '"]').each(function () { // iterate through all tr under first level under clicked tr
$(this).toggle(); // toggle _second level_ under clicked tr
var id = $(this).attr("data-id"); // get id from _second_ level under clicked tr
$(this).siblings('tr[data-parent-id="' + id + '"]').each(function () { // iterate through all tr under second level under clicked tr
$(this).toggle(); // toggle _third_ level under clicked tr
});
});
});
});
In my example I loop through each level but I don't know how to make a "never ending" traversing. I have specified only 3 levels of <tr> but it should be limitless.
It seems that http://ludo.cubicphuse.nl/jquery-treetable/ does what I want but I think it could be done much simpler and when I have a huge table I think it's better to hide the collapsed table rows with css instead of waiting for the javascript to do this (it flickers because of the loading).
How can I make a loop that checks for every <tr> if any other <tr> has its data-id as data-parent-id?
Edit:
Html
<table>
<tbody>
<tr data-id="1" data-parent-id=""></tr>
<tr data-id="2" data-parent-id="1"></tr>
<tr data-id="3" data-parent-id="1"></tr>
<tr data-id="4" data-parent-id="3"></tr>
<tr data-id="5" data-parent-id="4"></tr>
</tbody>
</table>

You need recursivity :
$("tr[data-id]").click(function () {
Expand($(this).attr("data-id"));
}
function Expand(id)
{
$('tr[data-parent-id="' + id + '"]').each(function () {
$(this).toggle();
Expand($(this).attr("data-id"));
});
}
You got to be carefull with recursivity cause it may create and endless loop. In this case it will stop when it will reach a tr that as no data-parent-id (the root).

Related

Changing hidden to visible state of Table > TR on click

I've a table with almost 100 rows, I'm displaying 20 as default by adding a class to the tr as visible and hiding the rest of rows by the class hidden
<tbody>
<tr class="visible"></tr>
<tr class="visible"></tr>
<tr class="hidden"></tr>
<tr class="hidden"></tr>
<tr class="hidden"></tr>
</tbody>
I've added an Add More button to display 5 rows each time the button is clicked but my jQuery logic is completely wrong, Have a look at it
$(".more-show").click(function (e) {
e.preventDefault();
for (var i = 0; i<5; i++) {
$('#ranking-table tr').each(function(i) {
$(this).removeClass("hidden").addClass("visible");
});
}
});
PROBLEM
Instead of displaying 5 rows each time upon click and it has to be the very first 5 hidden rows, It's displaying all the rows by changing the class to visible
You could use the selector $('#ranking-table tr.hidden:lt(5)') to select the first 5 tr elements with class .hidden. It makes use of :lt(5).
Example Here
$(".more-show").click(function (e) {
e.preventDefault();
$('#ranking-table tr.hidden:lt(5)').each(function(i) {
$(this).removeClass("hidden").addClass("visible");
});
});

Hide parent thead if ALL tr in tbody are hidden display:none

I need your help:
The problem:
I have a select filter for my table.
The filter hides the tr rows of the tbody if the value is not the same. The table-header still show.
The question:
If the select filter hides (display:none; ?) ALL tr of the tbody, the thead should also hide.
The Code:
$(document).ready(function(){
$("select[name='kurs']").click(function() {
$('tbody').each(function(){
if ($(this).find("tr:hidden")) {
$(this).closest(thead).hide();
}
});
});
});
This will also do :
$(this).parent().find("thead").hide();
Sample code :
function hide() {
$('tbody').each(function(){
if($(this).not("tr:hidden").length=1)
{
$(this).parent().find("thead").hide();
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Table
<table border='1'>
<thead>
<tr><td>H1</td><td>H2</td></tr>
</thead>
<tbody>
<tr style='display:none'><td>a</td><td>b</td></tr>
<tr style='display:none'><td>a</td><td>b</td></tr>
<tr style='display:none'><td>a</td><td>b</td></tr>
<tr style='display:none'><td>a</td><td>b</td></tr>
</tbody>
</table>
<button onClick='hide()'>Hide</button>
How about
$('tbody').each(function(){
if ($(this).has("> tr:visible").length === 0){
$(this).closest('table').hide();
}
});
It checks for visible trs in the tbody, if there isn't any the table is hidden.
Check this fiddle and see if that's what you want.
When the select changes, it filters the rows. I've done something that might or might not be as the filtering method you may have. The important thing is the part that closes the thead when there's no rows.
$("#filter").change(function () {// Select changes and filters rows of the different tables.
var class_to_filter = "." + $(this).val();// I'm accessing rows by class in order to close them, you may access them using some other method.
$.each($(class_to_filter), function (i, item) {// For each one of them, close and check if you have to close thead as well.
var $tr = $(item).closest('tr'),
$tbody = $tr.closest('tbody'),
$thead = $tbody.siblings('thead'),
numOfVisibleRows;
$tr.hide();// Hide row.
numOfVisibleRows = $('tr:visible', $tbody).length;// Number of sibling rows visible.
if (!numOfVisibleRows) {// if 0, hide thead.
$thead.hide();
}
});
});
Hope it helps.

Fade out Columns in HTML-Table with jQuery: Why is .fadeTo() so slow?

I want to fade out all cells in a column of my HTML-table when I click on a button in the Header of this col. For that I run the following JavaScript:
...
myDOMElement.find(".headerIcon").bind("click", function(event){
var colo = $(event.target).parent().attr("id"); // colNo is stored as Icons id
myDOMElement.find(".myTable").find("tr").find("#"+colo) // each tr has an id according to its colNumber
.each(function(index) {
$(this).fadeTo(0,0.2);
}
});
});
This works as desired but is relative slow even on tables with only 200 rows.
Is there a better (faster) way to do this?
"#"+colo is (must be!) a unique id. No reason for the cascaded finds - and if not, you are facing other problems:
...
myDOMElement.find(".headerIcon").bind("click", function(event){
var colo = $(event.target).parent().attr("id"); // colNo is stored as Icons id
$("#"+colo).fadeTo(0,0.2);
});
});
[edit]
As per the comments, in order to fade out Columns, the id must better hold information about row and column and will thus be unique per cell:
<tr>
<td id="1.1">scheme is <col>.<row></td>
<td id="2.1">
...
<tr>
<td id="1.2">
<td id="2.2">
...
...
myDOMElement.find(".headerIcon").bind("click", function(event){
var roco= $(event.target).parent().attr("id");
var col = roco.split('.')[0];
var row = roco.split('.')[1];
// now search all TD#s which have the clicked col (1.~) as a beginning of their ID
myDOMElement.find("td[id^='" + col + ".']").each(function(index) {
this.fadeTo(0,0.2);
});
});
see also jQuery Attribute selector
Since I dont need the animation provided by .fadeOut() I fond a faster way to do this:
myDOMElement.find(".myTable").find("tr").find("#"+colo).css({opacity:0.2});

Trying to remove a child html element with javascript

I have 3 tables in my boostrap tab. Each tab as a table. The rows of this table is dynamically generated with csharp asp.net code. Right I Want a scenario were if a user click on the row of the first table, the clicked role of the first table get remove from the first table and is added to the rows of the second table.
My challenge as been getting to remove the row after the onClick process.
<tbody>
<tr id="kayode#yahoo.com">
<td> kayode <a class="chat" connectionid="135976e6-799b-4cda-a764-a00f7110d515"
data-parentid="kayode#yahoo.com"
href="/Visitor/StartChat?threadid=3&email=kayode%40yahoo.com"
operatorid="1" target="_blank" threadid="3">chat</a></td>
<td>271.0.0.1</td>
<td>Active</td>
<td></td>
<td>9/13/2014</td>
<td>04:15:18</td>
<td>02:52:55</td>
<td>271.0.0.1</td>
</tr>
</tbody>
My javascript code which I am trying to use to remove the row after the Click event.
function updateWaitingState(sender) {
var parentid = $(sender).attr("data-parentid");
//alert(parentid);
//we are going to remove the role from this field
var element = document.getElementById(parentid);
element.parentNode.removeChild(element); //This line is a problem says
//document.querySelector("tablebody4 first").appendChild(element);
console.log(element);
}
This is untested, but I imagine jQuery will greatly reduce your headache here:
function updateWaitingState(sender) {
var parentId = $(sender).attr("data-parentid");
$('#' + parentId).appendTo('.tablebody4:first');
}
You may need to adjust the selector in the appendTo function, as it was a guess on my part.
function updateWaitingState(sender) {
var parentid = $(sender).attr("data-parentid");
var element = document.getElementById(parentid);
$(element).appendTo('.tablebody2:first');
}

Highlight table rows on hover containing same info with JS or jQ

My boss told me to build a table with rows that highlight and if -for example- the text or number is the same as the text or number on another row's column-two, that will also highlight.
I know I can give each row a class value and make any object with the same class highlight but my boss requires it to highlight depending on the text or number of a certain column.
This is my jsFIDDLE example.
If you look at column-two of each row, you'll see that the value for row-one and three are the same, so if I was to hover over row-three, it should along with row-one highlight and vise versa.
<table>
<tr>
<td>01/12/13</td>
<td>1234567</td>
<td>Lorem</td>
</tr>
<tr>
<td>02/12/13</td>
<td>7654321</td>
<td>Ipsum</td>
</tr>
<tr>
<td>02/01/14</td>
<td>1234567</td>
<td>Dolor</td>
</tr>
</table>
How can I write a script which allows this to happen without using classes?
// Mouse over event handler
$('table').on('mouseover', 'td', function() {
// Store the hovered cell's text in a variable
var textToMatch = $(this).text();
// Loop through every `td` element
$('td').each(function() {
// Pull selected `td` element's text
var text = $(this).text();
// Compare this with initial text and add matching class if it matches
if (textToMatch === text)
$(this).parent().addClass('matching');
});
});
// Mouse out event handler
// This simply removes the matching styling
$('table').on('mouseout', 'td', function() {
$('.matching').removeClass('matching');
});
JSFiddle demo.
Note that I've modified your CSS slightly to add:
tr:hover, tr.hover, tr.matching {
background: #E5E5E5;
}
Fiddle : http://jsfiddle.net/JLubs/4/
JS :
$(document).ready(function(){
$('table tr td:nth-child(2)').each(function(){
$index = $(this).parent().index() ;
var atext = $(this).html();
$('table tr td:nth-child(2):contains('+atext+')').not(this).parent().attr('match', $index );
});
$('[match]').on('mouseover', function(){
$matchInde = $(this).attr('match');
//alert($matchInde);
$('table tr:eq('+parseInt($matchInde)+')').addClass('highlight');
}).on('mouseout', function(){
$matchInde = $(this).attr('match');
$('table tr:eq('+parseInt($matchInde)+')').removeClass('highlight');
});
});

Categories