jquery/jqueryui, click anywhere in div besides button - javascript

I have a div as a ui-widget-content with a h3 as a ui-widget-header. The header has three buttons. Each have the class "save" "delete" and "cancel" respectivly. I want to have a .click function whene ever you click on the div, except if you actually click on one of the buttons.
I tried: $(".record").not(".save").not(".delete").not(".cancel").click(
my code is:
<div class="record cursorPointer hoverClass ui-widget-content">
<h3 class="ui-widget-header">
<table width="100%"><tr>
<td align="left" style="width:33%; color:Red">somecontractorone</td>
<td style="width:33%" align="center"> Name: Joe Q Shmoe </td>
<td style="width:33%" align="right"> Buisness: joeqshmoeelectrical</td>
<td><button style="width:20px;height:20px" class="save"></button></td>
<td><button style="width:20px;height:20px" class="delete"></button></td>
<td><button style="width:20px;height:20px" class="cancel"></button></td></tr>
</table>
</h3>
</div>
However the click function still activated when clicking the buttons.
Any ideas?

You can use the event.target to see what was clicked. Then rely on even bubbling and attach the click handler on the parent div. jsfiddle
$('.record').click(function(e){
if($(e.target).is(':button'))
alert('button');
else
alert('not button');
});

Assuming that you have another event handler (or several) that handles the buttons, you can prevent the bubbling there with
$('button').click(function(e) {
e.stopPropagation();
switch( this.className ) {
// Or whatever...
}
})

Use e.stopPropagation() in the buttons' click handler(s):
$('button').click(function(e) {
e.stopPropagation();
alert('you clicked a button!');
});
Here's a demo: http://jsfiddle.net/Ender/2yERz/
And some documentation on e.stopPropagation(): http://www.quirksmode.org/js/events_order.html#link9

Related

Prevent parent element click-event to trigger when child-dropdown clicked

I have a clickable parent element. As a child element I have a dropdown. When I click this dropdown, it also triggers the parent element.
The table elements are rendered dynamically as rows, thus I would like to target the elements by Id and not by class.
I have tried with e.stopPropagation() but then it prevents the dropdown to toggle.
Very thankful for any help!
document.getElementById("entirerow"+doc.id).addEventListener("click", function(e){
alert("Entire row clicked")
})
document.getElementById("dropdown"+doc.id).addEventListener("click", function(e){
alert("Only button clicked")
//e.stopPropagation(); I have tried this but it prevents the dropdown from triggering at all.
})
<tr id="entirerow"+doc.id>
<td>
<span>
<button id="dropdown"+doc.id>myDropdown</button>
</span>
</td>
<td>
...
</td>
</tr>
You could return early in your parent listener callback if the event target is the dropdown.
document.getElementById("entirerow"+doc.id).addEventListener("click", function(e){
if(e.target.id === ("dropdown"+doc.id)){
return;
}
alert("Entire row clicked");
})
document.getElementById("dropdown"+doc.id).addEventListener("click", function(e){
alert("Only button clicked");
})

Prevent button click from triggering click on tr while keeping Clipboard.js intact

I have a table with rows. In each row there is a "copy to clipboard" button implemented using Clipboard.js
Now I want the table row to be clickable and I want it to redirect to "google.com", if the user clicks anywhere on the row BUT the button.
When the user clicks the button, I want to copy the text to the clipboard, but NOT redirect.
I have tried using the solution suggested in this answer here, but using event.stopPropagation() also disables the Clipboard.js functionality.
Is there an elegant solution for this problem? Here's some code:
<table>
<tr>
<th>Name</th>
<th></th>
</tr>
<tr class='valign-middle' data-href='www.google.com'>
<td>Text</td>
<td>
<button data-clipboard-text='www.facebook.com' id='clipboard-btn'>
<i class="fa fa-clipboard"></i>
</button>
</td>
</tr>
</table>
<script>
// activate Clipboard buttons
var clipboard = new Clipboard('button#clipboard-btn');
// make table rows clickable
$(function(){
$('.table tr[data-href]').each(function(){
$(this).css('cursor','pointer').hover(
function(){
$(this).addClass('active');
},
function(){
$(this).removeClass('active');
}).click( function(event){
document.location = $(this).attr('data-href');
}
);
});
});
</script>
You can have a class for td in tr except for the last one in which your copy button is present, then instead of applying click event on row you can have this click event on each td and then check in click event whether td has that specified class or not, if it has redirect it to google.com else do nothing.
Below is the sample implementation :
<table>
<tr>
<th>Name</th>
<th></th>
</tr>
<tr class='valign-middle' data-href='www.google.com'>
<td class='normalText'>Text</td>
<td>
<button data-clipboard-text='www.facebook.com' id='clipboard-btn'>Copy
<i class="fa fa-clipboard"></i>
</button>
</td>
</tr>
</table>
<script>
var clipboard = new Clipboard('button#clipboard-btn');
// make table rows clickable
(function(){
$('table tr[data-href] td').each(function(){
$(this).css('cursor','pointer').hover(
function(){
$(this).addClass('active');
},
function(){
$(this).removeClass('active');
});
$(this).click( function(event){
if($(this).hasClass("normalText"))
document.location = $(this).parent().attr('data-href');
}
);
});
});
</script>

Stop Propagation not working

I'm trying to stop the bubbling of event of an inner checkbox to the click event of the tr element.
I have the following mark up:
<table border="1">
<tr class="row">
<td>
Item 1
</td>
<td>
<input type="checkbox" class="cb">
</td>
</tr>
<tr class="row">
<td>
Item 2
</td>
<td>
<input type="checkbox" class="cb">
</td>
</tr>
</table>
The rows are dynamically added, so to add listeners automatically to dynamically added elements, I used the following code:
$(document).ready(function() {
$('body').off('click.row').on('click.row', '.row', function() {
alert(1);
});
$('body').off('change.cb').on('change.cb', '.cb', function(e) {
e.stopPropagation();
alert(2);
});
});
However the event still bubble up to the tr element. I tried also the following:
e.stopImmediatePropagation();
window.event.cancelBubbles = true;
e.bubbles = false;
none seemed to work.
I reproduced this issue with JSFiddle:
JSFiddle
In this case, there is no event bubbling occuring because you have different events defined on different elements that just so happen to both fire when a mouse clicks on the check box (because you have also clicked a row).
You should either not add the row click event listener at all, or move stopPropagation to the the other handler to stop it from firing.
$(document).ready(function() {
$('body').off('click.row').on('click.row', '.row', function() {
e.stopPropagation();
alert(1);
});
$('body').off('change.cb').on('change.cb', '.cb', function(e) {
alert(2);
});
});

How to bind a .click() event only the container?

I want the user entry to open up accordion-style, but a .click() event is triggered even if I click on any other element inside the red box - the text, the image, etc.
I'd like to only have the "outer" whitespace cause the event to trigger.
How do I accomplish this?
$('#box').click(function(e) {
console.log(e);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box" style="width:80%;background:red;">
<table>
<tr>
<td><img src="http://i.imgur.com/NaCmGyX.jpg" style="width:50px;height:50px;border-radius:50%;"></td>
<td><b>John McDerpenstein</b></td>
<td><p>
A blurb goes here
</p></td>
</tr>
</table>
</div>
fiddle
You can check the target property of the event to see if it was the #box element directly by using is():
$('#box').click(function(e) {
if ($(this).is(e.target))
console.log(e);
});
Updated fiddle
<html>
<body>
<div id="box" style="width:80%;background:red;">
<table>
<tr>
<td><img src="http://i.imgur.com/NaCmGyX.jpg" style="width:50px;height:50px;border-radius:50%;"></td>
<td><b>John McDerpenstein</b></td>
<td><p>
A blurb goes here
</p></td>
</tr>
</table>
</div>
<script src="jquery-1.12.3.min.js"></script>
<script>
$('img').click(function(e) {
console.log(e);
});
</script>
</html>
Just check the e.target.id to see if it matches the specific id of the outer box you want. Example below:
$('#box').click(function(e) {
if (e.target.id === "box")
console.log('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box" style="width:80%;background:red;">this is the outer box
<table>
<tr>
<td><img src="http://i.imgur.com/NaCmGyX.jpg" style="width:50px;height:50px;border-radius:50%;"></td>
<td><b>John McDerpenstein</b></td>
<td><p>
A blurb goes here
</p></td>
</tr>
</table>
</div>
If you want to add the event to the parent container you will have to stop the propagation on all the child elements that will not need a click event .
Example :
since #box has the click and box is your container
you will need to give image an id and stop the propagation
$('#imageID').click(function(e){
e.stopPropagation();
})
With the example above when you click the image nothing will happen , but if you click the red container then your event will log.
The best way is to prevent the event if the click is done on child:
$('#box').click(function(e) {
if (!$(this).is(e.target)) {
return e.preventDefault()
}
// code here (or nothing, href="" action)
});

How to stop running the next function?

I have an event on clicking the top <tr> and then also an event on clicking the tr > td > button. When i click the tr > td > button, the related onclick() function is running but, the function related on <tr> is also running after previous.
Like:
<tr onclick="run_tr();">
<td><input type="button" onclick="run_td();" /></td>
</tr>
How can i stop automatically calling the next call by clicking the button?
At button onclick function you need to stop event bubbling:
event.stopPropagation();
Following to your code:
HTML:
<input type="button" onclick="run_td( event );" />
JS:
function run_td( event ) {
if ( event.stopPropagation ) {
event.stopPropagation();
}
event.cancelBubble = true;
// ... rest of your code.
}
You have to stop the event's propagation, by using the method e.stopPropagation(). For more info, check out this link : http://www.quirksmode.org/js/events_order.html#link9
I don't understand why you can't use the recommended methods, here's an example:
<div onclick="alert('div click called');">
Click here to see div onclick
<button onclick="
(event.stopPropagation && event.stopPropagation());
event.cancelBubble = true;
alert('stopped click');
">Button click but no div click</button>
</div>

Categories

Resources