397

I'm trying to trigger the change event on a text box when I change its value with a button, but it doesn't work. Check this fiddle.

If you type something in the text boxes and click somewhere else, change is triggered. However, if you click the button, the text box value is changed, but change doesn't trigger. Why?

dodov
  • 5,206
  • 3
  • 34
  • 65
Ergec
  • 11,608
  • 7
  • 52
  • 62
  • Title itself answered my question. Confirmed at **[.change()](https://api.jquery.com/change/)** yellow "Note: Changing the value of an input element using JavaScript, using .val() for example, won't fire the event." – Bob Stein Nov 20 '16 at 03:35
  • Wish I'd have come across https://stackoverflow.com/questions/11873721/jquery-val-change-doesnt-change-input-value sooner, hope it helps some. – JeopardyTempest Jun 22 '18 at 08:42
  • 1
    This question must be reopened as popular, and we should mark less popular [question](https://stackoverflow.com/q/2247386/4632019) as duplicate – Eugen Konkov Oct 06 '21 at 08:49

11 Answers11

542

onchange only fires when the user types into the input and then the input loses focus.

You can manually call the onchange event using after setting the value:

$("#mytext").val( 777 ).change(); // someObject.onchange(); in standard JS

Alternatively, you can trigger the event using:

$("#mytext").val( 777 ).trigger("change");
Eugen Konkov
  • 22,193
  • 17
  • 108
  • 158
djdd87
  • 67,346
  • 27
  • 156
  • 195
  • Is there a reason that jQuery guys didn't implement this? – Ergec Jul 05 '10 at 12:35
  • 19
    feel free to extend jquery and add a say valWithChange function that will do what you want. It cannot be the default action as many times you do not want the event triggering from an automated value change, only when a user interacts with the element – redsquare Jul 05 '10 at 12:57
  • 10
    I would like to see this answer edited to address the option of chaining `.change()` to the `.val()` method. – Snekse Jun 13 '12 at 18:39
  • 21
    The reason may be that some people call `.val()` in `.change()` because they do input validation. Triggering `.change()` on `.val()` would cause an infinite loop. – yingted Sep 02 '12 at 04:01
  • 7
    Only if they were changing the value to something that would fail their own validation, which would be silly. – Leng Jun 05 '13 at 17:21
  • 6
    I ended up binding to `blur` to accomplish something similar: `$('#mytext').focus().val('New text').blur();` – Wes Johnson Jul 24 '14 at 15:31
  • 1
    @WesJohnson Thanks, as the text input types don't fire change until focus loss, it is necessary to trigger focusin and focusout in combination with this answer. It's also very compact the way you wrote it ;-) – Tony Wall Oct 06 '15 at 14:53
  • If you trigger 'change' this way it will not care if the value has actually changed or not. – Geza Turi Nov 19 '16 at 21:18
  • I guess this is one of the reasons for the popularity of angular, react, and vue, right? – tnk479 Jul 25 '19 at 20:28
  • 1
    For JS Vanilla you can use `el.dispatchEvent(new Event("change", { bubbles: true }));` – Diego Fortes Dec 03 '20 at 08:24
  • Can you explain the difference between the two options you have provided? – user8016906 May 09 '21 at 20:44
  • $("#mytext").trigger("input") has been the solution for me! – gtamborero Sep 14 '21 at 10:11
  • 1
    wrong answer not worked – Mahmoud Magdy Dec 01 '22 at 21:09
67

From redsquare's excellent suggestion, this works nicely:

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

$("#my-input").changeVal("Tyrannosaurus Rex");
Florian Lemaitre
  • 5,905
  • 2
  • 21
  • 44
Chris Fulstow
  • 41,170
  • 10
  • 86
  • 110
31

You can very easily override the val function to trigger change by replacing it with a proxy to the original val function.

just add This code somewhere in your document (after loading jQuery)

(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0)
            $(this).change(); // OR with custom event $(this).trigger('value-changed');
        return result;
    };
})(jQuery);

A working example: here

(Note that this will always trigger change when val(new_val) is called even if the value didn't actually changed.)

If you want to trigger change ONLY when the value actually changed, use this one:

//This will trigger "change" event when "val(new_val)" called 
//with value different than the current one
(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var prev;
        if(arguments.length>0){
            prev = originalVal.apply(this,[]);
        }
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0 && prev!=originalVal.apply(this,[]))
            $(this).change();  // OR with custom event $(this).trigger('value-changed')
        return result;
    };
})(jQuery);

