I have a simple table and I write some JS code in order to achieve that whole tr become a data-href. Everything works very nice except for one thing.
Now the whole row is clickable and that is fine, but there is a small issue, if you click on the delete button, it takes you to the update page (data-href), and I want to avoid that. So my question is how can I modify that code for the whole row to stay clickable except that delete button?
Here is my code:
$("tr").each(function() {
const $tr = $(this);
$tr.attr("data-href", $tr.find("a").attr("href"))
})
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
.modal {
padding:5px;
background-color:red;
color:#fff;
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table>
<tr>
<td>Name</td>
<td> Age</td>
<td>
Update
<a data-toggle="modal" class="modal" data-target="#deleteModal">Delete</a>
</td>
</tr>
</table>
Can somebody try to help me with this?
To achieve this you can use the is() method to determine what element within the tr was clicked on. If it was an a element then you can prevent the window.location from being updated.
Also note that you can update the data-href of each tr using an implicit loop which makes the code slightly more succinct. Try this:
$('tr').attr('data-href', function() {
return $(this).find('a').attr('href');
});
$('*[data-href]').on('click', function(e) {
if (!$(e.target).is('a')) {
window.location.assign($(this).data("href"));
}
});
.modal {
padding: 5px;
background-color: red;
color: #fff;
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table>
<tr>
<td>Name</td>
<td>Age</td>
<td>
Update
<a data-toggle="modal" class="modal" data-target="#deleteModal">Delete</a>
</td>
</tr>
</table>
Related
So I've made this table, and by using Javascript, I made them clickable.
My Javascript is the following:
function tdClick() {
$(document).ready(function() {
$('table td').click(function() {
var TJid = $(this).attr('id');
window.open(
'TestResults?ID=' + TJid,
'_blank' // <- This is what makes it open in a new window.
);
});
});
}
This Javascript is applied to this table <td>
function MakeTable($TestPlanData){
echo"
<tr>
<td class='font-weight-bold' scope='row' id=".$TestPlanData['TestJobId'].">".$TestPlanData['TestSuiteCollectionName']."</td>
<td id=".$TestPlanData['TestJobId'].">
<div class='row ml-1'>";
if ($TestPlanData['Passed'] != 0) {
echo"
<div class='col-xs-6 mr-1'>
<span class='bg-success rounded text-light font-weight-bold h6 p-2'>
".$TestPlanData['Passed']."
</span>
</div>";
}
echo"
</div>
</td>
<td id=".$TestPlanData['TestJobId']."><small class='text-muted'>".convertTimeZone($TestPlanData['Date'], 'UTC', 'Europe/Copenhagen')."</small></td>
<td id=".$TestPlanData['TestJobId']."><small class='text-muted'>".$TestPlanData['NameVersion']."</small></td>
</tr>
";
}
BUT at the moment when I hover my mouse over the <td> no URL is shown at the bottom of the browser, unlike if I use a tag. I can only make the tag apply to the text and not the whole rectangle/.
Is there a way to get this at the bottom of the page when I hover my mouse over each <td>?
You need "normal" <a> tags for this to work. Example:
tr td { width: 50%; }
tr th { background: #EEE; }
a { color: black; text-decoration: none; }
<table border="1">
<tr><th>Description</th><th>Link</th></tr>
<tr><td>First</td><td>Link 1</td></tr>
<tr><td>Second</td><td>Link<br/>with<br/>multiline<br/>text</td></tr>
<tr><td>Third</td><td>Link with long text with very long description and it will be wrapped automatically</td></tr>
</table>
As far as I know, it only works in <a> tags:
<html>
<div>Link 1</div>
<div onclick="window.open('index.php','_self')">Link 2</div>
</html>
In function ClickedRow, i want to use the "a" which is being clicked. So i want to receive it as a parameter.
<td ...... >
<span class="......>
<span onmousedown="event.cancelBubble = true">
<a class="GridLinkRenderer" href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" urlText="XXXX">
<td ......
<span class="......>
<span onmousedown="event.cancelBubble = true">
<a class="GridLinkRenderer" href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" urlText="XXXXX">
Based on clicked <a ....> I would like to hide/show it (or to show/hide next <a class= "GridLinkRenderer" in other <td ...>) by function ClickedRow(this).
How can I do it ?
I've tried to send the clicked $(row).next().eq(0).tagName and row.style.display = 'none' , it says that it is "undefined".
function ClickedRow(row){
$(row).next().eq(0).hide();
$(row).hide();
}
Instead of this, remove href and use
$('#TheidOfTheA').on('click'function(){
let myAElement = $(this);
}
have you looked at closest(),find() and next() ?
https://api.jquery.com/closest/
https://api.jquery.com/next/
https://api.jquery.com/find/
$(row).closest('td').next('td').find('.GridLinkRenderer')
haven't tested this.. but if I'm thinking right this should be at least the point to right direction.
I can't tell by OP if the td are being used in a tr and the tr in a table as it should so I'll just mention real quick that it's invalid HTML should there be any td without a tr as a parent and it's invalid HTML having a tr without a table as its ancestor.
If starting at a tag nested within a td you'll need to climb out:
$(this).closest('td')...
Once at the cell level look around for the cells to the left: ....prev('td'), or to the right: ....next('td') or both: ....siblings('td'). Then go down each td and find the link nested within and turn it off/on: ....find('.gLR').fadeToggle();
$(this).closest('td').siblings('td').find('.gLR').fadeToggle();
$('.gLR').not('.g5').hide();
$('.gLR').on('click', function(e) {
if ($(this).hasClass('g5')) {
$('.gDir').fadeToggle();
} else if ($(this).hasClass('g1') || $(this).hasClass('g9')) {
const cell = $(this).closest('td');
cell.siblings('td').find('.gLR').fadeToggle();
} else if ($(this).hasClass('g4')) {
$(this).closest('td').prev('td').find('.gLR').fadeToggle();
} else if ($(this).hasClass('g6')) {
$(this).closest('td').next('td').find('.gLR').fadeToggle();
} else {
return false;
}
});
:root {
font: 700 5vw/1.5 Consolas
}
table {
table-layout: fixed;
border-collapse: collapse;
}
td {
width: 20%;
text-align: center
}
a {
display: block;
height: 10vh;
text-decoration: none;
color: cyan;
}
a:hover {
color: tomato;
}
a.g5:hover {
font-size: 0;
}
a.g5:hover::after {
content: '\1f536';
font-size: 5vw;
}
td b {
display: block;
height: 10vh;
}
<table>
<tr class='gRA'>
<td colspan='2'>
<b>🌈</b>
</td>
<td><b>⮝</b></td>
<td colspan='2'>
<b>🦄</b>
</td>
</tr>
<tr class='gRB'>
<td><b>🏰</b></td>
<td><b>⮜</b></td>
<td><b>🔷</b></td>
<td><b>⮞</b></td>
<td><b>🏯</b></td>
</tr>
<tr class='gRC'>
<td colspan='2'>
<b>🔥</b>
</td>
<td><b>⮟</b></td>
<td colspan='2'>
<b>💀</b>
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I tried both recommendations(thx for it) - no success.
It looks that the "this" argument is not passed like clicked element(object) reference.
The parameter "row" seems to be like parent of all object, so like new Object and not the clicked object.
I am not sure if href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" is correct syntax though.
so copied Your sample and came up with this. ;) try this out.. and
make sure You understand what's happening here.
$(() => {
$("body").on("click",".GridLinkRenderer", (e) => {
e.preventDefault();
//works on the first link.. stil misses a few check..
//for example do we have the next td.. at all..
console.log($(e.currentTarget).closest('td').next('td').find('.GridLinkRenderer'));
})
});
I am working with a web application where I am re-ordering HTML table rows and am seeing when an item with a class is clicked. The event is firing twice but I do not see how.
I would be grateful if anyone would be able to let me know how I can stop this behavior as this will be creating an AJAX call and passing the array back to the code behind but I only need and want it to fire once.
$('table').on('click', ".up,.down,.top,.bottom", function() {
console.log("up or down arrow clicked");
var row = $(this).parents("tr:first");
if ($(this).is(".up")) {
if (row[0].rowIndex > 1) {
row.insertBefore(row.prev());
}
} else if ($(this).is(".down")) {
row.insertAfter(row.next());
} else if ($(this).is(".top")) {
row.insertBefore($("table tr:first"));
row.insertAfter(row.next());
} else {
row.insertAfter($("table tr:last"));
}
//... more code here
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<table>
<tr id="sectionRow_1010_M_TR" style="border: 1px solid black;">
<td style="padding: 0px; width: 15px;">
<input class="collapse" id="btnMinus0_1010" style="padding: 0px; width: 15px; height: 20px; text-align: center; vertical-align: top; display: none;" onclick="collapse('0_1010')" type="button" value="-">
<input class="expand" id="btnPlus0_1010" style="padding: 0px; width: 15px; height: 20px; text-align: center; vertical-align: top;" onclick="expand('0_1010')" type="button" value="+">
</td>
<td style="padding: 0px; width: 100%; text-align: left; background-color: gray;">
<span>Engine, Fuel and Cooling Systems</span>
</td>
<td>
<a class="up" href="#"><i class="fa fa-angle-up" aria-hidden="true"></i></a>
<a class="down" href="#"><i class="fa fa-angle-down" aria-hidden="true"></i></a>
</td>
</tr>
</table>
Your symptom doesn't match your code, but the three most likely reasons for your symptom are (I lean toward #3):
You have an .up, .down, .bottom, or .top element inside an .up, .down, .bottom, or .top element. So since click propagates (and jQuery faithfully replicates that when doing event delegation), it's firing for the innermost match, and also for the outermost match.
If so, target the handler more directly at the elements in question.
or
You're running your code twice, and thus setting up two handlers, each of which is firing.
If so, er, don't do that. :-)
or
Your table is inside another table, so $("table") matches both of them, and again because click propagates (at the DOM level this time), you get a response from both tables.
If so, target just the table you want these handlers hooked up in.
Since your code doesn't replicate it, here's a simplified example of #1:
$("table").on("click", ".up, .down", function() {
console.log(this.className + " clicked");
});
<table>
<tbody>
<tr class="up">
<td class="down">Click me</td>
</tr>
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
...and of #2:
$(document).ready(setup);
$(window).load(setup);
function setup() {
$("table").on("click", ".up, .down", function() {
console.log(this.className + " clicked");
});
}
<table>
<tbody>
<tr>
<td class="down">Click me</td>
</tr>
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
...and of #3:
$("table").on("click", ".up, .down", function() {
console.log(this.className + " clicked");
});
<table>
<tbody>
<tr>
<td>
<table>
<tbody>
<tr>
<td class="down">Click me</td>
</tr>
</tbody>
</table>
</td>
</tr>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
1) It may be happening as you are assigning the same handler to click event multiple times. I suggest, you kindly check the line where you assign the handler. I guess it is being called multiple times. A solution could be a call to unbind first then bind, like this:
$('table').unbind("click").click('.up,.down,.top,.bottom') {
//Do Stuff
});
$('table').off("click").on('click', ".up,.down,.top,.bottom", function() {
//Do Stuff
});
2) if in any case, if you find that .off() .unbind() or .stopPropagation() can't fix your issue, please use .stopImmediatePropagation(). It usually works great in these kind of situations when you just want your event to be handled without any bubbling and without effecting any other events already being handled. Something like:
$("table").click(function(event) {
event.stopImmediatePropagation();
//Do Stuff
});
which does the trick always!
I have a table with each row representing a song.
When a song is clicked, the parent td should be highlighted a light blue color with the .active class and if any song was highlighted previously the parent td's .active class should be removed.
This part works fine and is represented with this jquery:
$(".songs").click(function(){
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
I also want to have a next button and a previous button. This where I am having issues. When the next button is clicked, the next song on the list should be highlighted and the previously highlighted song should be unhighlighted (I am using the class .active to do the highlighting and unhighlighting). This part is not working:
$('#next_button').click(function(){
var current = $('td.active');
$('.songs').parents('td').removeClass('active');
current.nextAll('td:first').addClass('active');
});
Here is the jsfiddle link:
jsfiddle Link
Here is my html code:
<table id="song_table">
<thead id="song_thead">
<tr>
<th id="table_head">Songs</th>
</tr>
</thead>
<tbody id="song_tbody">
<tr>
<td class="td_songs">
<a class="songs">
1
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
2
</a>
</td>
</tr>
</tbody>
</table>
<div id="next_button">
<p id="next_text">Next Button</p>
</div>
Here is my css:
.active{
background-color: #D9FAFA;
}
table{
text-align: center;
height: 100px;
width: 200px;
}
#table_head{
text-align: center;
}
#next_button{
height: 100px;
width: 200px;
background-color: lightgreen;
}
Here is my jquery
$(document).ready(function() {
$(".songs").click(function(){
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
$('#next_button').click(function(){
var current = $('td.active');
$('.songs').parents('td').removeClass('active');
current.nextAll('td:first').addClass('active');
});
});
If you could help me solve this issue, I would greatly appreciate it. I feel like this should be so easy but I just can't seem to make it work.
Thanks!
The trick is to get the row index of the current song, add 1, and then do a modulo with number of rows that way if the current row+1 overflows the number of rows, it will start from the beginning:
$().ready(function() {
$(".songs").click(function(){
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
$('#next_button').click(function(){
//here .parent() will get the current <tr>
//.parent().index() will get the index of the current <tr>
var currentID = $('td.active').parent().index();
//here .parent() will get the <tr>
//.parent().parent() will get the <tbody>
//.parent().parent().children() will get all the rows
//.parent().parent().children().length will get the row count
var nextID=(currentID+1)%($('td.active').parent().parent().children().length)
$('.songs').parents('td').removeClass('active');
$('td').eq(nextID).addClass('active');
});
});
.active{
background-color: #D9FAFA;
}
table{
text-align: center;
height: 100px;
width: 200px;
}
#table_head{
text-align: center;
}
#next_button{
height: 100px;
width: 2d00px;
background-color: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="song_table">
<thead id="song_thead">
<tr>
<th id="table_head">Songs</th>
</tr>
</thead>
<tbody id="song_tbody">
<tr>
<td class="td_songs">
<a class="songs">
1
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
2
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
3
</a>
</td>
</tr>
<tr>
<td class="td_songs">
<a class="songs">
4
</a>
</td>
</tr>
</tbody>
</table>
<div id="next_button">
<p id="next_text">Next Button</p>
</div>
Something like this? http://jsfiddle.net/y5ntap04/3/
You needed to go up the DOM and then where all the siblings are, you can go to the next() one.
Plus added a previous button for you.
$().ready(function () {
$(".songs").click(function () {
$('.songs').parents('td').removeClass('active');
$(this).parents('td').addClass('active');
});
$('#next_button').click(function () {
$('.songs').parents('td.active').removeClass('active').closest('tr').next().find('td').addClass('active');
});
$('#previous_button').click(function () {
$('.songs').parents('td.active').removeClass('active').closest('tr').prev().find('td').addClass('active');
});
});
in your code you have each td in its own tr meaning there is no next td to go to.
you should adjust your jquery to focus on the rows, as in this fiddle (shown below)
$().ready(function() {
$(".songs").click(function(){
$('.songs').parents('tr').removeClass('active');
$(this).parents('tr').addClass('active');
});
$('#next_button').click(function(){
var current = $('tr.active');
$('.songs').parents('tr').removeClass('active');
current.next('tr').addClass('active');
});
});
You'll also notice I'm using .next() which will just grab the next element or the next element which matches the argument (in this case tr) - no need to get all then restrict to just the first.
All this will make your fiddle behave as expected, however, if you want to target the td's within each of the tr's you'll have to add .find('td') to get the td out of the retrieved tr, like this. Here the only line that is changed is the one that adds the class on click of next, which is now: current.parent().next('tr').find('td').addClass('active');
Refactoring out $('.songs').parents('tr').removeClass('active'); into it's own function would also clear your code a bit and make it easier to follow, a good habit! (also +1 for using a variable to store a returned JQuery DOM object - var current = $('tr.active'); - another good habit for code clarity and efficiency, especially when you are deraling with more complicated DOM structures and functions)
I'm new to Javascript and I'm working on a project. Thanks to help from a online help website, I'm able to show/hide my table successfully.
When I click the h3 element, it opens up and append the anchor (in this situation, #1, #2, #3) to the URL.
I want to use this anchor element to open up the specific table from an external link from another web page. (e.g. at Home Page, I clicked on this testing.html#1, I want it automatically open the 1st table when I reach the page)
Thank you very much!
JAVASCRIPT
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
function showonlyone(thechosenone) {
$('.newboxes').each(function(index) {
if ($(this).attr("id") == thechosenone) {
$(this).show(200);
}
else {
$(this).hide(600);
}
});
}
</script>
CSS
<style>
#special1{ display: none }
h3 {text-align: center;
background-color: black;
color: white;
clear: both;
cursor: pointer; }
.newboxes {
display: none;
}
a {text-decoration: none;}
</style>
HTML
<a id="myHeader1" onclick="javascript:showonlyone('newboxes1');" href="#1"><h3>Table 1</h3></a>
<table border="1" align="center" cellspacing="10px" class="newboxes" id="newboxes1">
<tr>
<td>1</td>
</tr>
</table>
<a id="myHeader2" onclick="javascript:showonlyone('newboxes2');" href="#2"><h3>Table 2</h3></a>
<table border="1" align="center" cellspacing="10px" class="newboxes" id="newboxes2">
<tr>
<td>2</td>
</tr>
</table>
<a id="myHeader3" onclick="javascript:showonlyone('newboxes3');" href="#3"><h3>Table 3</h3></a>
<table border="1" align="center" cellspacing="10px"class="newboxes" id="newboxes3">
<tr>
<td>3</td>
</tr>
</table>
Note this only work if you are loading from a html page in the same domain.
JQuery's .load function is very versatile. To load the first table from testing.html, we can do:
$('#tableContainer').load('testing.html table:eq(0)');
2nd table:
$('#tableContainer').load('testing.html table:eq(1)');
and so on.
demo
Note that the 3 tables in the demo are loaded from here
If the URL ends with #1, and you need showonlyone('newboxes1') automatically executed:
if (window.location.hash.substr(1) == '1') {
showonlyone('newboxes1');
}