change event not stopping - javascript

I am trying to change Country event when (ddlcountry) select value but the change event fire continuously.
$(document).ready(function () {
$('#ddlCountry').on('change', function () {
if ($('#ddlCountry option:selected').index() > 0) {
getStateDetails();
}
});
$('#ddlState').on('change', function () {
if ($('#ddlState option:selected').index() > 0) {
getCityDetails();
}
});
});
$('#ddlCountry').val(data.CountryID).trigger('change');
$('#ddlState').val(data.StateID).trigger('change');
How can I stop this.

I think you would be getting data variable's value in getStateDetails and getCityDetails functions, and so following two lines are getting new values each time:
$('#ddlCountry').val(data.CountryID).trigger('change');
$('#ddlState').val(data.StateID).trigger('change');
And they trigger change event then. And again when you really select any value from these dropdown, the jquery change event triggers and calls those above mentioned functions and then the cycle goes on and on.
To pass value of selected option of dropdowns you can code like this:
$('#ddlCountry').on('change', function () {
if ($('#ddlCountry option:selected').index() > 0) {
getStateDetails($(this).val());
}
});
$('#ddlState').on('change', function () {
if ($('#ddlState option:selected').index() > 0) {
getCityDetails($(this).val());
}
});
Pass their value as an argument in the functions.

Generally while continiously triggering events we can use following to avoid it:
Use off() and on() in a single statement(i.e
.off().on(function(){})).
Moving the Javascript or Jquery code to
other js file.
Hope this helps!

Related

this.id on an Element Event Listener becomes an array of all id's of elements clicked

I have an event listener on all textboxes. When a textbox is clicked, I'd like to open a keyboard. On Enter of the keyboard I'd then like to use the id of the textbox which called it to do some logic. However the id (txtbxId in code) just becomes the first textbox I click, then the second textbox I click in an array.
E.g, the alert becomes 'textbox1' - after second textbox click alert is 'textbox1' 'textbox2'
I've tried to force the variable id to '', to delete it etc. to no avail,
Code snippet here:
$('.textbox').click(function() {
var txtbxId = this.id;
$("#Keyboard").show();
$(document).on('keydown', function(e) {
if (e.which === 13) {
alert(txtbxId);
}
});
});
});
The issue is because you're nesting events. Therefore as well as duplicating the keydown event when a click event happens, you're supplying each individual id to those events.
To fix this, use a single event handler for all the .textbox elements, and read their own id from the reference to the element which raised the event which is available through the this keyword:
$('.textbox').click(function() {
$("#Keyboard").show();
});
$(document).on('keydown', '.textbox', function(e) {
if (e.which === 13) {
alert(this.id);
}
});
The problem is that your on('keydown') function the first time you click a textbox never gets unassigned, so for every time you click a .textbox, you're making a NEW keydown callback, but not removing your old ones.
I would recommend making an object outside of your onClick callback which manages .keydown callbacks, so that you only have one at any time.
Something like this:
window.keydownmanager = {
init: () => {
$(document).on('keydown', function (e) {
window.keydownmanager.callback(e);
});
},
callback: () => {},
setCallback: (cb) => {
window.keydownmanager.callback = cb;
}
}
And inside your onClick callback, do this:
var txtbxId = this.id;
$("#Keyboard").show();
window.keydownmanager.setCallback(function(e) {
if (e.which === 13) {
alert(txtbxId);
}
})

toggleClass for different functions

