Duncan Duncan - 5 months ago 28
HTML Question

Input event not working if value is changed with jQuery val() or JavaScript

If I change the value of an input field programmatically, the

input
and
change
events are not firing. For example, I have this scenario:



var $input = $("#myinput");

$input.on('input', function() {
// Do this when value changes
alert($(this).val());
});

$('#change').click(function() {
// Change the value
$input.val($input.val() + 'x');
});

<input id="myinput" type="text" />
<button id="change">Change value</button>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>





The problem: The event is triggered when I type in the textfield, but not if I press the button. Is there a way to achieve this with some kind of event or otherwise without having to do it manually?

What I don't want to do: I could go through all my code to add a
trigger
or function call everywhere manually, but that's not what I'm looking for.

The reason: The main reason I would like to do this automatically is that I have a lot of input fields and a lot of different places where I change these inputs programmatically. It would save me a lot of time if there was a way to fire the event automatically when I change any input anywhere in my code. Besides saving time, I am just interested in the solutions people might come up with.

Answer

As mentioned you don't want to trigger input event manually and looking for an automatic solution. A good solution I think will be to trigger the event automatically.

In my solution I overrided jQuery's val() method. You can place it once in your code and val() will automatically invoke the input event when it is called on any <input type='text'>

Just add this to your code:

(function ($) {
    var originalVal = $.fn.val;
    $.fn.val = function (value) {
        var res = originalVal.apply(this, arguments);

        if (this.is('input:text') && arguments.length >= 1) {
            // this is input type=text setter
            this.trigger("input");
        }

        return res;
    };
})(jQuery);

See JSFiddle Demo

PS

Please notice I put this.is('input:text') in the condition. If you want to trigger the event for more types, add them to the condition.