I have tested many and many solution but any solve my problem.
I have a simple html table. Each row have a edit button.
Jquery is firing many time when I click on the edit button.
Example : I click the first time on a edit button, all work fine. After that, I click on a second edit button and then jquery is firing 2 time, ...
$('.edit').one('click', function(e)
{
e.preventDefault();
e.stopPropagation();
$(this).unbind('click');
var tr = $(this).closest('tr');
var saveUrl = $(this).attr('href');
$('.form-edit').submit(function(e)
{
e.preventDefault();
e.stopPropagation();
console.log($('.form-edit').serialize());
});
});
stopPropagation, return false, unbind, ... change nothing.
What is the problem with my code ?
Simply resolved with this code : unbind then bind
$('.form-edit').unbind('submit').bind('submit', function(event)
{
...
}
Related
I am attaching a onclick function to the button#1 and according to this function i am changing other buttons' opacity and disabling user to click on them.
But I want to undo what has been changed onclick event, making other buttons as normal.
My javascript and jquery code as below;
btnLink.onclick = function(e) {
var divToShow = document.getElementById('linkNewDiv');
console.log('clicked');
divToShow.style.display = 'inherit';
$(btnVideo).prop('disabled',true);
$(btnVideo).addClass('opacityReducing');
$(btnPicture).addClass('opacityReducing');
$(btnPublish).addClass('opacityReducing');
$(btnPicture).prop('disabled',true);
$(btnPublish).prop('disabled',true);
$(btnCheck).addClass('opacityReducing');
}
I couldnt manage to figure it. I found a one way if user clicks outside of the elements I am changing elements style and disable property by writing all these codes again. Any better solutions ? Thanks :)
You can achieve this with stopPropagation(). I made some changes to your code to make it more readable, check this:
$(document).on('click', function(e) {
console.log('clicked');
$('#linkNewDiv').css("display", "inherit");
$(btnVideo, btnPicture, btnPublish).removeClass('opacityReducing').prop('disabled', false);
$(btnCheck).removeClass('opacityReducing');
});
$('#bnLink').on('click', function(e) {
e.stopPropagation();
console.log('clicked');
$('#linkNewDiv').css("display", "inherit");
$(btnVideo, btnPicture, btnPublish).addClass('opacityReducing').prop('disabled', true);
$(btnCheck).addClass('opacityReducing');
});
I have some lis including a links as below
<li>
<span>SomeText</span>
<a href='someurl' class='entityDetailModal'>sometext</a>
</li>
I am using a third party library ('LightGallery') that adds click event on Li, and by Jquery I have add click event to the links to show a dialog.
The problem is when I click on link both click event will be fired,
my click event handler is
$('body').on("click", 'a.entityDetailModal', function (event) {
event.preventDefault();
event.stopPropagation();
loadDialog(this, event, '#mainContainer', true, true, false);
return false;
});
I tried event.stopPropagation() and event.preventDefault(); and return false; in link onclick event handler but they don't work.
Sample:http://jsfiddle.net/HuKab/30/
How can I overcome this?
Update
It seems the problem is the way I add click event handler,
using this way it seems that everything is ok
$('a.entityDetailModal').click(function (event) {
event.preventDefault();
event.stopPropagation();
loadDialog(this, event, '#mainContainer', true, true, false);
return false;
});
Update 2
Thanks #Huangism, this post stackoverflow.com/questions/16492254/pros-and-cons-of-using-e-stoppropagation-to-prevent-event-bubbling is explaining the reason.
Use stopPropagation(); in child element
$("li").click(function (e) {
alert("li");
});
$("a").click(function (e) {
e.preventDefault(); // stop the default action if u need
e.stopPropagation();
alert("a");
});
DEMO
It is not very clear to me what your problem really is. If you simply want to get rid of the click on the li tag you may use .unbind() from jQuery (see: http://api.jquery.com/unbind/). You should end up with only your click event.
Another thing that might help is to use something like:
$("a").on('click.myContext', function(event) {
//Your action goes here
}
This way you can have parallel events and turn them on with $("a").on('click.myContext') and off with $("a").off('click.myContext')
Edit: Use:
$("a").on('click.myContext',function (e) {
e.stopPropagation();
alert("a");
});
see working example: http://jsfiddle.net/bGBLz/4/
I have this sample code here
http://jsfiddle.net/DBBUL/10/
$(document).ready(function ($) {
$('.creategene').click(function () {
$('#confirmCreateModal').modal();
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
});
});
});
If you click the create button 3 times and each time you click yes on the confirmation, the alert is fired multiple times for each click instead of just one time.
If you click the create button 3 times and each time you click no and on the 4th time you click yes the alert is fired for each of the previous clicks instead of just one time.
this behavior seems weird to me as i would expect the alert to be fired once per click. Do I have to use .unbind() or is there a better solution?
Could someone please tell me why this is happening and how to fix it?
Thanks
Because you are binding it multiple times. Click event inside a click event means every time you click, a new click event is being bound on top of the previously bound events. Do not bind click events inside of click events unless the click event creates the element. There's also no need to re-initialize the modal over and over.
$(document).ready(function ($) {
$('#confirmCreateModal').modal({show: false});
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
});
$('.creategene').click(function () {
$('#confirmCreateModal').modal('show');
});
});
Demo
change the code like this
$(document).ready(function ($) {
$('.creategene').click(function () {
$('#confirmCreateModal').modal();
});
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
});
});
fiddle
You dont have to bind $('#confirmCreateYes').click in each button click.
You can try this also -
$("#confirmCreateYes").unbind().click(function() {
//Stuff
});
Add this to your code:
$( "#confirmCreateYes").unbind( "click" );
Like this:
$(document).ready(function ($) {
$('.creategene').click(function () {
$('#confirmCreateModal').modal();
$('#confirmCreateYes').click(function () {
$('#confirmCreateModal').modal('hide');
var test = "123";
alert(test);
console.log(test);
$( "#confirmCreateYes").unbind( "click" );
});
});
});
It will unbind the event, so that it isn't bound on top of the previous event. This allows the event only to fire within the original click event.
This is not a good method. It will unbind all click events attached to the element. I will leave it here for learning purposes.
As of now its the below code worked for me,
$("#parentID").off("click", ".button").on("click", ".button", function(e){
e.preventDefault(); // stop probagation if its button or a href
// your code here
});
After lots of reading posts and fiddling, I thought this was working to attach a doubleclick 'handler' to each row of my jQuery datatable:
$('#myTable').find('tr').dblclick( function(e){
var ref = $(this).find('td:first').text();
someThingToDoWithTextFromFirstCell(ref);
});
Unfortunately, this only seems to work for rows on the first page. I tried doing something like this as a workaround (basically do the same thing when paging):
$('#myTable').on('page', function () {
$('#myTable').find('tr').dblclick( function(e){
var ref = $(this).find('td:first').text();
someThingToDoWithTextFromFirstCell(ref);
});
} );
However, when it fires there are no tr's found so nothing happens. I assume the event is firing before the datatable has new rows?
Does anyone know how I can get this to work?
Here is a JS Fiddle example, Nikola. Thanks for your time. Double click a row and get an alert, click next and double click a row and get no alert.
JS Fiddle example
This is what you can add in for the workaround that doesn't work:
$('#example').on('page', function () {
$('#example').find('tr').dblclick( function(e){
var ref = $(this).find('td:first').text();
alert(ref);
});
} );
You could find answer here.
So, for dynamically created elements you should use:
$(document).on("dblclick", "#myTable tr", function () {
//code here
});
I have the following HTML-table:
<table>
<tr>
<td>
Row 1
</td>
<td>
<!-- Hidden JSF-button -->
<button class="hide" />
</td>
</tr>
</table>
When I click on a tr, I trigger a click on the hidden button with JS:
$('table tr').on('click', function(e) {
var $button = $(this).find('button');
console.log('trigger click on', $button);
$button.trigger('click');
});
The click event propagates up, and will cause a never ending loop (can be seen here: http://codepen.io/anon/pen/kDxHy)
After some searching on Stack Overflow, it is clear that the solution is to call event.stopPropagation,
like this (can be seen here: http://codepen.io/anon/pen/BnlfA):
$('table tr').on('click', function(e) {
var $button = $(this).find('button');
// Prevent the event from bubbling up the DOM tree.
$button
.off('click')
.on('click', function(e) {
console.log('click');
e.stopPropagation();
return true;
});
console.log('trigger click on', $button);
$button.trigger('click');
});
The solution above works. But it feels like a hack, and I don't like it.
Do I have to register a click handler on the on the $button just to call event.stopPropagation? Are there any better way(s) of preventing the click event from bubbling?
A better overall solution would be not to trigger the click event at all but simply have a seperate function that you can call and that encapsulates the event handler logic.
function doSomething(someArg) {
//do something
}
$('button').click(function () {
doSomething(/*pass whatever you want*/);
});
$('table tr').on('click', function () {
doSomething(/*pass whatever you want*/);
});
Please note that doSomething doesn't have an event handler signature such as (e). That's generally a good practice to pass just what's needed to the function to do it's own work, not the whole event object. That will simplify the implementation of doSomething and decouple it completely from the event object.
EDIT:
Sorry, but I need to manually trigger the button click when the user
clicks on a tr. Please see my comment to #magyar1984 question.
In this case you probably found the best solution already, which is to attach an event listener on the button and call stopPropagation. You could also look into getting all click event handlers by using the events data on the element, but beware that you would then be relying on jQuery internals so the code could break in future releases.
Have a look at this question to know how to retrieve the event handlers.
I was able to get it to only register the button click once by updating your codepen to the following:
var handleClick = function(e) {
var $button = $(this).find('button');
console.log('trigger click on', $button);
$button.trigger('click');
};
$('button.hide').on('click',function(e){
e.stopPropagation();
});
$(function() {
$('table tr')
.on('click', handleClick);
});
But the general idea is to declare an onClick event on the button and stop the propagation there.
Modifying buttons behaviour, expecially in frameworks, can cause some unexpected issues. You could add a flag to the row and use it to check if the button should be clicked. But you have to know how many click are automatically generated and should be omitted.
var handleClick = function(e) {
var $button = $(this).find('button');
console.log('triggerring click on...', $button);
if (this.clicked !== true) {
console.log('and clicked!')
this.clicked = true;
$button.trigger('click');
} else
this.clicked = false;
};
Here's the code: http://codepen.io/anon/pen/dJroL