I guess this code does not work, because at DOM load jQuery caches its objects and bind the functions to them?
$('span.button.slide_out').on('click', function () {
$(this).toggleClass('slide_out').toggleClass('slide_in');
$('#testbox').slideDown();
});
$('span.button.slide_in').on('click', function () {
$(this).toggleClass('slide_out').toggleClass('slide_in');
$('#testbox').slideUp();
});
I know I could write this easily with slideToggle or something else, but I have to fire different actions on every first and every second click. How can I achieve this using the same selector (instead of creating two different selectors)?
JS FIDDLE
The binding is indeed done on DOM creation, but that doesn't have to be a problem in this case, it also means that the button is still clicked if it no longer has the slide_out class. Therefore you can reuse the same click event and check the current state to choose whether to slide up or down. For example:
$('.slide_out').on('click', function () {
if($(this).toggleClass('slide_out slide_in').hasClass('slide_in'))
$('#testbox').slideDown();
else
$('#testbox').slideUp();
});
Fiddle
You could use the solution from Event binding on dynamically created elements?, as suggested by https://stackoverflow.com/users/502381/juhana:
HTML:
<span class="button_container"><span class="button slide_out">Click me</span></span>
<div id="testbox">Whohoohoooo, I am slidiiing!<br><br><small>Hey… wait! Why I am not sliding up again?</small></div>
JS:
$('.button_container').on('click', '.slide_out', function () {
$(this).toggleClass('slide_out').toggleClass('slide_in');
$('#testbox').slideDown();
});
$('.button_container').on('click', '.slide_in', function () {
$(this).toggleClass('slide_out').toggleClass('slide_in');
$('#testbox').slideUp();
});
http://jsfiddle.net/ag3cpcfb/
But, in my opinion it would be better to make your code simpler by using slideToggle() and adjust your css classes:
HTML:
<span class="button">Click me</span>
<div id="testbox">Whohoohoooo, I am slidiiing!<br><br><small>Hey… wait! Why I am not sliding up again?</small></div>
JS:
$('.button').on('click', function () {
var $testbox = $('#testbox');
if ($testbox.is(':visible')) {
console.log('Click 1');
} else {
console.log('Click 2');
}
$(this).toggleClass('slide_in');
$testbox.slideToggle();
});
http://jsfiddle.net/k77ferjh/
But this fires "Click 1" all of the time if you repeatedly click on the button. If this is not an issue, fine, if it is, you can also use a number to keep track of your clicks:
JS:
var clicks = 0;
$('.button').on('click', function () {
clicks++;
if (clicks % 2 == 0) {
console.log('Slide out');
} else {
console.log('Slide in');
}
$(this).toggleClass('slide_in');
$('#testbox').slideToggle();
});
http://jsfiddle.net/k77ferjh/1/

jquery onblur not firing

I am trying to get an onblur/onfocus combination working for a pair of text boxes which I am selecting via class in jquery. I am not getting any errors in debug, but the blur function never seems to be called. When debugging my breakpoint in the blur function is not hit.
$(document).ready(function () {
var row = $(this).closest('tr');
$('.editClass').click(function () {
var editBoxes = $(row).find('.editClass');
var focus = 0;
$(editBoxes).focus(function () { focus++ });
$(editBoxes).blur(function () {
focus--;
setTimeout(function () {
if (!focus) {
alert('LOST FOCUS'); // both lost focus
}
}, 50);
});
});
});
Pretty sure the problem here was that the editBoxes were dynamically added to the page. This was not apparent in my question. Since they were dyncamically added I need to use
$(document).on('blur', '.editBoxes', function (){
...
}
The last two lines of your code example should be this
});
});
This is needed for closing the ready and click function call.
Another possible problem is that you wrap the focus and blur listeners in a click handlers. Why did you do this?

How can I apply event handlers to new elements without refreshing the tab?

