Backbone change event not fired for select field selected by jQuery - javascript

I have a button that when clicked sets the value of a select field and also have a change event for the select field. The 'change select[name=location_id]' event works when selecting normally via mouse/keyboard but clicking the button, which uses jQuery to change the select field value, doesn't fire off the 'change select[name=location_id]' event.
How do I get the 'change select[name=location_id]' to fire when changing the field via jQuery?
SubscriptionsModule.Views.SubscriptionEditView = Backbone.Marionette.LayoutView.extend({
template: "subscriptions/edit",
events: {
'click #home-delivery-select': 'selectHomeDeliverySite',
'change select[name=location_id]': 'updateLocation'
},
selectHomeDeliverySite: function() {
this.$el.find('select[name=location_id]').val(this.model.get('hd_location_id'));
},
updateLocation: function(e) {
//update location code
},
updateOrderSize: function(e) {
SubscriptionsModule.eventManager.trigger('updateOrderSize', $(e.currentTarget).data('price'));
}
});

Update
Also, please disregard the below answer, since as per the MDN input event docs, the input event only fires for <input> and <textarea> and will not fire for <select>, since the value of <select> doesn't change when any of its options are selected (btw, <input> with type checkbox or radio will also not emit an input event since their value attribute is not changed on selection(!).
I'll leave the answer up for reference.
The following is incorrect
From the MDN
The change event is fired for <input>, <select>, and <textarea> elements when a change to the element's value is committed by the user. Unlike the input event, the change event is not necessarily fired for each change to an element's value.
According to Quirksmode, the change event is buggy for all IE and Opera.
Try replacing
'change select[name=location_id]': 'updateLocation'
with
'input select[name=location_id]': 'updateLocation'

All you need is to add an event:
this.$('select[name=location_id]').val(this.model.get('hd_location_id')).trigger('change');

To trigger the change event on backbone after you change something with jquery you need to trigger the change event.
elem.trigger('change')
http://api.jquery.com/trigger/

Related

My change event listener not tracking changes as expected [duplicate]

