3

For example, if I've got an input like this:

<input id="myInput" type="text" />

How can I be notified when the value is changed programatically (for example, as a result of $("#myInput").val("new value"))?

An example: http://jsfiddle.net/2ax9y/

Edit: please note, the question is asking how to listen for changes, not “how to manually dispatch changes”. I'm well aware that I can manually dispatch change events, but I'm trying to avoid that.

David Wolever
  • 148,955
  • 89
  • 346
  • 502
  • Have a look at this answer: http://stackoverflow.com/questions/7905871/change-event-doesnt-get-called-when-the-value-of-select-is-set-programmatical/7905958#7905958 – Rob W Nov 01 '11 at 21:05
  • 1
    possible duplicate of [Detect changes in the DOM](http://stackoverflow.com/questions/3219758/detect-changes-in-the-dom) – Marc B Nov 01 '11 at 21:06
  • @MarcB That "duplicate" question is completely different. This question is asking for a value change, not for a DOM modification. – Rob W Nov 01 '11 at 21:10
  • Modifying the value of an element is a DOM change. – Marc B Nov 01 '11 at 21:11
  • @RobW again, that relies on “manually” triggering the change… Something I know that I can do, but I'd like to avoid, as it will lead to unhappy bugs. – David Wolever Nov 01 '11 at 21:14
  • @DavidWolever That's slightly different. It's a compact jQuery-plugin which combines `.val` and `.change`. If you want to detect changes, you have to either use a poller (!!!), or the method as suggested by MarcB. – Rob W Nov 01 '11 at 21:22

4 Answers4

2

You can change the $ prototype to always trigger change() events whenever val(value) is called:

$.prototype.changeval = $.prototype.val;
$.prototype.val = function(v) {
    if (v) {
        $(this).changeval(v);
        $(this).change();
    } else {
        return $(this).changeval();
    }
}
William
  • 3,511
  • 27
  • 35
jzila
  • 724
  • 4
  • 11
  • Please note: do *not* use this if you ever plan on calling val(value) in the change() handler for the object that was just changed. I.e. `$("#foo").change(function(e) { $(this).val("bar"); }); ` – jzila Nov 02 '11 at 17:11
1

Trigger the change: http://jsfiddle.net/maniator/2ax9y/1/


A little differently: http://jsfiddle.net/maniator/2ax9y/2/

Naftali
  • 144,921
  • 39
  • 244
  • 303
  • That's not idea for two reasons: first, it means adding a `.trigger('change')` to all my code which modifies form fields (lame?), and second my change handlers can't rely on having a “real” change `event`. – David Wolever Nov 01 '11 at 21:07
  • @DavidWolever see my second fiddle. – Naftali Nov 01 '11 at 21:07
  • Uuhhh… Isn't that exactly the same, except with the manually dispatched `change` event being manually dispatched from somewhere else? – David Wolever Nov 01 '11 at 21:09
  • @DavidWolever see related Q's in the comments in the OP – Naftali Nov 01 '11 at 21:09
  • @DavidWolever his second method requires it be written in only one place. It basically ties `click` and `change` together – Joseph Marikle Nov 01 '11 at 21:10
  • Sure, but what if the input is changed because of something *other* than a click? Obviously I could dispatch change events *everywhere* the element is changed… But that's pretty lame. – David Wolever Nov 01 '11 at 21:13
  • @DavidWolever that is the only way you can do it at the moment. you need to attach handlers everywhere you may need them.. – Naftali Nov 01 '11 at 21:13
  • @DavidWolever you can however bind multiple events with the same `bind` function. – Naftali Nov 01 '11 at 21:14
1

You can't reliably subscribe to every change on an input element, but you can check if there has been a change since you last checked and do that within some desired time granularity.

Make a checker function and loop it with your desired time granularity—100ms is a good start, adjust to your needs.

Hypothetical untested implementation:

var last_value = null;

function handle_changed() {
    // Do something here
}

function check_value() {
    var v = $("#myelement").val();
    if(v !== last_value) {
        last_value = v;
        handle_changed();
    }
}

setInterval(check_value, 100);
shazow
  • 17,147
  • 1
  • 34
  • 35
0

I don't think this is an inherent ability of the change event. You could manually trigger the change event when you programmatically change the value.

$("#myInput").val(+(new Date())).change();
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129