Is there a way to listen to a textbox when its value changes programmatically

Environment:
JavaScript only (no jquery :()
Button click event handler is not changeable.

Is there a way to listen to a textbox if its value changes programmatically?

<input type="button" id="button1" value="button" />
<input type="text" id="text1" />


var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');
btn1.onclick=function(){ txt1.value = 'hello world'}

      

https://jsfiddle.net/yrt7e57w/

+3


source to share


3 answers


You can rely on the coder to change the element programmatically to know to call onChange, but that's a suggestion. Looking at other posts, this looks very promising: For your text element, override the setters and getters so that they are automatically triggered for changes made or programmatically.

var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');


btn1.onclick = function() {
    txt1.value = 'hello world'
  }
  
txt1.addEventListener("change", function(e){
  console.log(txt1.value);
})
  
  //property mutation for hidden input
Object.defineProperty(txt1, "value", {
  // Don't override the getter, but stub it in.
  get: function() {
    return this.getAttribute("value");
  },
  // In the setter, we want to set the value
  //  and also fire off the change event.
  //  By doing this, the coder changing the
  //  value never needs worry about it.
  set: function(val) {
    console.log("set");

    // handle value change here
    this.setAttribute("value", val);

    //fire the event
    if ("createEvent" in document) { //NON IE browsers
      var evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", false, true);
      txt1.dispatchEvent(evt);
    } else { //IE
      var evt = document.createEventObject();
      txt1.fireEvent("onchange", evt);
    }
  }
});
      

<input type="button" id="button1" value="button" />
<input type="text" id="text1" />
      

Run codeHide result


Or see it like a fiddle Here

So, to answer your question as to why the click handler shows the input as being null, it's because the getter / setter overrides the default behavior. The easiest way to get around this is to create a custom getter / setter to act as an interface to the value attribute:



var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');

btn1.onclick = function() {
  console.log("in the button click handler, ");
  console.log("Value is: " + txt1.val);
  console.log("--------------------------------")
  txt1.val = 'hello world'
}

txt1.addEventListener("change", function(e) {
  console.log("in txt1.onChange function...")
  console.log(this.val);
  console.log("--------------------------------")
})


//property mutation for hidden input
Object.defineProperty(txt1, "val", {
  get: function() {
    return this.value;
  },
  set: function(val) {
    // handle value change here
    this.value = val;

    //fire the event
    if ("createEvent" in document) { //NON IE browsers
      var evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", false, true);
      txt1.dispatchEvent(evt);
    } else { //IE
      var evt = document.createEventObject();
      txt1.fireEvent("onchange", evt);
    }
  }
});
      

<input type="button" id="button1" value="button" />
<input type="text" id="text1" />
      

Run codeHide result


What happens when the button is clicked is I get the val attribute (which gets the value behind the scenes), then programmatically sets the val attribute of the same input (which, again, sets the value to the attribute). For some reason, you cannot use get / set on object.defineProperty on an input value attribute without breaking it up completely. So in the console you will see three function calls: when the button is clicked, the input loses focus by calling its change method, but then the button itself fires the click handler, which then changes the input value and triggers the change handler again.

Hope this helps!

Again, to see this as a fiddle ...

+2


source


You can use element.dispatchEvent(event)

when you programmatically change the text. In your example, it would look like this:

var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');

btn1.addEventListener("click", function() { // Add to OnClick of button.
    txt1.dispatchEvent(new Event('change')); // force change event to run on textbox.
});

txt1.addEventListener("change", function(e){ // EventListener for OnChange of the element.
    alert("changed");
});

      



Just addEventListener

by itself won't work as it doesn't exactly change in the DOM.

Above is a simple solution that requires few keystrokes, but for a much more convenient and reusable solutions, check the response Snomonki (and perhaps most of the other answers to this question), fooobar.com/questions/2417285 / ... .

+3


source


Maybe this is too much, but you can use the mutationObserver api to listen for an attribute change ,
you will have to change the value using the method setAttribute

:

var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');

btn1.onclick=function(){ txt1.setAttribute('value', 'hello world') }

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log( mutation );
  });    
});
 
// configuration of the observer:
var config = {  attributes:true };
 
// pass in the target node, as well as the observer options
observer.observe(txt1, config);
      

<input type="button" id="button1" value="button" />
<input type="text" id="text1" />
      

Run codeHide result


0


source







All Articles