1

We have a lot of forms on a website we're developing. Some of these forms have functionality that will populate specific fields using JavaScript based on something else the user does. (For example postcode lookup).

For every form, we want to do something when each form field value is modified.

  • On change events aren't fired by values changed by JavaScript.

  • MutationObserver doesn't appear to be able to listen to value changes (it only listens for attribute changes, not property changes). Unless I am missing something?

  • We don't want to (and in some cases can't) change the JavaScript that populates fields to trigger the on change event.

So, we have a form which may have fields values populated by some JavaScript or another somewhere along the way, and we need to know when the field's values have changed.

Currently the only working solution we've come up with is to use 'polling' to periodically check all fields (using setInterval) to see if their value has changed. We're wondering if anyone can come up with a better solution?

(We are using jQuery 1.11.2).

Update: We have found an answer to this question which I have posted below. However, we do not know what the ramifications of redefining an object's default property might be, so we aren't 100% comfortable with that solution yet and continue to search for more ideas.

halfer
  • 19,824
  • 17
  • 99
  • 186
Josh
  • 376
  • 2
  • 13
  • 2
    Without being able to amend the code which sets the values to trigger events, nor MutationObservers, there's not much else you can do besides polling (which is awful). I'd strongly suggest you try and edit the code which sets the values to trigger events. – Rory McCrossan Oct 03 '18 at 09:37
  • Why not use a library such as knockout.js? – nbokmans Oct 03 '18 at 09:39
  • @nbokmans - googling it now – Josh Oct 03 '18 at 09:39
  • 1
    Upon a cursory search [this approach](https://stackoverflow.com/a/51056988/519413) may work, although I'd have my doubts if it's reliable cross-browser. – Rory McCrossan Oct 03 '18 at 09:39
  • 1
    @nbokmans I don't see how that's anyway useful if the OP says they can't amend the existing code. They may as well just add `trigger()` calls if that was possible, instead of adding another entire library – Rory McCrossan Oct 03 '18 at 09:40
  • @RoryMcCrossan yes, as you say, Knockout doesn't appear to be helpful, thanks though nbokmans – Josh Oct 03 '18 at 09:41
  • @RoryMcCrossan - just looking into that approach, will have to test it and see how it goes. Thanks. – Josh Oct 03 '18 at 09:45
  • @wOxxOm please read the 3rd bullet point. We don't want to / can't change that code. Otherwise, yes, this would be easy. – Josh Oct 03 '18 at 12:57

1 Answers1

1

The solution that GracefulLight posted here that Rory put us onto does work.

You can redefine the object's value property, enabling you to do whatever you like when the value property is set.

Object.defineProperty(document.querySelector(".my-object"), "value", {
  set: function(newValue) {
    console.log("Object's value property has changed");

    // do something
    this.style.borderColor = "#228B22";

    // make sure the value is still passed to the input to be output
    return this.defaultValue = newValue;
  }
});
Josh
  • 376
  • 2
  • 13