How to prevent multiple event calling with jQuery on change - javascript

The problem is that sometimes on select change $('selector').on('change', ...) function is fired multiple times.
Generally when I'm using .on function then I always add .off() function and it works great. But in this case I can't use the off function due to the fact that off function is disabling the select input (I mean that it does not change).
I've tried to add event.preventDefault() and event.stopImmediatePropagation() but it is not the solution.
JS:
$('#addMealToMenuDiet').on('change', function(event) {
//then ajax function is called
});
HTML:
<select id="addMealToMenuDiet" class="form-control">
...
</select>
How can I avoid such a situation?
Solution
Unfortunately my on change method was placed in another on click method. Therefore it was called multiple times...

most possibly your code runs multiple times, you could simply always unbind the event before you bind it just put your ajax stuff into a function in before your other code
function myAjaxfunction(){
//...
}
and then run this to initialize your select
$(document).off("change", '#addMealToMenuDiet', myAjaxFunction).on("change", '#addMealToMenuDiet', myAjaxFunction)
this way you are on the save side ;)

Related

Is it possible to execute an inline click event function without executing a click event?

Explaining by example:
$(".myCheckboxes").click(function () {
...
});
Inside the click event function I have code that does various things depending on what checkboxes are checked.
I however need to run this code to initialize it first, kindof like this:
$(".myCheckboxes").click(function () {
...
}).click();
It runs the code and it gets initialized, but it also clicks on all my checkboxes making them all invert their value.
Is it possible to execute the inline click event function wihtout executing a click event?
I would very much like to keep the function inline to keep the flow of the code. Also, it's not big enough to have the function outside of the event, but it's not so small as I would like to write the code twice.
triggerHandler triggers only the handler:
$(".myCheckboxes").click(function () {
...
}).each(function(i, checkbox) {
$(checkbox).triggerHandler('click');
}
Note that you need to iterate the checkboxes if you wish to trigger the handler for all of them instead of just the first one:
while .trigger() will operate on all elements matched by the jQuery
object, .triggerHandler() only affects the first matched element.
Use a named function as the handler, bind it and execute it:
$(".myCheckboxes").click(clickHandler);
clickHandler();
You may consider to call the function triggerHandler who seems to do what you need.
$(".myCheckboxes").click(function () {
...
}).triggerHandler('click');
NB: I haven't tested this solution.

jQuery event firing twice after .load()

I've come across an issue where jQuery events fire twice after $.load() is called. The event handler is placed in the load() callback function, and this seems to be the only place where events fire twice on the script.
I've tried adding event.stopPropogation() and event.preventDefault(), as these seem to be common suggestions with jQuery events firing more than one. I'm not sure if my code is bubbling improperly or what. Any feedback would be helpful.
Here's an extract of some of the code where you see the behavior.
$("div.questions").load("question_source.php #simplified_a", function(){
...
// Line 1
$("#some_id").change(function(){
cantBeNegative(this);
adjusted_gross_income = $(this).val();
console.log(adjusted_gross_income);
// event.stopPropagation();
// event.preventDefault();
});
You can clearly see the event firing twice with the console.log bit I've got in there. Any advice would be appreciated!
EDIT
OK, I checked through everything on the live page based on some of the suggestions, and there's definitely only one <div id="questions"> in existence when the problem is occurring. So, it doesn't appear to be an HTML problem.
I also checked to see if the event was actually being called twice, and as far as I can tell, the event is only being called once.
Now, I added a .on() event attached to the document which is called on the dynamically created elements, and that only fires once. .on() is not called within the .load() callback. Here's an example used on one of the other input boxes on the page which works without any problems:
$(document).on('change', "#SWA_mothers_income", function(){
console.log("mothers income changes from on()");
});
So, that works properly, but when tested on the same input within the .load() callback function, it fires twice, regardless of how it's called. So, it seems to me that it's almost certainly an issue with .load(). I wouldn't exactly call myself an expert in this, so if someone can figure out the issue, I'd love to know the answer. As it stands, I'm going to rewrite this code using .on().
SECOND EDIT
Adding $("#some_id").unbind('change');
before the 'change(function()) bit did the trick!
add this line
$("#some_id").unbind('change');
before
$("#some_id").change(function(){});
I'm not saying this will solve your problems but you need to pass in the event to reference it.
$("#some_id").change(function(event){
cantBeNegative(this);
adjusted_gross_income = $(this).val();
console.log(adjusted_gross_income);
event.stopPropagation();
event.preventDefault();
});
It's possible that you have two divs with a class of 'questions', so you could be binding the change function twice.
If you update your change function to the below, this will unbind the change event before re-adding it. This will make sure you only have the function bound once;
$("#some_id").unbind('change').change(function(event) {
event.preventDefault();
cantBeNegative(this);
adjusted_gross_income = $(this).val();
console.log(adjusted_gross_income);
});

Is there any way to use javascript (jquery) to make an element behave **exactly** as if it was clicked (a unique situation)

I want to make 'select' element to behave as if it was clicked while i click on a completely different divider. Is it possible to make it act as if it was clicked on when its not??
here is my code
http://jsfiddle.net/fiddlerOnDaRoof/B4JUK/
$(document).ready(function () {
$("#arrow").click(function () {
$("#selectCar").click() // I also tried trigger("click");
});
});
So far it didnt work with either .click();
nor with the .trigger("click");
Update:
From what i currently understand the answer is no, you cannot. Although click duplicates the functionality it will not work for certain examples like this one. If anybody knows why this is please post the answer below and i will accept it as best answer. Preferably please include examples for which it will not work correctly.
You can use the trigger(event) function like ("selector").trigger("click")
You can call the click function without arguments, which triggers an artificial click. E.g.:
$("selector for the element").click();
That will fire jQuery handlers and (I believe) DOM0 handlers as well. I don't think it fires It doesn't fire handlers added via DOM2-style addEventListener/attachEvent calls, as you can see here: Live example | source
jQuery(function($) {
$("#target").click(function() {
display("<code>click</code> received by jQuery handler");
});
document.getElementById("target").onclick = function() {
display("<code>click</code> received by DOM0 handler");
};
document.getElementById("target").addEventListener(
'click',
function() {
display("<code>click</code> received by DOM2 handler");
},
false
);
display("Triggering click");
$("#target").click();
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
And here's a version (source) using the onclick="..." attribute mechanism for the DOM0 handler; it gets triggered that way too.
Also note that it probably won't perform the default action; for instance this example (source) using a link, the link doesn't get followed.
If you're in control of the handlers attached to the element, this is usually not a great design choice; instead, you'd ideally make the action you want to take a function, and then call that function both when the element is clicked and at any other time you want to take that action. But if you're trying to trigger handlers attached by other code, you can try the simulated click.
Yes.
$('#yourElementID').click();
If you added the event listener with jquery you can use .trigger();
$('#my_element').trigger('click');
Sure, you can trigger a click on something using:
$('#elementID').trigger('click');
Have a look at the documentation here: http://api.jquery.com/trigger/
Seeing you jsfiddle, first learn to use this tool.
You selected MooTools and not jQuery. (updated here)
Now, triggering a "click" event on a select won't do much.
I guess you want the 2nd select to unroll at the same time as the 1st one.
As far as I know, it's not possible.
If not, try the "change" event on select.

JavaScript will not run a second time

I am running a script using $(document).ready() it is performing the way I want it to on load up, however, the same script needs to be ran when an html select control is changed.
What I need ultimately is for the filter and sort to run on initial load with sorting on Low to High, and then after the page is loading the user should be able to select any select control and filter and sort as they wish.
Go to http://webtest.ipam.ucla.edu to view the code and on the bottom of the page you can download the folder with all of the files.
How do I fix this?
You can put all your reusable logic into a function:
function myPrettyJavaScriptLogic () {
// All the code that you want to reuse in here
}
Then you can call the above function both from document.ready() and also from the onchange handler of your select control.
Create a function outside of your doc ready closure and call it when you need to. Example is jQuery but doc ready is the same event:
var doSomethingCool = function( coolStuff ) {
// Do cool stuff
}
$(function(){
doSomethingCool( $(this) );
$('#selectControlId').change(function(e){
doSomethingCool();
});
});
Since you are referencing the .ready function I'm assuming you are actually using jQuery.
$(document).ready() or jQuery(document).ready()
Anything within the ready() function will only be called once - when the page is loaded. It waits until the entire DOM is loaded before executing that code.
You can extract out your functionality to a separate function to get kicked off based on your select control changing.
You may benefit from reading a jQuery tutorial I wrote the other week:
http://chadcarter.net/jquery-goodness/
Also, the actual .change event in the jQuery API is here:
http://api.jquery.com/change/
Assuming you want the functionality to be called when the page loads and when the option is changed you will want to create a new function and have that function called inside of both the .ready and the .change functions.
Hope this helps!
put your script in a Named function. call it in domready and select.change().
You will need to set up a handler for the select box's onChange event. What I would do is pull out the code you need to execute into a separate function and then do something like
function dostuff(){
//do whatever you need to
}
$(document).ready(function() {
dostuff();
}
<select onchange"dostuff()" >... </select>
Note this was quick and dirty, just to give you an idea.
Check out this link for more about select's onchange.
If you are using jQuery, which I will assume you are because of this syntax, you just have to bind the event onchange to the element.
$("element").bind("change", function() { /* your logic */ });
You have to run this code after the element is rendered. If you place this code inside the $(document).ready there will be no problem. but the whole page will have to load before the even is bound.
So you can do the following:
<select id="sel">
<option>A</option>
<option>B</option>
</select>
Then bind the event change.
$(function() { /* equivalent to document.ready */
$("#sel").bind("change", function() {
/* code that runs when the selection change */
});
});
Thank you all for your help, this is now fixed. The way i did it was to encapsulate the $(function(){}) in another function (filtersortProcess()) and then created another script that autoselects the Low to High option and calls filtersortProcess() on windows.load.
Within the $(function(){}) I added a variable (complete) and set it to 1 when it goes within the actual filter process, then after the filter process (if the code exits before completing the process) I check for the complete variable and do a simple filter and sort on the data and with all of this it works great.
Thank you again.

jquery ajax events called on every element in the page when only targeted at one element

So, you have a page:
<html><head>
<script type="text/javascript" src="jquery.1.3.2.js"></script>
<script type="text/javascript">
$(function() {
var onajax = function(e) { alert($(e.target).text()); };
var onclick = function(e) { $(e.target).load('foobar'); };
$('#a,#b').ajaxStart(onajax).click(onclick);
});
</script></head><body>
<div id="a">foo</div>
<div id="b">bar</div>
</body></html>
Would you expect one alert or two when you clicked on 'foo'? I would expect just one, but i get two. Why does one event have multiple targets? This sure seems to violate the principle of least surprise. Am i missing something? Is there a way to distinguish, via the event object which div the load() call was made upon? That would sure be helpful...
EDIT: to clarify, the click stuff is just for the demo. having a non-generic ajaxStart handler is my goal. i want div#a to do one thing when it is the subject of an ajax event and div#b to do something different. so, fundamentally, i want to be able to tell which div the load() was called upon when i catch an ajax event. i'm beginning to think it's not possible. perhaps i should take this up with jquery-dev...
Ok, i went ahead and looked at the jQuery ajax and event code. jQuery only ever triggers ajax events globally (without a target element):
jQuery.event.trigger("ajaxStart");
No other information goes along. :(
So, when the trigger method gets such call, it looks through jQuery.cache and finds all elements that have a handler bound for that event type and jQuery.event.trigger again, but this time with that element as the target.
So, it's exactly as it appears in the demo. When one actual ajax event occurs, jQuery triggers a non-bubbling event for every element to which a handler for that event is bound.
So, i suppose i have to lobby them to send more info along with that "ajaxStart" trigger when a load() call happens.
Update: Ariel committed support for this recently. It should be in jQuery 1.4 (or whatever they decide to call the next version).
when you set ajaxStart, it's going to go off for both divs. so when you set each div to react to the ajaxStart event, every time ajax starts, they will both go off...
you should do something separate for each click handler and something generic for your ajaxStart event...
Because you have a selector with two elements, you're creating two ajaxStart handlers. ajaxStart is a global event, so as soon as you fire any ajax event, the onajax function is going to be called twice. So yes, you'd get two popups.

Categories

Resources