Changing hidden to visible state of Table > TR on click - javascript

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");
});
});

Related

ScrollTo fires too early resulting in not scrolling all the way

I am making an Angular application which shows a table with a single tr. This row contains multiple td's which contain data. the table is built up like this:
<div class="col" id="TableCol">
<table id="Table">
<tbody>
<tr>
<td *ngFor="let item of items;">
<div
(click)="ItemSelected(item)"
draggable="true"
[class.selected]="item.id == selecteditem?.id"
(dragstart)="dragStart($event, item)"
(drop)="dropItem($event, item)"
(dragover)="dragoverItem($event, item)">
{{item.description}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
The table is scrollable when it overflows its X value
#TableCol{ overflow-x: scroll; }
Now i have a function which adds a td at the right side of this tr.
When this function is called an extra td shows up into my table and scrolling works fine.
The thing I want to achieve is that the table automatically scrolls all the way to the right when I add a new td.
I've tried to call this function right AFTER I've added the new item to the items array.
this.items.push(item);
scrollRight() {
document.querySelector('#mapLocationTableCol').scrollLeft = 10000;}
and
scrollRight() {
document.querySelector('#mapLocationTableCol').scrollTo(10000, 0);}
Both these give the same result:
They scroll my row all the way to the right except for the last element.
I think this is due to the scrollRight() being called before the table is redrawn.
Anyone have a solution to make it scroll after the table is drawn?
edit: I've made a stackblitz example:
https://stackblitz.com/edit/angular-d6lm6k
You should monitor the creation of the table cell with ViewChildren and the QueryList.changes event. In the markup, set a template reference variable on the td elements:
<td #cells *ngFor="let item of items;">
In the code, use ViewChildren to get the list of these elements, and subscribe to the QueryList.changes event in ngAfterViewInit. If a new cell was added, do the scrolling. In the code below, I set a flag to make sure that automatic scrolling is performed only when desired.
#ViewChildren("cells") cells: QueryList<ElementRef>;
private shouldScrollRight = false;
...
addItem() {
this.shouldScrollRight = true;
this.items.push(item);
}
ngAfterViewInit() {
this.cells.changes.subscribe((cellList) => {
if (this.shouldScrollRight) {
this.shouldScrollRight = false;
this.scrollRight();
}
});
}
See this stackblitz for a demo.

Toggle hidden columns data in a row

I have two hidden columns in my html table (I've tried to use hidden rows and the toggling worked great, but it messed up my rows count)
I want to toggle the hidden columns data in a row below the row that is shown.
My current state is that it's indeed toggling, but it covers the next row in the table.
Is there a way to create a temporary new row that will be placed below the clicked row that will toggle the hidden column data without hiding the next row?
Any help will be appreciated :)
This is my table which is being populated by PHP script:
if($SELECT != false)
{
while($rows = mysqli_fetch_array($SELECT))
{
echo "
<tr>
<td><label><input type=\"checkbox\" name=\"lead\" value=\"".$rows["email"]."\" /></label></td>
<td>".$rows["createdTime"]."</td>
<td>".$rows["firstName"]."</td>
<td>".$rows["lastName"]."</td>
<td>".$rows["email"]."</td>
<td>".$rows["phoneNumber"]."</td>
<td>".$rows["country"]."</td>
<td>".$rows["ip"]."</td>
<td>".$rows["affiliate"]."</td>
<td>".$rows["description"]."</td>
<td>".$rows["broker"]."</td>
<td>".$rows["status"]."<br> <br>
Comment:<b> ".$rows["comment"]."</b></td>
<td>".$rows["ftd"]."</td>
<td colspan=\"13\">
Transaction Id: ".$rows["transaction_id"]."
<br>
<br>
Balance: ".$rows["balance"]."
</td>
";
}
}
This is my toggle function:
$(function() {
$("tr").find("td[colspan=13]").hide();
$("table").click(function(event) {
if($(event.target).is('input')){
return;
}
else{
var $target = $(event.target);
$target.closest("tr").next().find("td").slideToggle(-2000);
}
});
});
First solution :
Why dont you just make a hidden row (after each visible row) with the columns that you want to display.And make it visible after you hover the first row?
Second solution :
Place the hidden data in a div and the displayed data in a div. Let both be childs of the td element. The tr height will scale if the hidden div gets displayed.

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.

Toggle table rows with jquery

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).

What's the smartest way to select specific table elements in javascript?

I've got a table with hidden rows on it, like such
-visible-
-invisible-
-visible-
-invisible-
When I click on a table row, I want it to show the invisible row. Currently I have that using this function:
var grid = $('#BillabilityResults');
$(".tbl tr:has(td)").click(
function () {
$(grid.rows[$(this).index()+1]).toggle();
}
However, this table also hides the visible rows if I click on one of the (now visible) hidden rows.
I'd like the click function to only work on the specific visible rows. Currently all my invisible rows have the class "even" so I figured I could limit the click based on that. However, I can't seem to find the syntax to explain that to my function. How would I go about doing that? And, more importantly, is there a better way to approach this?
Use next:
$(".tbl tr:has(td)").click(
function () {
$(this).next().toggle();
}
);
And also if you have specific selector for odd or even:
$(".tbl tr.odd").click(
function () {
$(this).next().toggle();
}
);
But I think that the major help with my answer is to use next() that get you the next row, instead of the index process that you were doing.
var grid = $('#BillabilityResults');
$(".tbl tr:visible").click(
function () {
$(this).next('tr').toggle();
});
Use the NOT function to disregard the EVEN tr elements:
http://jsfiddle.net/7AHmh/
<table class="tbl">
<tr><td>one</td></tr>
<tr class="even" style="display:none"><td>two</td></tr>
<tr><td>three</td></tr>
<tr class="even" style="display:none"><td>four</td></tr>
</table>​
$(".tbl tr:has(td)").not("tr.even").click(function() {
alert("Click triggered.");
$(this).next("tr").show();
});
I guess you could check for even/odd rows with the modulus operator before calling your toggling code:
function() { // your anonymous function
if (rowNumber % 2 == 0) { // only even rows get through here
// toggle code here
}
}
I hope it helps.

Categories