Dynamically hiding table rows with jQuery - javascript

I am trying to alternate background colors of table rows, each section starting with the same color. I have achieved this with the following code:
$(document).ready(function(){ $("tbody tr.row:nth-child(even)").css("background", "#efefef"); });
I also need to be able to limit the number of rows (5 for example) that are visible inside each tbody section. These need to be able to be toggled with a button with a .click() event. Does anyone know how I could achieve this? The only solutions I have come up with caused the background colors to break. Any help would be greatly appreciated!
Here is an example of the table structure:
<table>
<tbody>
<tr>
<td>Cell Contents</td>
<td>Cell Contents</td>
</tr>
<tr>
<td>Cell Contents</td>
<td>Cell Contents</td>
</tr>
<tr>
<td>Cell Contents</td>
<td>Cell Contents</td>
</tr>
</tbody>
<tbody>
<tr>
<td>Cell Contents</td>
<td>Cell Contents</td>
</tr>
<tr>
<td>Cell Contents</td>
<td>Cell Contents</td>
</tr>
<tr>
<td>Cell Contents</td>
<td>Cell Contents</td>
</tr>
</tbody>
</table>

This should do the trick:
$(function() {
$('#showAll').click(function() {
$('table > tbody').each(function() {
$(this).children('tr:gt(4)').toggle();
});
$("tr:visible").filter(':odd').css("background", "#efefef").end()
.filter(':even').css("background", "#ffffff");
}).click();
});
Edited to clean up code (inspired by #karim79's answer).

This does it (tested):
var rowLimit = 5;
$(document).ready(function() {
$('button').click(function() {
//hide everything after the rowLimit row
$('table > tbody > tr:gt(' + (rowLimit - 1) + ')').toggle();
});
});
The key is in the gt selector
To prevent your row styles from vanishing, put them in a CSS class and use addClass and removeClass instead to apply them, bearing in mind that if they're not in a class, then they don't exist :)

Scrolling. Set the height of the table to what 5 rows will fit in, and then use css
overflow: scroll; :D

Related

jQuery - Removing td's click event after clicking it