When using jquery .change on an input the event will only be fired when the input loses focus
In my case, I need to make a call to the service (check if value is valid) as soon as the input value is changed. How could I accomplish this?
UPDATED for clarification and example
examples: http://jsfiddle.net/pxfunc/5kpeJ/
Method 1. input event
In modern browsers use the input event. This event will fire when the user is typing into a text field, pasting, undoing, basically anytime the value changed from one value to another.
In jQuery do that like this
$('#someInput').bind('input', function() {
$(this).val() // get the current value of the input field.
});
starting with jQuery 1.7, replace bind with on:
$('#someInput').on('input', function() {
$(this).val() // get the current value of the input field.
});
Method 2. keyup event
For older browsers use the keyup event (this will fire once a key on the keyboard has been released, this event can give a sort of false positive because when "w" is released the input value is changed and the keyup event fires, but also when the "shift" key is released the keyup event fires but no change has been made to the input.). Also this method doesn't fire if the user right-clicks and pastes from the context menu:
$('#someInput').keyup(function() {
$(this).val() // get the current value of the input field.
});
Method 3. Timer (setInterval or setTimeout)
To get around the limitations of keyup you can set a timer to periodically check the value of the input to determine a change in value. You can use setInterval or setTimeout to do this timer check. See the marked answer on this SO question: jQuery textbox change event or see the fiddle for a working example using focus and blur events to start and stop the timer for a specific input field
If you've got HTML5:
oninput (fires only when a change actually happens, but does so immediately)
Otherwise you need to check for all these events which might indicate a change to the input element's value:
onchange
onkeyup (not keydown or keypress as the input's value won't have the new keystroke in it yet)
onpaste (when supported)
and maybe:
onmouseup (I'm not sure about this one)
With HTML5 and without using jQuery, you can using the input event:
var input = document.querySelector('input');
input.addEventListener('input', function()
{
console.log('input changed to: ', input.value);
});
This will fire each time the input's text changes.
Supported in IE9+ and other browsers.
Try it live in a jsFiddle here.
As others already suggested, the solution in your case is to sniff multiple events.
Plugins doing this job often listen for the following events:
$input.on('change keydown keypress keyup mousedown click mouseup', handler);
If you think it may fit, you can add focus, blur and other events too.
I suggest not to exceed in the events to listen, as it loads in the browser memory further procedures to execute according to the user's behaviour.
Attention: note that changing the value of an input element with JavaScript (e.g. through the jQuery .val() method) won't fire any of the events above.
(Reference: https://api.jquery.com/change/).
// .blur is triggered when element loses focus
$('#target').blur(function() {
alert($(this).val());
});
// To trigger manually use:
$('#target').blur();
If you want the event to be fired whenever something is changed within the element then you could use the keyup event.
There are jQuery events like keyup and keypress which you can use with input HTML Elements.
You could additionally use the blur() event.
This covers every change to an input using jQuery 1.7 and above:
$(".inputElement").on("input", null, null, callbackFunction);

Backbone view change event not firing when input manipulated by code

In my Backbone model's View I have:
events: {
'change textarea' : 'changeContentTextarea',
...
When user enters a text manually into the textarea, it triggers and do this:
this.model.set('content', this.$el.find('textarea').val());
But it doesn't fire when the content is changed in program (using jQuery):
txtarea.val(finalText);
and so the model's attribute does not update and only the text in the textarea changes.
Is there any event that I can bind to address this problem?
Or how can I fire the event after I change the content using jQuery?
From https://api.jquery.com/change/
Note: Changing the value of an input element using JavaScript, using .val() for example, won't fire the event.
So you have to trigger the change event yourself
$("textarea").val(finalText).trigger("change");
The answer below is right and only if you need to know if the event is triggered by user or by JS, you can do this:
$("textarea").val(finalText).trigger("customChange");
and define the listen event like that:
events: {
'customChange textarea' : 'doSomethingWithJSEvent',

Programmatically changing checkbox does not fire change event

I have the following code here:
$('input[type="checkbox"][id="gridlines"]').change(function () {
alert('hello world');
});
$('#gridlines').prop('checked', true);
When I load my page, the checkbox is checked, but the "hello world" does not get prompted.
However, when I click on the checkbox manually, "hello world" gets prompted.
What gives?
You need to call change() or use trigger() to tirgger the change event when values is changed through code.
Using .change()
$('#gridlines').prop('checked', true).change();
Using .trigger()
$('#gridlines').prop('checked', true).trigger("change");
That is how it is suppose to work, only user interaction is support to trigger the change event
You can trigger it manually using .change()/.trigger('change');
$('#gridlines').prop('checked', true).change();
change
The change event is fired for <input>, <select>, and <textarea>
elements when a change to the element's value is committed by the
user. Unlike the input event, the change event is not necessarily
fired for each change to an element's value.

Why browser doesn't fire change event

I have
<input type="text" id="pies" value="" />
and
$( document ).ready(function() {
$('#pies').on('change', function() { alert('cham'); });
$('#pies').focus();
$('#pies').val('kooooo');
$('#pies').blur();
});
Why browser doesn't fire change event? How can I make that browser will fire change event. I don't want to trigger "change" manually, because if I will trigger change, in some cases trigger change will be triggered twice. This is only example.
Call the change using :
$('#pies').change();
You have to do it manually
$('#pies').change();
As docs says
The change event is sent to an element when its value changes. This event is limited to elements, boxes and elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.
In auto complete case try to do $("#pies").trigger("autocompleteselect");
Better use keypress instead of change

Why does dynamically changing a checkbox not trigger a form change event?

I wrote this snippet of javascript/jQuery to change a check box.
http://jsfiddle.net/johnhoffman/crF93/
Javascript
$(function() {
$("a").click(function() {
if ($("input[type='checkbox']").attr('checked') == "checked")
$("input[type='checkbox']").removeAttr('checked');
else
$("input[type='checkbox']").attr('checked', 'checked');
return false;
});
$("input[type='checkbox']").change(function(){
console.log("Checkbox changed.");
});
});​
HTML
<input type="checkbox" />
Change CheckBox​
Interestingly, clicking the link alters the text box, but does not trigger the form change event that calls the function that logs a message in Chrome Web Developer Console. Why? How do I make it do that?
You need to trigger the change event, .trigger('change'), so that event knows that a change took place.
From http://api.jquery.com/change/:
Description: Bind an event handler to the "change" JavaScript event, or trigger that event on an element.
This method is a shortcut for .on( "change", handler ) in the first two variations, and .trigger( "change" ) in the third.
The change event is sent to an element when its value changes. This event is limited to <input> elements, <textarea> boxes and <select> elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.
Demo:
http://jsfiddle.net/nPkPw/3/
Using chaining: http://jsfiddle.net/nPkPw/5/
i.e. $("input[type='checkbox']").trigger('change').attr('checked', 'checked');
This isn't surprising, but I guess you could as this to the list of non-effect in the msdn.
"This event is fired when the contents are committed and not while
the value is changing."
"The onchange event does not fire when the
selected option of the select object is changed programmatically."
You could always just .click() it jsFiddle

Categories

Resources