5

I would like to immediately detect changes in an input type="text" when it's modified by JavaScript. When it's changed manually by user the detection can be triggered by:

onchange="myfunction();" onkeyup="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();"

I just can't figure this one out.

Key-Six
  • 2,439
  • 2
  • 26
  • 22
  • 1
    `onpropertychange onkeyup oninput onpaste onchange` covers everything I've ever known. Also you should be attaching these in JavaScript rather than adding them to the tags. – Dave Aug 29 '13 at 21:25
  • oh, modified by JavaScript? Not that I'm aware of. The rational being that you set it in the first place. Only option could be to have an interval continuously checking it. – Dave Aug 29 '13 at 21:26
  • Do you control the code that changes it? You could trigger a custom event whenever it changes. – Evan Davis Aug 29 '13 at 21:28
  • @Dave: I tried to do so via setInterval (as suggested in the answer on the top), but it doesn't work with JavaScript changes. – Key-Six Aug 29 '13 at 21:32
  • @Mathletics: Yes, I do. What kind of event do you have in mind? – Key-Six Aug 29 '13 at 21:34
  • @Drejon, Did you look at my answer? – plalx Sep 05 '13 at 17:08

2 Answers2

3

As you've said that you control the code that changes it, you might simply trigger a change event when you change the contents of the input. In jQuery it'd be:

var textinput = //Perhaps $("input[type='text']") or $("#someid")
textinput.val("New text here");
textinput.trigger("change");

And that would trigger whatever function you bound to your onchange event.

If you're doing this often enough, you may just want to make a function that updates the value and triggers the event.

Without jquery, it's a little more complicated, but take a look at How can I trigger an onchange event manually?

EDIT:

Here's a complete example, again using jQuery. Note that I'm using javascript to set up handlers, rather than actually specifying them in HTML, as this is the better practice, generally speaking.

HTML:

<input type="text" id="toChange">

Javascript:

function changeFunction() {
    //Do whatever  
}

$(document).ready(function() {
    var inputbox = $("#toChange");
    inputbox.on('change', changeFunction);
    inputbox.on('paste', changeFunction);
    //Can attach other functions, though beware of multiple triggers
});

//SetTimeout in place of whatever code does the changing
window.setTimeout(function() {
    var inputbox = $("#toChange")
    inputbox.val("Set by function");
    inputbox.trigger("change");
}, 3000);

JFiddle

Community
  • 1
  • 1
Retsam
  • 30,909
  • 11
  • 68
  • 90
1

You could possibly use the MutationObserver object which allows to observe attribute changes. However, I am not sure if the callback will get called when you do el.value = ... instead of el.setAttribute('value', ...).

You could also define a custom setter for the value property using Object.defineProperty. However, I've never done it on a DOM element and if there's already a setter defined, you might want to make sure that your new setter calls it as well. You can probably use Object.getOwnPropertyDescriptor to get the current setter if any.

Finally, as last resort you could always use setInterval to periodically check if the value property of the element changed, but I don't really like this approach. However it might be the only cross-browser one.

Unfortunately, I cannot test any of this right now, but I will get back and update this answer later.

plalx
  • 42,889
  • 6
  • 74
  • 90