I bind a click event to all tds like so:
$(document).ready(function(){
$("#table").on("click","td",clickHandler);
});
How to remove a particular clickHandler from a clicked td after clicking it?
If you just want each table cell to have the click event bound to it for one click, use .one():
$("td").one("click",function(){
$(this).off("click");
});
$("td").one("click", function() {
console.log($(this).text())
$(this).off("click");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Item 1</td>
<td>Item 2</td>
<td>Item 3</td>
<td>Item 4</td>
</tr>
</table>
You can try this:
$('td').toArray().forEach(td => {
td = $(td);
td.attr('onclick', 'alert(this.id)');
});
$(document).on('click', 'td', function () {
$(this).removeAttr('onclick');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<table>
<tr>
<td id="td1">Item 1</td>
<td id="td2">Item 2</td>
<td id="td3">Item 3</td>
<td id="td4">Item 4</td>
</tr>
</table>
My idea: setting onclick attribute to td tag, after clicking, removing the attribute.
Try this. A different approach where you don't need to add/remove class and also no need to modify onclick attribute as inline events are not recommended.
What i'm doing here is binding the click event slightly differently.
What you are doing is $("#table").on("click", "td", clickHandler) - it will bind event to #table and upon click filter it for td.
Now what i'm doing is $("#table td").on("click",clickHandler) - it will bind the event to all td inside #table. So when the click event occurs, for that particular td click can be turned off by $(this).off("click");
$(document).ready(function(){
$("#table td").on("click",clickHandler);
});
var clickHandler = function(){
console.log(this);
$(this).off("click");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="table">
<tr>
<td>Item 1</td>
<td>Item 2</td>
<td>Item 3</td>
<td>Item 4</td>
</tr>
</table>

How to move/reorder an html table row

The idea is to move a particular table row to a different location
HTML
<table id="grid1" class="table table-zebra">
<tbody>
<tr>
<td>Cont 1 tr 1</td>
</tr>
<tr>
<td>Cont 2 tr 2</td>
</tr>
<tr>
<td>Cont 3 tr 3</td>
</tr>
<tr>
<td>Cont 4 tr 4</td>
</tr>
<tr>
<td>Cont 5 tr 5</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 7 tr 7</td>
</tr>
<tr>
<td>Cont 8 tr 8</td>
</tr>
<tr>
<td>Cont 9 tr 9</td>
</tr>
<tr>
<td>Cont 10 tr 10</td>
</tr>
<tr>
<td>Cont 11 tr 11</td>
</tr>
<tr>
<td>Cont 12 tr 12</td>
</tr>
<tr>
<td>Cont 13 tr 13</td>
</tr>
<tr>
<td>Cont 14 tr 14</td>
</tr>
</tbody>
</table>
That is the basic table, now, how do I can I move the TR 11 in a away that it will be under TR 4, I'm sorry that I don't post any JS but I have no idea how to do it... I was looking at this JSbin which is nice but can't use it..
Move the 11th tr to under the 4th:
$("tbody tr:nth-child(11)").insertAfter("tbody tr:nth-child(4)");
Working demo
If you prefer vanilla, you need the selectors the other way around.
document.querySelector("tbody tr:nth-child(4)").insertAdjacentElement("afterend", document.querySelector("tbody tr:nth-child(11)"));
In the context of an HTML table with rows that look like this:
<tr class="form-grid-view-row">
<td>
<a class="up" href="#">⇑</a>
</td>
<td>
<a class="down" href="#">⇓</a>
</td>
<td>
<span id="index1" class="form-label">1</span>
</td>
<td>
<span id="span1" class="form-label">Value 1</span>
</td>
</tr>
And this script:
$('.up,.down').click(function () {
var row = $(this).parents('tr:first');
if ($(this).is('.up')) {
row.insertBefore(row.prev());
} else {
row.insertAfter(row.next());
}
});
$('.up,.down').click(function () {
This is selecting every DOM element with the class "up" and every element with the class "down", e.g. $('.up,.down').click(function () {. The function sets up a click handler for each element.
var row = $(this).parents('tr:first');
$(this) refers to the DOM element which is the target of the click handler (one of the "up" or "down" elements which was selected above). .parents() looks for tr:first, the first <tr> element starting with <a> and travelling up the DOM. It'll end up selecting the entire row.
if ($(this).is('.up')) {
This is checking to see whether or not the element selected has the class "up" or not.
row.insertBefore(row.prev());
This takes the row that was clicked, and moves it right above the upper-most sibling of the row that was clicked.
The jQuery methods used (insertBefore, prev, is, parents, etc.) are described in greater detail in the jQuery documentation.
You can do it by using JQuery Library.
// selecting tbody is bad instead you need to give an id or class to this tag and select according to this
var fourth = $( "tbody tr:nth-child(4)" ),
eleventh = $( "tbody tr:nth-child(11)" );
$( "tbody tr:nth-child(11)" ).insertAfter(fourth);
In order to move dynamically your elements you can add an event to all tbody children. What I basically do is select one element on first click then I move it after second element clicked.
$(document).on("ready", function () {
var $tbody = $("#grid");
var selected = null;
$tbody.children().on("click", function () {
if (selected == null)
selected = this;
else
{
$(selected).insertAfter(this);
selected = null;
}
});
});
It move after an element but is just an idea, you can customize it.
Your html should be like this.
<table>
<tbody id="grid">
<tr> <td> 1 </td> </tr>
<tr> <td> 2 </td> </tr>
<tr> <td> 3 </td> </tr>
<tr> <td> 4 </td> </tr>
</tbody>
</table>

jquery tablesorter usage without tbody and th block

I am very much interested to know how to use jquery tablesorter without tbody and th block, the reason behind this is I have many tables and css working which I generated from http://www.csstablegenerator.com/ site, in which only tr and td blocks only used
This is working table with tbody block Working default table style fiddle
But I want to sort table with only tr and td blocks Expected Fiddle
This is my test table which I want to sort
<table border='1' id='test' >
<!-- this is my header -->
<tr>
<td>AlphaNumeric</td>
<td>Numeric</td>
<td>Animals</td>
<td>Sites</td>
</tr>
<tr>
<td>abc 123</td>
<td>10</td>
<td>Koala</td>
<td>http://www.google.com</td>
</tr>
<tr>
<td>abc 1</td>
<td>234</td>
<td>Ox</td>
<td>http://www.yahoo.com</td>
</tr>
<tr>
<td>abc 9</td>
<td>10</td>
<td>Girafee</td>
<td>http://www.facebook.com</td>
</tr>
<tr>
<td>zyx 24</td>
<td>767</td>
<td>Bison</td>
<td>http://www.whitehouse.gov/</td>
</tr>
</table>
Assuming you don't want to manually deal with the HTML of the table, so I would get jquery to do it for you:
var header = $("#test tr:first").html();
$("#test tr:first").remove();
$("#test").prepend('<thead>' + header + '</thead>');
$('#test').tablesorter();

HTML / CSS / Javascript - Changing one table cell value, when hovering over a different cell

I don't actually have any code relating to this, as it is completely hypothetical, but I was just wondering how simple it would be to do.
Lets say, for example, I have a standard table with 4 cells.
<html>
<head></head>
<body>
<table>
<tr>
<td>Cell 1</td>
</tr>
<tr>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 4</td>
</tr>
</table>
</body>
</html>
Now I want to hover over cell 2 and have an image display in cell 3... Is this possible using JavaScript?
Here is a more generic example with pure JavaScript. It changes the background of the next td for all the td. For the last one it will change the background of the first. Setting to a background image would be as simple as changing the CSS to use background-image instead of background-color.
jsFiddle
JavaScript
var tds = document.querySelectorAll('td');
for (var i = 0; i < tds.length; i++) {
tds[i].onmouseover = (function (i) {
return function () {
tds[(i + 1) % tds.length].className = 'hovered';
}
})(i);
tds[i].onmouseout = (function (i) {
return function () {
tds[(i + 1) % tds.length].className = '';
}
})(i);
}
CSS
.hovered {
background-color:#F00;
}
Give this code a try. Keep in mind that this does exactly what you asked, no more, no less. You'll want to extend this code properly using classes (instead of IDs) if you want a maintainable solution, but that would be beyond the scope of this question.
<html>
<head></head>
<body>
<table>
<tr>
<td>Cell 1</td>
</tr>
<tr>
<td id="hoverover">Cell 2</td>
</tr>
<tr>
<td id="changeme">Cell 3</td>
</tr>
<tr>
<td>Cell 4</td>
</tr>
</table>
<script>
var hoverEl = document.getElementById('hoverover'),
changeEl = document.getElementById('changeme');
hoverEl.addEventListener('mouseover', function() {
changeEl.innerHTML = '<img src="/path/to/image" />';
}, false);
hoverEl.addEventListener('mouseout', function() {
changeEl.innerHTML = 'Cell 3';
}, false);
</script>
</body>
</html>
You can try to achive that using only css. There are at least two selectros that might be helpful.
First one is +, second one is nth-child(). So lets say you always want to display the image in table cell n+1, where n is the cell you're hovering:
<table>
<tr>
<td>Cell 1</td>
</tr>
<tr>
<td><img src="yoursource.jpg"></td>
</tr>
<tr>
<td>Cell 3</td>
</tr>
<tr>
<td><img src="yoursource2.jpg"></td>
</tr>
</table>
You can try it this way:
img { display: none; }
tr:hover + tr img { display: block; }
Or you can create rule using css3 selectors:
img { display: none; }
tr:nth-child(n+1):hover + tr img { display: block; }
I guess there are few more ways to do it only by using css, but of course it'll work only if you have images already in your code (you didn't precise if you want to just display them or load them).
working example

How to avoid duplicate code (toggle when page loaded)?

See the code below, If you click on the sub-title row it then will hide the rows with it. It work well.
On the second sub-title row (<tr class="sub-title default-hide">) - I want this to toggle/hidden by default when the page loaded.. How to do this without writing duplicate code like below?
$(".sub-title").on("click",function() {
tr = $(this).find('span').hasClass("arrow2");
trSpan = $(this).find('span');
$(this).nextUntil(".sub-title").each(function() {
if (!$(this).hasClass('head-order')) {
$(this).toggle();
if (tr) {
trSpan.removeClass('arrow2').addClass('arrow1');
} else {
trSpan.removeClass('arrow1').addClass('arrow2');
}
}
});
});
HTML
<table border="1">
<tbody>
<tr class="head">
<td> title </td>
</tr>
<tr class="sub-title">
<td>Sub Title 1 <span class="arrow2"> </span></td>
</tr>
<tr> <td>Item 1</td> </tr>
<tr> <td>Item 2</td> </tr>
<tr> <td>Item 3</td> </tr>
<tr class="sub-title default-hide">
<td>Sub Title 2 <span class="arrow2"></span></td>
</tr>
<tr> <td>Item 4</td> </tr>
<tr> <td>Item 5</td> </tr>
<tr> <td>Item 6</td> </tr>
</tbody>
</table>
I created a jsFiddle example with the information you provided.
I edited the code a bit, using a default arrow-class and just adding the class close to it, to define the new style, which should make the code a little shorter.
$(".sub-title").on("click",function() {
var trSpan = $(this).find('span');
trSpan.toggleClass('closed');
$(this).nextUntil(".sub-title").each(function() {
if (!$(this).hasClass('head-order')) {
$(this).toggle();
}
});
});
To make the "default-hidden" - element closed on pageload, all I do is to trigger a click-event on it after binding the click-Handler.
$('.default-hide').trigger('click');
See the fiddle for a working example
Create a named function and call it a couple times:
var toggleArrow = function(el) {
tr = $(el).find('span').hasClass("arrow2");
trSpan = $(el).find('span');
$(el).nextUntil(".sub-title").each(function() {
if (!$(el).hasClass('head-order')) {
$(el).toggle();
if (tr) {
trSpan.removeClass('arrow2').addClass('arrow1');
} else {
trSpan.removeClass('arrow1').addClass('arrow2');
}
}
});
};
$(".sub-title").on("click", function(){ toggleArrow(this); });
$(".default-hide").each(function(i, el){ toggleArrow(this); });
You can trigger the click event manually for the default-hide rows.
Like this
$('.default-hide').trigger('click');

Categories

Resources