jQuery off() not removing click handler - javascript

I have the following code:
$(document).ready(function () {
EnableModal();
});
function EnableModal() {
if (isModalEnabled) { return; }
// Initialize modal dialog
// attach modal-container bootstrap attributes to links with .modal-link class.
// when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog.
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
}
function DisableModal() {
$('body').off('click', '.modal-link');
}
I am attempting to turn this off under certain circumstances, so I am calling:
$('body').off('click', '.modal-link');
However, the button with the modal-link class is still allowing click events through. I see no errors in the developers console.
I have verified it is calling these correctly and that each is only being called once in my test case.
What am I doing wrong here?

I met this issue before. I wasn't sure what happened at the very beginning and wonder if it was because the selectors weren't actually the same. I checked them and found out they were the same but still couldn't remove the event handler.
I finally fixed this by giving a dummy function as event handler after I removed the original one.
function DisableModal() {
$('body').off('click', '.modal-link');
$('body').on('click', '.modal-link', () => {});
}
Feel free to use ES5 version if you don't like the lambda expression. as
$('body').on('click', '.modal-link', function(){});

Works fine here:
var isModalEnabled;
$(document).ready(function () {
EnableModal();
$(".disableModal").click(DisableModal);
});
function EnableModal() {
if (isModalEnabled) { return; }
// Initialize modal dialog
// attach modal-container bootstrap attributes to links with .modal-link class.
// when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog.
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
}
function DisableModal() {
$('body').off('click', '.modal-link');
}
body { font-family: sans-serif; }
[data-target='#modal-container'] {
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click a few "Modal Link" buttons, and watch the button text turn bold. Then click the "Disable Modal" button, and click the remaining "Modal Link" buttons. The button text does <em>not</em> turn bold.</p>
<button class="modal-link">Modal Link</button>
<button class="modal-link">Modal Link</button>
<button class="modal-link">Modal Link</button>
<p><button class="disableModal">Disable Modal</button></p>
<button class="modal-link">Modal Link</button>
<button class="modal-link">Modal Link</button>
<button class="modal-link">Modal Link</button>
<p>To reset, click the "Run code snippet" button above.</p>

Without knowing the real cause of this, maybe the solution is to use namespaced events.
$('body').on('click.modal', '.modal-link', function (e) { });
and to remove it
$('body').off('.modal');
But I have a feeling it has nothing to do with this, but with the real issue is with the bootstrap modal. Maybe you need to clean up those attributes.
$('[data-toggle="modal"]').removeAttr("data-target data-toggle");

Related

Prevent onclick from firing

I was working around with form submissions in html. Please take a look at below code
<form id="form1">
<button id="btn1" onclick="clicked();">Submit</button>
</form>
<script>
$("#btn1").click(function (event) {
alert("event triggered");
if(some_condition == true){
// stop firing onclick method but it always submits the form
event.stopImmediatePropogation(); // not working
event.preventDefault(); // not working
event.stopPropogation(); // not working it's for bubbled events
}
});
function clicked(){ alert("clicked me"); }
</script>
I want to stop clicked() function from firing which is attached to inline onclick attribute. I would like to run my jquery click function and if something goes wrong, I dont want to trigger onclick but it always runs clicked() function. Could any one help me. Any help is greatly appreciated.
The order in which an onxyz handler is called relative to dynamically-attached handlers varies from browser to browser, so your handler may well not run before the original does.
To deal with that, you save and remove the onclick handler:
var btn = $("#btn1");
var clickHandler = btn[0].onclick;
btn[0].onclick = false;
Then, in your handler, if you want that function to be called, you call it:
clickhandler.call(this, event);
Example:
// Get the button
var btn = $("#btn1");
// Save and remove the onclick handler
var clickHandler = btn[0].onclick;
btn[0].onclick = false;
// Hook up your handler
$("#btn1").click(function(event) {
alert("event triggered");
if (!confirm("Allow it?")) {
// Disallowed, don't call it
alert("stopped it");
} else {
// Allowed, call it
clickHandler.call(this, event);
}
});
// The onclick handler
function clicked() {
alert("clicked me");
}
<form id="form1" onsubmit="return false">
<button id="btn1" onclick="clicked();">Submit</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Try event.stopPropagation()
api docs
if condition is true then remove the 'onclick' attribute
if (some_condition == true) {
$("#btn1").removeAttr('onclick').click(function(event) {
alert("event triggered");
//do something
});
}
function clicked() {
alert("clicked me");
}
I am sharing a quick workaround without knowing why you cannot add logic to stop adding "onclick="clicked();" code which you are saying getting automatically added.
I recommend you hide button with id as "btn1". Add style display:none. You donot need on ready function for this but simply add style attribute to the button btn1 or if that is also not possible directly then use jQuery to do that post document ready.
Read :
How to change css display none or block property using Jquery?
Then add a new button to the form using jQuery with id as "btn2" and add register the btn2 click event as well. DO this after form load.
<form id="form1">
<div id="newbut">
<button id="btn1" onclick="clicked();">Submit</button>
</div>
</form>
jQuery("#newbut").html('<button id="btn2">Submit</button>');
$(document).on('click', '#btn2', function(){
// Your Code
});
Refer below url to how to register click event for new button:
Adding click event for a button created dynamically using jQuery
jquery - Click event not working for dynamically created button
Can't you do the condition check and the clicked() logic in one function? i.e
<script>
function clicked() {
if(some_condition == true){
return;
}
alert("clicked me");
}
</script>

Jquery.Change not working

I am having some trouble with $.change in jQuery.
HTML
<button class="btn">Reset</button>
<p id="chg" class="change">Click Me</p>
<div class="onchange"></div>
JS
$('.btn').on('click', function() {
$('.change').text('Click Me');
$('.onchange').text('');
});
$('.change').on('click', function() {
$('.change').text('Nearly There');
});
$('.change').on('change', function() {
$('.onchange').text("Nice One");
});
Here is the link to Codepen
Basically what should happen is when "Click Me" is clicked the text will change to "Nearly There" then straight after "Nice One" should appear below.
However this isn't happening, I've tried both
$('.change').on('change', function() {});
$('.change').change(function() {});
And neither work.
Note
The code I have supplied is my test code, and is all relevant to what I'm trying to achieve.
Update
I wasn't aware the .change only worked for form controls, which would explain why it wasn't working.
Solution
CreMedian - Suggested the solution that I was looking for.
$('.change').on('DOMSubtreeModified', function() { });
I have updated the CodePen for future reference.
As indicated in the comments, the .change() event does not work with div elements.
One way you could get the same effect is with the following code:
$('.change').bind("DOMSubtreeModified",function(){
//action you want when the '.change' object changes
});
Javascript MutationEvent is not widely supported, so be careful if implementing this in production code.
Reference Link: http://help.dottoro.com/ljrmcldi.php
$('.change').on('change', function() {
in your example, .change is a div, and divs dont raise change events when clicked.
You probably wanted to just update both elements from the click event
$('.btn').on('click', function() {
$('.change').text('Click Me');
$('.onchange').text('');
});
$('.change').on('click', function() {
$('.change').text('Nearly There');
$('.onchange').text("Nice One");
});
Try with DOMSubtreeModified event.
$('.btn').on('click', function() {
$('.change').text('Click Me');
$('.onchange').text('');
});
$('.change').on('click', function() {
$('.change').text('Nearly There');
});
$('.change').on('DOMSubtreeModified', function() {
$('.onchange').text("Nice One");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button class="btn">Reset</button>
<p id="chg" class="change">Click Me</p>
<div class="onchange"></div>
Note: It will not supported by IE8 and older.
Demo in CodePen
The browser only fires change events for textbox, check/radio box and select list - all form elements. When something changes within your <div> or <p>, the browser does nothing to notify your javascript. Therefore, the listener .on('change' is not going to ever fire.
Here is a short lists of for elements that raise the event:
TextBox When Enter key is pressed
Radio/Check Box When the state is changed
Select List When the selected item is changed
Here is more on the event: Mozilla MDN onchange
do it like this
$('.change').text('Nearly There').trigger('change');
example
$('.btn').on('click', function() {
$('.change').text('Click Me');
$('.onchange').text('');
});
$('.change').on('click', function() {
$('.change').text('Nearly There').trigger('change');
});
$('.change').on('change', function() {
$('.onchange').text("Nice One");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<button class="btn">Reset</button>
<p id="chg" class="change">Click Me</p>
<div class="onchange"></div>

Why my plugin fires multipe callback or clicks

I am creating my simple jQuery plugin that can be use to attach for any action's confirmation. But facing very strange issue, It work fine for single element click, But when i am going to click for second element which also bind with my plugin it work fine but it's also fires for previous clicked element as well.
(function ($) {
$.fn.BootConfirm = function (options) {
// Establish our default settings
var settings = $.extend({
message: 'Are you sure about this ?',
complete: null
}, options);
var self = this;
var cointainer = '\
<div class="modal fade" id="confirmBoot" role="dialog" aria-labelledby="confirmDeleteLabel" aria-hidden="true">\
<div class="modal-dialog">\
<div class="modal-content">\
<div class="modal-header">\
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>\
<h4 class="modal-title">Confirm action</h4>\
</div>\
<div class="modal-body">\
<p>Are you sure about this ?</p>\
</div>\
<div class="modal-footer">\
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>\
<button type="button" class="btn btn-success btn-ok" id="confirm">Ok</button>\
</div>\
</div>\
</div>\
</div>';
return this.each(function () {
var self = this;
$(this).click(function () {
if (!$('#confirmBoot').length) {
$('body').append(cointainer);
}
if (settings.message) {
$('#confirmBoot').find('.modal-body').text($(this).attr('data-confirm'));
}
$('#confirmBoot').modal({ show: true });
if ($.isFunction(settings.complete)) {
$('#confirmBoot').find('.btn-ok').click(function () {
$.when(settings.complete.call(this, self)).done(function () {
$('#confirmBoot').modal("hide"); // Alerts "123"
});
});
}
});
});
}
}(jQuery));
This is my callback function :
function kaushik(myObject) {
ManageAcriveProducts(myObject);
};
and i am calling it by following way
$('a[data-confirm]').BootConfirm({
complete: kaushik
});
For more detail check this js fidder Jsfiddle. Can anyone one share possible solution or better way to do this. Or is there any better way to achieve this ?
The problem is that you're assigning a click on your btn-ok on every click event on a bootconfirmed object. And each click is linked to the object that has been clicked, so it ends up in your callback every time you click btn-ok.
One simple fix, though I'm not sure it's the best, is to remove the click on your btn-ok after the action is complete. Like this:
$.when(settings.complete.call(this, self)).done(function () {
$('#confirmBoot').modal("hide");
$('#confirmBoot').find('.btn-ok').off('click');
});
Working fiddle: http://jsfiddle.net/ywunutyw/
EDIT:
A little improvement on previous solution, it might need some adjustments, since I didn't look into details, but it should give you some ideas. To prevent adding click events and removing them every time user clicks on a button, you can define the click on modal window outside click behavior of each active/inactive button. And on click of active/inactive you define target that will be used in modal confirmation. Like this:
Just before calling behaviors with this.each:
$(document).on('click', '#confirmBoot .btn-ok',
function (e) {
if ($.isFunction(settings.complete)) {
console.log(self)
$.when(settings.complete.call(this, click_origin)).done(function () {
$('#confirmBoot').modal("hide");
});
}
});
Then on the click event of you active/inactive:
click_origin = e.target;
See fiddle: http://jsfiddle.net/ywunutyw/1/

Close Modal issues

I'm using the following code to open my Modal.
The modal opens as expected - and appends open to the parent class. However, when 'close' is clicked, it doesn't close & close is not added to the class.
Can someone explain why?
<script type="text/javascript">
jQuery(document).ready(function($) {
$window = $(window)
$(".modal-trigger").click(function(e) {
e.preventDefault()
var id = $(e.target).attr("href")
$(id).addClass("open")
$(id).find('.close').click(function(e) {
e.preventDefault()
$(e.target).parent().removeClass(".open")
});
})
});
</script>
My Close button HTML:
<button class="close icon-close"></button>
I don't think that parent() brings you to correct level. Instead try to remove .open class from the element you add this class in the first place, i.e. $(id):
$(".modal-trigger").click(function(e) {
e.preventDefault();
var id = $(e.target).attr("href");
$(id).addClass("open");
$(id).find('.close').click(function(e) {
e.preventDefault();
$(id).removeClass("open");
$(this).off();
});
});
Also you probably want to unbind click event from close button, otherwise it will bind multiple times.

Dynamically add event handler to an href which is also dynamically generated

I have a button and when this button is clicked I need to generate a link dynamically and add a handler to it which shows a twitter bootstrap modal. I tried this:
$(function() {
function showModal() {
$("#myModal").modal("show");
}
$(document).on("click", "#my_btn", function() {
//generating a link a adding a handler to it which is "showModal()"
//.....
$("#my_href").html("Some text123 <a href='#' onclick='showModal();'>test123</a>.");
//.....
})
});
But when I clink a this link the error is being thrown saying
Uncaught ReferenceError: showModal is not defined
I can, of course, move showModal() out of $(function() {...}). But I was wondering, is there a better way to do it? And in general, is this a good way to achieve what I want?
UPDATE:
Even after moving showModal() out of $(function() {...}) it doesn't work, it redirects me to the same page but doesn't show pop up.
Don't use inline Javascript. You've posted a perfect example of how you should be doing this right in your question: Use .on on the containing element.
$(document).on("click", "#my_btn", function() {
$("#my_href").html("Some text123 <a href='#'>test123</a>.");
});
$('#my_href').on('click', 'a', showModal);
Use jQuery delegated event handlers to add the click handler
$(function () {
function showModal() {
$("#myModal").modal("show");
}
$(document).on("click", "#my_btn", function () {
//generating a link a adding a handler to it which is "showModal()"
//.....
$("#my_href").html("Some text123 <a href='#' class='showmodal'>test123</a>.");
//.....
});
$("#my_href").on('click', '.showmodal', showModal)
});
In your case you have a inlined event handler which is calling showModal, this expects a method named showModal in the global scope but you have added the method showModal as a closure method in the dom ready handler.
$(function() {
function showModal() {
alert("Modal");
}
$('<a/>',{
href: '#',
text: "Click Me",
click: function(e) {
e.preventDefault();
showModal();
}
}).appendTo('#my_href');
});
jsfiddle
Here you should attach your event to the body or document not to the button
$("body").on( "click","button[id$=my_btn]", function(){
alert( "hi" );
})

Categories

Resources