Live example for that: http://jsfiddle.net/5fSmx/1/

Yaron U.
  • 7,681
  • 3
  • 31
  • 45
  • 4
    Hmm, unnecessary duck-patching, I think :-p. Might be better to, as [commented by redsquare](http://stackoverflow.com/questions/3179385/val-doesnt-trigger-change-in-jquery#comment3273526_3179392), give such a function a different name than `.val()`. – binki Jun 16 '14 at 20:09
  • 1
    If you rename it you should change your existing code - this way your existing code will continue to work – Yaron U. Jun 16 '14 at 20:16
  • 4
    But then all of the code which was written with the correct definition of `.val()` in mind would suddenly start producing side-effects :-p. – binki Jun 16 '14 at 20:19
  • 2
    This will also make plugins malfunction, which might not be as easily fixable – SoWhat Oct 17 '15 at 11:31
  • 2
    In order to avoid side effects, I modified the val function as above, but I'm triggering a different event ("val"), which lets me keep the existing code but easily handle it whenever I need to: $(...).on('change val', ...) – ulu Feb 04 '16 at 09:24
  • 2
    This is an excellent solution in the case you have no control over the code calling `.val()` like using external library. And if you trigger a custom event, it does not cause any harm. – Radek Matěj Jan 03 '17 at 11:18
  • This is good, but can you show how you would limit it to just one particular input? – jwebb Jul 20 '18 at 15:33
  • Thank you for this brilliant solution! This seems to be the correct answer, considering you're not always in control over the entire code base (e.g. using external libraries). Nice and clean. – Mladen B. May 28 '21 at 07:12
26

You need to chain the method like this:

$('#input').val('test').change();
14

No you might need to trigger it manually after setting the value:

$('#mytext').change();

or:

$('#mytext').trigger('change');
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
9

It looks like the events are not bubbling. Try this:

$("#mybutton").click(function(){
  var oldval=$("#mytext").val();
  $("#mytext").val('Changed by button');
  var newval=$("#mytext").val();
  if (newval != oldval) {
    $("#mytext").trigger('change');
  }
});

I hope this helps.

I tried just a plain old $("#mytext").trigger('change') without saving the old value, and the .change fires even if the value didn't change. That is why I saved the previous value and called $("#mytext").trigger('change') only if it changes.

RAM
  • 2,413
  • 1
  • 21
  • 33
Jay Godse
  • 15,163
  • 16
  • 84
  • 131
  • Surprised this didn't have more votes, since it is the current effective implementation of an HTML element change. – vol7ron Apr 23 '14 at 20:39
6

As of feb 2019 .addEventListener() is not currently work with jQuery .trigger() or .change(), you can test it below using Chrome or Firefox.

txt.addEventListener('input', function() {
  console.log('not called?');
})
$('#txt').val('test').trigger('input');
$('#txt').trigger('input');
$('#txt').change();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="txt">

you have to use .dispatchEvent() instead.

txt.addEventListener('input', function() {
  console.log('it works!');
})
$('#txt').val('yes')
txt.dispatchEvent(new Event('input'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="text" id="txt">
cieunteung
  • 1,725
  • 13
  • 16
3

I know this is an old thread, but for others looking, the above solutions are maybe not as good as the following, instead of checking change events, check the input events.

$("#myInput").on("input", function() {
    // Print entered value in a div box
    $("#result").text($(this).val());
});
Slipoch
  • 750
  • 10
  • 23
  • 1
    Depends on the situation. The "change" and "input" methods both work a bit differently and don't trigger at the same times. The "input" will trigger on every key press, while the "change" triggers when a change has been made, and the input loses focus. – Kalko Mar 21 '23 at 16:10
1

From https://api.jquery.com/change/:

The change event is sent to an element when its value changes. This event is limited to <input> elements, <textarea> boxes and <select> elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.

Sky Yip
  • 1,059
  • 12
  • 10
1

you can use the attr and val method and then triggering the change:

$('.parent-form').find('input').each(function() {
    item = $(this);
    item.attr('value', '0622-03-22');
    item.val('01/01/01').trigger('change');
});
Mustafa Poya
  • 2,615
  • 5
  • 22
  • 36
1

In some case, as it happened for me, when you have a custom input validation, which listens to input updates/changes, the .change() or .trigger('change') want help.

In such cases, for inputs, you can try using the following:

.trigger('input')
Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42