2

Attempting to create a Chrome extension, I use jQuery to change certain input and textarea values using the following statement:

$(this).val(newValue).trigger('change');

The goal of the trigger part is to notify any 2-way data binding modules used on the current page that the value of the input has been changed.

It does not work.

I tried with Knockout and Rivets, and both do not know that the value of the input has been changed using the above jQuery line.

Using the accepted answer here, I tried:

 $(this).val(newValue).change();

That does not work either.

Interestingly enough, if I downgrade to pure DOM interface (i.e. no jQuery), then it works fine and the 2-way bindings get properly notified of the value change. Using the following code:

element.value = newValue;
element.dispatchEvent(new Event('change'));

The above works and all 2-way binding modules that I tried are aware of the value change.

How can I achieve the same effect with jQuery? Note that my code lives in the content script of my Chrome extension.

Community
  • 1
  • 1
miniml
  • 1,489
  • 2
  • 17
  • 27
  • 1
    `data binding modules used on the current page` - in this case you'll have to inject a script into the page: [Building a Chrome Extension - Inject code in a page using a Content script](https://stackoverflow.com/q/9515704) – wOxxOm Nov 02 '15 at 09:06
  • @wOxxOm this makes sense. I'll have to inject jQuery into the page, so it doesn't work in isolation. – miniml Nov 03 '15 at 13:40
  • 1
    You can reuse jQuery of the webpage in the injected code. Otherwise don't forget to use `jQuery.noConflict()`. – wOxxOm Nov 03 '15 at 13:57

1 Answers1

1

You simply have to change the value and trigger the change event, which is detected by most MVVM frameworks to update the observable value. I don't know how your code looks like, and why it fails, but this snippet works:

var vm = {
    val: ko.observable('Some value'),
};

ko.applyBindings(vm, bound);

$('#changeText').on('click', function() {
    $('#textInput').val('ABC');
    $('#textInput').trigger('change');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bound" name="bound">
  <input type="text" data-bind="value: val" id="textInput"/>
  <div>
    The observable is: <span data-bind="text: val"/>
  </div>
</div>
<input type="button" value="Click to change" id="changeText"/>
JotaBe
  • 38,030
  • 8
  • 98
  • 117