28

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($input.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 when 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.

Why: 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 any input is changed anywhere in my code.

Duncan Lukkenaer
  • 12,050
  • 13
  • 64
  • 97
  • such events `input` do not exist, try `keyup` `keydown` events – Vitaly Jun 07 '16 at 18:39
  • If you use `change` instead of `input`, the `change` will not fire until `#myInput` is out of focus. If you want the event to fire upon clicking a button, then that would unfocus(or blur) `#myInput` and the `change` event would fire in the context of the `#myInput`. – zer00ne Jun 07 '16 at 19:23
  • 2
    @Duncan hi I dont really know why your question receives negative votes. I guess it might be because the subject has been covered many times but I believe your case is special because you cannot use the standard solution. Bottom line your question is fine and dont mind the downvotes too much. Anyway I am really curious to know the reason you dont want to trigger `input` or `change` events. Is is because it isnt automatic only, or you have an additional problems with this solution? Thank you – Jaqen H'ghar Jun 13 '16 at 16:41
  • @JaqenH'ghar Thank you for your comment. The main reason I would like to do check it automatically is that I have a lot of input fields and a lot of different places where I change these inputs programmatically. I could go through all my code to add a `trigger` everywhere, but it would save me a lot of time if there was a way to not having to do this. Besides that, I am just interested in the solutions people might come up with. – Duncan Lukkenaer Jun 13 '16 at 17:16
  • 2
    LOL I dont have any clue why this question gets so many negative votes – codefreaK Jun 16 '16 at 20:52
  • duncan +1 from lol and I want to know why you dont want use custom events or trigger the change event in the line the very next time the value is changed – codefreaK Jun 16 '16 at 20:54
  • @SachinDivakar As I'm saying in the question, I have a lot places in my code where I change the input fields, so having to trigger the events manually is just a lot of extra work. I just hope that there are ways to let some code do that extra work for me. After all, that's what event handlers are for, right? About the downvotes; I'm just looking for an answer which could help others too, and all these negative votes don't help raising attention and they're making the chance of good answers a lot smaller. This question had -6 at one point, so thanks for everyone upvoting! – Duncan Lukkenaer Jun 16 '16 at 21:14
  • I upvoted it as I found the question interesting and have wondered this and then only I learned about custom events now but this question made me wondered whether there is other option other than custom events . – codefreaK Jun 16 '16 at 21:42
  • What about... a function ? If all you need is not repeating yourself, anything else is overkill. – ttzn Jun 18 '16 at 22:29

8 Answers8

35

Simple solution:

Trigger input after you call val():

$input.trigger("input");

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

$input.on('input', function() {
  alert($(this).val());
});

$('#change').click(function() {
  // Change the value and trigger input
  $input.val($input.val() + 'x').trigger("input");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

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

Specific solution:

As mentioned you don't want to trigger input manually. This solution triggers the event automatically by overriding val().

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

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

Jaqen H'ghar
  • 16,186
  • 8
  • 49
  • 52
  • 1
    Best solution I've seen yet. I never thought about overriding, very nice! – Duncan Lukkenaer Jun 13 '16 at 17:41
  • @JaqenH'ghar What about setting the `input.value = 'something'`? Will it work for that? – Praveen Kumar Purushothaman Jun 18 '16 at 12:59
  • OPs question and the answer both regard jQuery `val()`. If you wish to set the value without `val()` as by using `input.value = 'something'` the best and easiest way for you would probably be to trigger the event manually (something OP didnt want but might be best for you) – Jaqen H'ghar Jun 18 '16 at 19:18
  • 3
    I would advise against overriding such an ubiquitous function as `val`. Some jQuery plugins you'd want to add later may rely on it *not* triggering an input event and start to act weird if you do. For instance, if a plugin does sanitizing on the user input and writes back a modified value using `val` you're stuck in an infinite loop. – ttzn Jun 18 '16 at 22:26
  • Best solution for fix external addons change value not trigger. – Mahdi Akrami Dec 05 '21 at 04:37
5

There are some ways on how to achieve it. Here, you can use the levelup HTML's oninput() event that occurs immediately when an element is changed and call the function.

<input id="myinput" type="text" oninput="sample_func()" />
<button id="change">Change value</button>

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

.

var input = $("#myinput");

function sample_func(){
  alert(input.val());
}

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

Or this jQuery, input thing (just related to above example).

<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>

.

var input = $("#myinput");

input.on("input", function() {
  alert(input.val());
});

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

You can also use javascript setInterval() which constantly runs with a given interval time. It's only optional and best if you're doing time-related program.

<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>

.

var input = $("#myinput");

setInterval(function() { ObserveInputValue(input.val()); }, 100);

$('#change').click(function() {
  input.val(input.val() + 'x');
});
rhavendc
  • 985
  • 8
  • 21
  • And hey @Duncan I just found that there's something missing in your code (might a reason why your code is not working). In `$('#change').click(function() { ..... });`, you forgot the `;` right after the `$input.val($input.val() + 'x')` – rhavendc Jun 13 '16 at 06:51
  • arnt most semi colons optional? though a good idea to use them afer every statement – tgkprog Jun 18 '16 at 22:37
3

jQuery listeners only work on actual browser events and those aren't thrown when you change something programmatically.

You could create your own miniature jQuery extension to proxy this so that you always trigger the event but only have to do in one modular place, like so:

$.fn.changeTextField = function (value) {
  return $(this).val(value).trigger("change");
}

Then, just call your new function whenever you want to update your text field, instead of using jQuery's 'val' function:

$("#myInput").changeTextField("foo");

Here's a version working with a proxy function:

    <!DOCTYPE html>
    <html>
        <head>
            <title>Test stuff</title>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
        </head>
        <body>

  <input id="myInput" type="text" />
        <button id="myButton">Change value</button>

        <script type="text/javascript">
            $.fn.changeTextField = function (value) {
             return $(this).val(value).trigger("change");
            }

            $( document ).ready(function() {
                var $input = $("#myInput");

                $input.on("change", function() {
                    alert($input.val());
                });

                $('#myButton').click(function() {
                    $("#myInput").changeTextField("foo");
                });
            });
        </script>
        </body>
    </html>

For reference, this question has really already been answered here: Why does the jquery change event not trigger when I set the value of a select using val()?

and here: JQuery detecting Programatic change event

Community
  • 1
  • 1
hightempo
  • 469
  • 2
  • 8
2

Looks like there's no way, other than using .trigger().

Let's try the same thing using .change() event:

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

$input.on('change paste keyup', function() {
  alert($(this).val());
});

$('#change').click(function() {
  $input.val($input.val() + 'x').trigger("change");
});
<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>

Or you need to trigger it manually:

$('#change').click(function() {
  $input.val($input.val() + 'x').trigger("input");
});

Snippet

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

$input.on('input', function() {
  alert($(this).val());
});

$('#change').click(function() {
  $input.val($input.val() + 'x').trigger("input");
});
<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>
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
  • 1
    I dont think OP wants to programmaticly trigger the input changed. I think he wants to put a watcher on it, so if anyone changes the input from anywhere OP's alert will be triggered – gh9 Jun 07 '16 at 18:39
  • 1
    Something that only use JQUERY and/or vanilla javascript. Not another 3rd party framework that has two way data binding – gh9 Jun 08 '16 at 12:22
1

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

$input.on('input', function() {
  // Do this when value changes
  alert($input.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/3.6.0/jquery.min.js"></script>
AamirSohailKmAs
  • 314
  • 6
  • 14
  • 1
    While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – adiga Mar 25 '19 at 10:40
  • Code Snippet is not working because jQuery link contains * – AamirSohailKmAs Dec 16 '21 at 14:58
1

Trigger didn't work for. Creating an event and dispatching with native JavaScript did the work.

Source: https://stackoverflow.com/a/41593131/6825339

 <script type="text/javascript">
            $.fn.changeTextField = function (value) {
             return $(this).val(value).dispatchEvent(new Event("input", { bubbles: true });
            }

            $( document ).ready(function() {
                var $input = $("#myInput");

                $input.on("change", function() {
                    alert($input.val());
                });

                $('#myButton').click(function() {
                    $("#myInput").changeTextField("foo");
                });
            });
        </script>
Zulqarnain
  • 611
  • 7
  • 18
0
$input.val($input.val() + 'x')
$input.trigger('change');

The change event only fire when input blur.

gu mingfeng
  • 1,010
  • 8
  • 10
0

Try this

$('#input').trigger('change');
Hatim Hussein
  • 117
  • 1
  • 4