I am trying to bind some functions to some input fields. The weird part is, if I add the .change event to the inputs it fires just fine but when I add the '.keyup' on the same inputs the event does not fire.
Note: Yes the inputs are found in a document ready function. I also commented out the .unbind method and that did not fix the issue. The only reason that is there is so I can call the this method later and the inputs will not be bound twice.
here is what I am using:
bindInputChange: function()
{
var inputs = jQuery(':input');
if(inputs != null)
{
inputs.unbind();
}
inputs.change(function() { alert('change called'); }); // this one works
inputs.keyup(function() { alert('keyup called'); }); // this one does not
},
any ideas? Thanks!
It turns out that I have another function that makes anything you type uppercase and that function has an .unbind which was removing the .keyup. After removing the .unbind everything worked. Thanks for all the help!
Related
I wrote some code for a custom confirm box that calls a function when confirm button (yes-button) is pressed and passes another function as a parameter and I bind it to 2 different button clicks with different functions as a parameter. For example:
$('#button1').click(function() {
callFunction(function() { alert("test"); });
});
$('#button2').click(function() {
callFunction(function() { alert("test2"); });
});
function callFunction(callback) {
//code to display custom confirm box
console.log(callback);
$('.confirm-box .yes-button').click(function() {
callback();
});
}
Everything happens as expected, confirm box appears and on confirm button click I get a callback function executed and it alerts "test" (or "test2" depending on which button called the confirm box). The problem arises when I click button1 that sends a function that alerts "test", then instead of confirming I cancel that (nothing happens as expected), and then click button2 that passes alert("test2") as a callback function. Now once I press the yes-button instead of alerting just "test2", I get both "test2" and "test" alerts even though that console.log I wrote logs just the function that alerts "test2" at the time of that button2 click. It seems like these callback functions get stacked somewhere, but I don't understand where and why.
The .click() function can add more than one handler to an element, and I think that's what's happening here. Try this:
// ...
$('.confirm-box .yes-button').unbind('click').click(function() {
callback();
});
This removes any previous click handler before applying the new one.
When you execute the code:
$('.confirm-box .yes-button').click(function() {
callback();
});
you are binding an event handler to the .yes-button element. If you run that code twice, it will have two events bound to it. And so on.
One solution is to use .one instead, so that the event handler will be removed after the first time it is fired:
$('.confirm-box .yes-button').one("click", function() {
callback();
});
This of course has issues if there are two confirm boxes open simultaneously or if there are two .yes-button elements, but for a simple use case it works fine.
What is happening is that each time a button is clicked the callFunction method is executing. It runs through that code block and applies an event listener to the $('.confirm-box .yes-button') button. So clicking your button N times will apply the click listener N times as well. One solution is to store the function in a variable.
Not sure what the end goal is, but this is one solution.
Another solution would be to remove buttons event listeners each time.
var functionToCallOnYes = function() {};
$('#button1').click(function() {
functionToCallOnYes = function() {
alert("test");
};
});
$('#button2').click(function() {
functionToCallOnYes = function() {
alert("test2");
};
});
$('.confirm-box .yes-button').click(function() {
console.log(functionToCallOnYes);
functionToCallOnYes();
});
You can do it by setting an identity by classes,
var button = $('.confirm-box .yes-button');
$('#button1').click(function() {
button.removeClass("b").addClass("a");
});
$('#button2').click(function() {
button.removeClass("a").addClass("b");
});
button.click(function() {
if($(this).hasClass("a")){
callBackForButton1();
} else {
callBackForButton2();
}
});
It is a bad practice to stack up the event handler for a single element.
Yes, extra callbacks are getting stacked up. In $('button1').click(f), the function f will be called with no parameters every time button1 is clicked. In this case, f is callFunction-- a function that itself attaches a new handler to any .confirm-box .yes-button element each time it's invoked. So on the Nth click, you should have N-1 alerts.
To make things like this easier, you can refer to functions by name in JavaScript. So if you had function test() { console.log("test"); };, you could write $(".confirm-box").click(test) just once and every click on a .confirm-box from then on would print test to the console.
Usually if you have callbacks whose sole purpose is to call a callback, you can just remove that callback.
Got this piece of code, which works great. However the .trigger('change') is not working.
$(function () {
$('form').each(function () {
var form = $(this);
form.find('.cbox1').change(function () {
if (form.find('.cbox1:checked').length) {
form.find('.cbox2, .cbox3').button("enable");
} else {
form.find('.cbox2, .cbox3')
.prop("checked", false)
.trigger("change")
.button("refresh")
.button("disable", "disable");
}
});
});
});
I know this is probably something simple, but for a noob like me, it's killing me, been reading and studying for days...
Any knowledge/assistance is greatly appreciated,
Si
It works fine. Try adding this line and you'll see that cbox2 change is triggered.
$('form').find(".cbox2").on("change", function() {alert("cbox2 triggered")});
When you are triggering a change, you are triggering it on .cbox2 and .cbox3. However you have not added any listener for the change event on these elements. The listener for change event is attached only to .cbox1. If that is the listener you want to trigger, then call the the trigger("change") on .cbox1 or add event listeners for the other two elements.
I'm trying to set a textbox to 'readonly', add a class, and put a text into the textbox at that moment when I check the checkbox. Moreover, I'm also trying to remove 'readonly' attribute from the textbox, add a class, and delete text in the textbox.
I have
$('#CheckBoxSectionCode').click(function () {
if ($(this).is(':checked')) {
$('#TextBoxSectionCode').attr('readonly', 'readonly');
$('#TextBoxSectionCode').addClass('disabled');
$('#TextBoxSectionCode').text(document.getElementById('TextBoxSectionName').val);
}
else {
$('#TextBoxSectionCode').attr('readonly', false);
$('#TextBoxSectionCode').addClass('abled');
$('#TextBoxSectionCode').text('');
}
});
This code doesn't work for me.
Thanks,
Phillip
Thanks everyone for answers.
According to your comments and answers, I've changed my code but it's still not working.
$('#CheckBoxSectionCode').click(function () {
if ($(this).is(':checked')) {
$('#TextBoxSectionCode').prop('readonly', true);
$('#TextBoxSectionCode').addClass('disabled');
$('#TextBoxSectionCode').text('disabled');
}
else {
$('#TextBoxSectionCode').prop('readonly', false);
$('#TextBoxSectionCode').removeClass('disabled').addClass('enabled');
$('#TextBoxSectionCode').text('');
}
});
I'm using chrome browser to run this code, and using developer tools in chrome and put a break point at the code above to see what's happening in the jquery. However, when I click the check box to check/uncheck, nothing happens there.
document.getElementById('TextBoxSectionName').val this is wrong. You really should cache your jQuery object so it's not navigating the DOM over and over. Then you mix in native JS and .val is not a DOM property or method, nor is it a jQuery property, it should be .value for a DOM object or .val() for a jQuery object.
Obligatory explanation by #Archy Wilhes:
"Just to clarify; when #SterlingArcher says caching the jQuery object,
she/he means doing something like var obj = $('#TextBoxSectionCode')
then calling the functions using the variable like this:
obj.attr(...); obj.addClass(...). Every time you do a $(something) you
are calling a function in jQuery that looks for the DOM."
since everytime you are adding the class the element is going to end up having both the two classes. Consider removing the other class before adding one. For example,
$(selector).removeClass('disabled').addClass('enabled')
Try with change event instead of click:
$('#CheckBoxSectionCode').change(function () {
if ($(this).is(':checked')) {
$('#TextBoxSectionCode').attr('readonly', 'readonly');
$('#TextBoxSectionCode').addClass('disabled');
$('#TextBoxSectionCode').text(document.getElementById('TextBoxSectionName').val);
}
else {
$('#TextBoxSectionCode').attr('readonly', false);
$('#TextBoxSectionCode').addClass('abled');
$('#TextBoxSectionCode').text('');
}
});
You could do the following way.
//Cache reference to DOM as DOM scan is expensive!
var textBox = $('#TextBoxSectionCode');
$('#CheckBoxSectionCode').click(function () {
//Use prop as opposed to attr
textBox.prop("readOnly", false).removeClass('disabled').addClass('abled').text("");
if ($(this).is(':checked')) {
textBox.prop("readOnly", true).removeClass('abled').addClass('disabled').text($("#TextBoxSectionName").val());
}
});
var id=100;
for(var i=0;i<5;i++) {
$("#divtext_"+id).click(function(e) {
onClicked();
});
}
function onClicked() {
alert("Clicked")
}
I tried with .on() , delegate(), and one() events.
When I clicked div, the onClicked() function gave an alert() 4 times.
Is it possible when I click div text/image to get one time function/alert?
This is how I would expect the code to run under jquery, the options here would be to either use .unbind (http://api.jquery.com/unbind/) to remove all previous instructions for this div or to check if the event has already been bound, this has been covered here. How to check if click event is already bound - JQuery
Presuming you have divs with IDs divtext_0 ... divtext_4
for(var i=0;i<5;i++) {
$("#divtext_"+i).click(function(e) {
onClicked();
});
}
function onClicked() {
alert("Clicked")
}
At the moment you are adding multiple click handlers to the div divtext_100 - rather than adding one click handler to multiple divs.
It is hard to say what is best without seeing your HTML - but if you gave all your divs a class, e.g. 'clickable', then you can avoid any loops and make any div with that class clickable.
<div class="clickable"></dvi>
You could simply do.
$(".clickable").click(function(e) {
onClicked();
});
function onClicked() {
alert("Clicked")
}
try this:
$("#divtext_"+id).one("click", function(e){
onClicked();
});
You can use
$("#divtext_"+id).off('click',onClicked).on('click',onClicked);
function onClicked() {
alert("Clicked")
}
'.off' prevents binding of onClicked function multiple times. I think using .off will solve your problem.
If you are using older version of jquery then use .unbind.
div.onclick = function(data, dom) {
return function() {
if (data.seenAlready == true) { // HACK
$(this).children().toggle();
return;
}
recursiveSearch(data, dom);
// after this onclick, I want to assign it to a toggle like function. no clue how to do it.
}
}(child, mycontainer.appendChild(div));
I'm trying to swap the onclick method after first onclick on a dom element. I've just not had any success, it seems to some sort of closure loss, or something. I'm fine using jQuery.
You have two ways to do this and both ways are by using a jQuery function:
1) Use one API method - this will work just once. You will click it once and then you choose your own second handler and the first one will not fire again e.g.
$(myselector).one(function(){
$(this).click(myotherhandler);
});
Here is the link to this API http://api.jquery.com/one/.
2) You can choose the following way to replace the event handler .
$(myselector).click(function(){
$(this).off();
$(this).click("secondhandler");
});
this will turn the first handler off and will just fire second handler
Check this jsbin:
http://jsbin.com/fekuq/1/edit?html,js,output