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>
Related
I have a htmltable that is dynamically created. I have made the rows clickable.
I need to pass the row innertext id to the script that fires when the row is clicked.
htmltable:
<table style="width:100%;">
<tr>
<th>id</th>
<th>name</th>
<th>other info</th>
</tr>
<tr>
<td class='table_row_click'>11</td>
<td class='table_row_click'>item 2</td>
<td class='table_row_click'>lmfao</td>
</tr>
<tr>
<td class='table_row_click'>22</td>
<td class='table_row_click'>item 2</td>
<td class='table_row_click'>lol</td>
</tr>
</table>
Click event:
$(document).ready(function ($) {
$(".table_row_click").click(function (e) {
//I need to use the clicked row ID here for something
});
});
$(e.target).closest('tr').find('td').first().text();
You can navigate up to the parent tr, find the td elemements, get the first one, and get its text.
Using closest('tr') will work if the class is on the td or tr level, as closest() can match on itself.
I have an onclick event in a table both on a <td> and <tr> elements. I need when the user clicks on the specific column (<td>), the <tr> event won't be triggered, only the <td> one.
How to do it ?
Example :
HTML :
<tr onclick='trclick();'>
<td>Column 1</td>
<td>Column 2</td>
<td onclick='tdclick();'>Column 3</td>
</tr>
JS :
function trclick(){console.log('tr clicked')};
function tdclick(){console.log('td clicked')};
When the user clicks on 'Column 3', both events are triggered, but i want only tdclick() to be triggered.
What you need to do is to stop the propagation of the parent event when a child is clicked, it's easy done in jQuery, but naively you need to do a little more work:
function trclick(){
console.log('tr clicked')
};
function tdclick(e){
if (!e) var e = window.event; // Get the window event
e.cancelBubble = true; // IE Stop propagation
if (e.stopPropagation) e.stopPropagation(); // Other Broswers
console.log('td clicked');
};
Note, for Firefox you need to pass a event parameter:
<td onclick='tdclick(event)'>Column 3</td>
You need to stop the propagation of the event.
to access the event object you need to use it as parameter of your function tdclick
function trclick(){console.log('tr clicked')};
function tdclick(event){
console.log('td clicked');
event.stopPropagation()
};
<table><tbody>
<tr onclick='trclick();'>
<td>Column 1</td>
<td>Column 2</td>
<td onclick='tdclick(event);'>Column 3</td>
</tr>
</tbody></table>
you can use el in your function input and pass the variable to it, in every where you wanna call it.
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
function colorChanger(el){
el.style.backgroundColor = '#007d00';
}
</script>
</head>
<body>
<table>
<tr onclick="colorChanger(this);">
<td onclick="colorChanger(this);">click me</td>
</tr>
</table>
</body>
</html>
All javascript events are invoked with an "event" object in the first argument. This object have a "stopPropagation" method, which prevent listeners of the same event on higher hierarchical DOM nodes to be triggered.
There's an example just like yours at MDN: https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Examples#Example_5:_Event_Propagation
In your example, you could just stop propagation on "tdclick":
function tdclick(e){
e.stopPropagation();
console.log('td clicked')
};
I like this method:
<td style='cursor: pointer;' tdclick(event);'></td>
then JS
<script>
tdclick(){
//do something...
}
</script>
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>
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');
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