Jquery change triggers too often - javascript

I'm using jQuery 1.7.2 and got an on change event for a class like this:
$(document).on('change', '.item_amount', function(){
});
Many selects on the same page have that class and if I change one of those selects the change event triggers X times if I change one of those selects(X is the amount of selects having that class) but I only want it to trigger once since only one select has changed.
Is that normal behaviour or am I doing something wrong?
Edit:
The problem seems to be somewhere else. The elements containing that select get inserted(Ajax call) and when one of them gets inserted into the dom, the change event is triggered for all existing elements.
So basically I got select number 1 which holds some products. When a product is selected HTML code is inserted into a div which holds all current products. When that happens the change event on all products in that div is triggered.

Use this keyword to refer to the current element changed in the change function block.
this --> JavaScript or Native Dom Element.
$(this) ->Your jQuery Object
$(document).on('change', '.item_amount', function(){
alert(this.value);
console.log(this);
});

Set the. on change to the element and pass it as an argument to the function?

Related

JQuery is delayed of one event to retrieve DOM object using `click` event handler

I have two questions on my webapp which are both radio input type but take the appearance and some properties of bootstrap buttons.
At each click I want to check which are the selected two button on the page.
When I click on a label, the tag label receives the class .active (from bootstrap framework I guess). I want to use it to filter which are the selected two buttons at every click of the user.
The problem is that if I click on Option 1, at first click, the button gets active but jQuery can't retrieve the element.
Then If I reclick on option 1 or option2, it will then properly find the element option 1 (even if I clicked on 2).
There is a one step delay between the option I click and what jQuery find.
Here is the JS
Note: I also tried by filtering on the class checked of input tag and observe the exact same behavior
$(function() {
$("label.btn").click(function() {
console.log($("label.active").children()[0].id);
});
})
And here is the pug that generate the HTML
.btn-group(data-toggle='buttons')
label.btn.btn-primary
input#option1(type='radio', name='lorem')
|Option 1
label.btn.btn-primary
...
NOTE :
Waiting for the answer to be edited... the solution is to replace click by change
Probably related to order that the event listeners are added. They will get executed in the order they are added to element.
Try adding small delay.
Example
$('button').click(function(){
var $btn = $(this)
console.log('Has class when clicked = ', $btn.hasClass('active'));
setTimeout(function(){
console.log('Has class after small delay = ', $btn.hasClass('active'));
},20);
}).click(function(){
// will add class after first click handler is fired
$(this).addClass('active')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click me</button>

Change events on dynamically added selects using the Chosen plugin

I'm using the Chosen plugin on my site, and so far it has been working perfectly. However, I'm in a situation where I added a select dynamically and activated the Chosen plugin on those selects. These Chosen selects are being produced fine, but I cannot figure out how to bind a click event to the element. Chosen offers this( $("#form_field").chosen().change( … );) as a way to do something on the change event, however, this does not work since my select was added dynamically.
I have tried $('#el').change and $(document).on("change", "#el", function()) as well without any success.
Original Answer:
From http://harvesthq.github.io/chosen/#change-update-events
"If you need to update the options in your select field and want Chosen to pick up the changes, you'll need to trigger the "chosen:updated" event on the field. Chosen will re-build itself based on the updated content."
$("#form_field").trigger("chosen:updated");
...so just call that after you add the new element.
Edit:
After reviewing this http://jsfiddle.net/amindunited/reh5p0tg/3/
I can see that the issue was that the change() listener for the second select was being attached before that select was added to the page.
I have updated the fiddle code to work:
http://jsfiddle.net/amindunited/reh5p0tg/4/
EDIT
Another way to make it work is to stuff everything inside an init function:
function init_new_content(){
$("#form_field").chosen();
}
init_new_content();
And then call it whenever you know you made a change (for example on ajax)
$.ajax({...},
success: function( data){
init_new_content();
},
...

How to attach onclick event on textboxes?

Hi,
I want to attach on click event on Text Box with value A in attachment and same with B.
I am using dojo toolkit with the following code:
window.onload = function () {
dojo.query('.test').onclick(function(){
alert('test');
});
};
I have a table control having two column name and value both columns contain textboxes.On column name textbox i have added a class with name 'test'.The table rows increase dynamically as shown in attachment.
Now my concern is these textboxes increase dynamically how can i attach event on these textbox.On signle textbox this is working fine but here table rows increase and how can i find particular textbox with same class?
Can anyone help me?
define the function separately.
var myFunc = function() {
alert('test');
};
Now, use it, to attach to text boxes (like you have already done)
dojo.query('.test').onclick(myFunc);
But, while adding new rows, it is your duty to attach this function to the newly added text boxes. You can refer it by the name "myFunc".
Note:-
Running the code piece again - "dojo.query('.test').onclick(myFunc);" will add duplicate handlers for existing textboxes.
If you are adding a large number of handlers or if the information on the screen is dynamic, you'll want to look at using delegated event handlers.
With delegation, you are only adding one handler, which is better for memory usage and you would be adding the handler to the container, not each specific item, which means that the items themselves can safely change without having to re-attach handlers to them.
For more details, I would point you towards this excellent answer: What is DOM Event delegation?

Refresh/Call PrototypeJs Event from jQuery

I have a Magento Website. I have two js files, one written in Prototype an one in jQuery.
I have two select elements, with about 10 options. From jQuery I'm changing the first select's attribute "selected" (an some more). In Prototype I have a class that creates dependencies between two select elements.
If I click on the first select element and choose an option with the mouse, on the second select element will appear only the options that are linked to the option I choosed in the first select element. This is allready done in prototype.
The idea is that I want to do the click/trigger automatically from jQuery. The first select change it's selected option. But the second select element display all the options (and should display only the options linked to the first select element).
On the Prototype file I have some Event Observers, and I guess that these observers are not triggered from jQuery:
var select_el = $('select_' + id);
...
Event.observe(select_el, 'change', this.update.bindAsEventListener(this));
Event.observe(select_el, 'swatches:change', this.update.bindAsEventListener(this));
...
update: function(event) { ...
So I need somehow to trigger these events from jQuery, or to set an autocheck in Prototype.
Please tell me what should I do.
I've read on stackoverflow that events from Prototype can't be triggered from jQuery. There should be a way to do that. I just haven't found it.
I've tried jQuery functions like:
jQuery("option[value='" + checkedId +"']").attr("selected","selected").parent().focus();
jQuery("option[value='" + checkedId +"']").parent().trigger("onchange");
jQuery("option[value='" + checkedId +"']").parent().trigger('change');
Where the "parent()" is the first select element. The first select element changes as I want, but the second select element should automatically change after the first select is changed. And this never happens. It works only if I click with the mouse on the select and choose manually an option. I want to do this from jQuery, without being necessary to manually click on the desired option.
Thanks for reading this, and now just give me a fix for this problem.
Regards.

Identify this item clicked on trigger

I have a menu that is usually clicked by the user. It executes a function
$('.MenuItem').click(function() {
document.writeln($(this).html() + ' was clicked');
});
I have run into a new requirement where I need to trigger the click of a menu item programmatically. So I tried
//I want to trigger click and identify the item that has been clicked. Normally, I just use
//the this object, but on a trigger I don't know how to assign this so `.html()` functions.
//This doesn't work as intended.
//$('.MenuItem').trigger('click','Item1');
How can I identify the item clicked on trigger?
Fiddle
You could do this in a number of ways. If you just want to use an index and click based on that:
$(".MenuItem").eq(1).click();
You could also give them each an ID and click based on the ID.
$('.MenuItem').trigger('click'); //will trigger click event on all elements with .MenuItem ClassName
You need to be more specific such as using an element id
$('#MenuItemID1').trigger('click');
$('.MenuItem:nth-child(1)').trigger('click');
as mentioned you need to specify which element is taking the trigger.
$('.MenuItem').trigger('click');
will in fact trigger the click on both elements.
James answer will work as well. (without altering markup)
I would do this using an index. Based on your html, get the index of the clicked element, then trigger the click event of the target element that also has that given index.
Generally, to get the index of an element, you use .index(), and to select an element by it's index, you use .eq(). Since you didn't post html, I wont be posting a complete sample.

Categories