Reputation: 126
I've the following table with a link in the last cell. The table is populated with data via ajax, depending on the users input.
<table class="table-list">
<tbody>
<tr>
<td>...</td>
<td><a href="/link">Link</a></td>
</tr>
</tbody>
</table>
Because I like to have the whole row clickable, I use the following script to catch the onClick event. But the link is also in the table row and the onClick-Event gets fired infinity times until the script aborts with an "stackoverflow" error.
<script>
$(function() {
$('.table-list tr').live('click', function() {
$('a:last', this).click();
});
});
</script>
I tried to disable the event temporarily like below but it's not working.
<script>
$(function() {
$('.table-list tr').live('click', function() {
$(this).off('click');
$('a:last', this).click();
$(this).on('click');
});
});
</script>
I also tried some variations like addind and removing a class isClicked
to the row etc. but nothing worked.
Any suggestions on this?
Upvotes: 1
Views: 1220
Reputation: 31
It is important to prevent event propagation, e.g. bubbling.
I posted some example code here: http://pastebin.com/d25QeVkK
This is the JS/jQuery part:
(function($){
$(document).delegate('table tr', 'click', function(e){
$('a', this).trigger('click');
});
$(document).delegate('tr a', 'click', function(e){
console.log("it works!");
// use either of these to prevent stackoverflow
//e.stopPropagation(); // use this if you want normal click behaviour without bubbling
return false; // use this if you don't want normal click behaviour and no propagation
});
})(jQuery);
So this wasn't the smartest solution, because it actually won't work because of the way delegate works. The click has to bubble to the body element for it to work if you use delegate - and stopPropagate prevents that. This should do the trick:
$('body').delegate('.table-list tr', 'click', function(e){
$('a', this).trigger('click');
});
$('body').delegate('.table-list tr a', 'click', function(e){
e.stopPropagation();
window.location.href = $(this).attr('href');
});
e.stopPropagation();
has to stay in the click handler, because else you would still get a frozen UI and recursion warning after a while, before getting redirected to the target url.
So this is even shorter and should work too:
$('body').delegate('.table-list tr', 'click', function(e){
window.location.href = $(this).find('a').attr('href');
});
Use this to open in new tab:
$('body').delegate('.table-list tr', 'click', function(e){
window.open($(this).find('a').attr('href'),'_newtab');
return false;
});
Please keep in mind to use the right selectors, this is really generic code.
Upvotes: 3
Reputation: 1080
Instead of trying to click the link, try this:
<table class="table-list">
<tbody>
<tr style='border: 1px solid black;'>
<td>.1.</td><td>.2.</td><td>.3.</td><td>.4.</td><td>.5.</td>
<td class='link'><a href="/link" target="_blank">Link</a></td>
</tr>
<tr style='border: 1px solid black;'>
<td>.1.</td><td>.2.</td><td>.3.</td><td>.4.</td><td>.5.</td>
<td class='link'><a href="/link">Link2</a></td>
</tr>
</tbody>
</table>
Script:
$('.table-list td').each(function(){
if ($(this).find('a').length === 0){
$(this).on('click', function(){
var link = $(this).siblings('.link').find('a');
if (link.attr('target') === '_blank'){
window.open(link.attr('href'));
}
else {
window.location = link.attr('href')
}
});
}
});
It's ugly, and could be shortened, but it's better than the form submit IMHO.
If you want to make the other tds clickable consider just wrapping the entire row with the link.
Upvotes: 0
Reputation: 24276
Try this one:
$(function() {
$('.table-list').on('click', 'tr', function(){
$(this).find('a:last').trigger('click');
});
$('.table-list').on('click','a',function(e){
e.stopImmediatePropagation();
});
});
Upvotes: 0