I have a JQuery function:
$('.btn-cart-toggle').on({
click: function () {
if (!CheckZero()) {
if ($('.cart-bubble').hasClass('active')) {
$('.cart-bubble').removeClass("active");
$('.cart-bubble').addClass("hidden");
}
else {
$('.cart-bubble').addClass("active");
$('.cart-bubble').removeClass("hidden");
}
}
}, mouseenter: function () {
if ($('.cart-bubble').hasClass('active') != true && !CheckZero()) {
clearTimeout(timer);
$('#notificacion-perfil').hide();
if ($('.cart-bubble ul.items li').size() > 0) {
if ($('.cart-bubble').hasClass('hidden')) {
$('.cart-bubble').removeClass("hidden");
}
}
}
}, mouseleave: function () {
if ($('.cart-bubble').hasClass('active') != true) {
if ($('.cart-bubble').hasClass('hidden') != true) {
timer = setTimeout(function () {
$('.cart-bubble').addClass("hidden");
}, 800);
}
}
}, dblclick: function () {
if (!CheckZero()) {
$('.cart-bubble').removeClass("active");
$('.cart-bubble').addClass("hidden");
}
}
});
The CheckZero() function checks if there are li elements inside something and returns true or false.
Everything works fine, but at the moment I add a li element I have to refresh the page to be able of toggling the .cart-bubble classes
you need to use event delegate
$('document').on('click','.btn-cart-toggle',function () {
//your code
});
You can use a syntax like the one you're using but have to modify it a little bit.
Now you have this:
$('selector').on(eventObject)
What this does is to subscribe the events to the selected objects already exisintg in the page.
If you need to subscribe to objects which will existe in the future you have to do it this way:
$('parent selector').on(eventObject,'filter');
If you do it this way you have to specify:
the "parent selector" must select a DOM element which contains all the elements whose events you want to handle
the "filter" must select only the DOM elements whose events you want to handle
No doubt, this will work for you:
$('document').on(eventObject,'.btn-cart-toggle');
But most probably you can choose an element smaller than the document itself.
How does it work? The events bubble up through the DOM element tree. When the event reaches the 'parent object' it checks if the element which started the event fulfills the filter. If so, the event is handled. If not, nothing is done.

Using jQuery $(this) to select anything in this form

have multiple forms on one page but all with the same class name.
I want to make it so that if there is no content in the text area, the submit button is disabled.
This works as you can see here i have done that:
http://jsfiddle.net/WJnqw/
However, this obviously will affect all of the forms with the same submit button classname.
I have tried changing the code to include e.g:
$(this).find(".addcommentbutton").prop("disabled", true);
As i thought that would select the form, and find the add comment button.
But it doesnt work.
Any help?
Thanks!
The problem is that this was the window. You need to pass the context somehow.
Here's a working version that shows two ways of either specifying what this in the function refers to or letting jquery do it:
http://jsfiddle.net/LVf5w/
$(document).ready(function () {
$('.addpostcomment').each(function() {
disableComments.call(this); // specify what "this" will be in the function
});
$(".addpostcomment").keyup(disableComments); //let jquery specify that "this" will be the element
});
function disableComments() {
$(this).closest('form').find(".addcommentbutton").prop("disabled", $(this).val().length < 1);
};
You could also just do this instead of iterating and calling the function:
http://jsfiddle.net/LX2Dj/
$(document).ready(function () {
$(".addpostcomment").keyup(disableComments).trigger('keyup');
});
Or (my preference) do away with the anonymous function altogether:
http://jsfiddle.net/sfuHU/
$(document).ready(function () {
$(".addpostcomment").keyup(function() {
$(this).closest('form').find(".addcommentbutton").prop("disabled", $(this).val().length < 1);
}).trigger('keyup');
});
Note that you have duplicate ids on your elements. The id must be unique.
JSFIDDLE DEMO
You need to use .next() not find & also use this directly in the keyup event
$(this).next('.addcommentbutton').prop('disabled', !($(this).val().length > 0));
// comment form not allow submit when empty
$(document).ready(function () {
disableComments();
$( ".addpostcomment" ).keyup(function() {
$(this).next('.addcommentbutton').prop('disabled', !($(this).val().length > 0));
});
});
function disableComments() {
var commentLength = $('.addpostcomment').val().length;
if (commentLength < 1) {
$(".addcommentbutton").prop("disabled", true);
} else {
$(".addcommentbutton").prop("disabled", false);
}
};

Categories

Resources