102

How can I handle an onchange for <input type="number" id="n" value="5" step=".5" /> ? I can't do a keyup or keydown, because, the user may just use the arrows to change the value. I would want to handle it whenever it changes, not just on blur, which I think the .change() event does. Any ideas?

Ian Davis
  • 19,091
  • 30
  • 85
  • 133

11 Answers11

166

Use mouseup and keyup

$(":input").bind('keyup mouseup', function () {
    alert("changed");            
});

http://jsfiddle.net/XezmB/2/

Avatar
  • 14,622
  • 9
  • 119
  • 198
JohnColvin
  • 2,489
  • 1
  • 14
  • 8
  • 6
    This will alert even if the value hasn't changed (just click anywhere in the `input`). – James Allardice Mar 07 '12 at 22:10
  • Yes it will. If that's a problem, you should keep track of the value in the input in a global variable or in a data element on the input. When the mouseup event calls your function, compare that value to the current value of the input. Only do something if the value has changed. – JohnColvin Mar 08 '12 at 19:05
  • 3
    This doesn't work if value is changed by mouse scroll above the element. – Ondrej Machulda Feb 17 '14 at 18:31
  • Functionally it's not acting as change event. – N K Mar 06 '14 at 11:12
  • 7
    Add the "mousewheel" event to support changes by scrolling. – Martijn Mar 19 '15 at 10:17
  • 4
    If the user holds an arrow key down to change the value, then this doesn't fire until the arrow key is released. Using `input` instead (as suggested in another answer) seems to work better. – Josh Kelley Aug 05 '15 at 19:05
95

The oninput event (.bind('input', fn)) covers any changes from keystrokes to arrow clicks and keyboard/mouse paste, but is not supported in IE <9.

jQuery(function($) {
  $('#mirror').text($('#alice').val());

  $('#alice').on('input', function() {
    $('#mirror').text($('#alice').val());
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input id="alice" type="number" step="any" value="99">

<p id="mirror"></p>
isherwood
  • 58,414
  • 16
  • 114
  • 157
Flo
  • 1,965
  • 11
  • 18
11

http://jsfiddle.net/XezmB/8/

$(":input").bind('keyup change click', function (e) {
    if (! $(this).data("previousValue") || 
           $(this).data("previousValue") != $(this).val()
       )
   {
        console.log("changed");           
        $(this).data("previousValue", $(this).val());
   }

});


$(":input").each(function () {
    $(this).data("previousValue", $(this).val());
});​

This is a little bit ghetto, but this way you can use the "click" event to capture the event that runs when you use the mouse to increment/decrement via the little arrows on the input. You can see how I've built in a little manual "change check" routine that makes sure your logic won't fire unless the value actually changed (to prevent false positives from simple clicks on the field).

Jake Feasel
  • 16,785
  • 5
  • 53
  • 66
8

To detect when mouse or key are pressed, you can also write:

$(document).on('keyup mouseup', '#your-id', function() {                                                                                                                     
  console.log('changed');
});
Kingsley Ijomah
  • 3,273
  • 33
  • 25
3
$("input[type='number']").bind("focus", function() {
    var value = $(this).val();
    $(this).bind("blur", function() {
        if(value != $(this).val()) {
            alert("Value changed");
        }
        $(this).unbind("blur");
    });
});

OR

$("input[type='number']").bind("input", function() {
    alert("Value changed");
});
N K
  • 3,217
  • 5
  • 23
  • 38
3

Because $("input[type='number']") doesn't work on IE, we should use a class name or id, for example, $('.input_quantity').

And don't use .bind() method. The .on() method is the preferred method for attaching event handlers to a document.

So, my version is:

HTML

<input type="number" value="5" step=".5" min="1" max="999" id="txt_quantity" name="txt_quantity" class="input_quantity">

jQuery

<script>
$(document).ready(function(){
    $('.input_quantity').on('change keyup', function() {
        console.log('nice');
    }); 
});
</script>
Aᴍɪʀ
  • 7,623
  • 3
  • 38
  • 52
SandroMarques
  • 6,070
  • 1
  • 41
  • 46
3

Just write a function in plain javascript and call it in the HTML code:

<input type="number" onchange="onChangeFunction(this.value)">
Bruno L.
  • 457
  • 6
  • 8
3
$(':input').bind('click keyup', function(){
    // do stuff
});

Demo: http://jsfiddle.net/X8cV3/

AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
1
<input type="number" id="n" value="0" step=".5" />
<input type="hidden" id="v" value = "0"/>

<script>
$("#n").bind('keyup mouseup', function () {
    var current = $("#n").val();
    var prevData = $("#v").val(); 
    if(current > prevData || current < prevData){
       $("#v").val(current);
       var newv = $("#v").val(); 
       alert(newv);
    } 
});  
</script>

http://jsfiddle.net/patrickrobles53/s10wLjL3/

I've used a hidden input type to be the container of the previous value that will be needed for the comparison on the next change.

1

I had same problem and I solved using this code

HTML

<span id="current"></span><br>
<input type="number" id="n" value="5" step=".5" />

You can add just 3 first lines the others parts is optional.

$('#n').on('change paste', function () {
    $("#current").html($(this).val())   
});
// here when click on spinner to change value, call trigger change
$(".input-group-btn-vertical").click(function () {
   $("#n").trigger("change");
});
// you can use this to block characters non numeric
$("#n").keydown(function (e) {
    // Allow: backspace, delete, tab, escape, enter and .
    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 || (e.keyCode === 65 && e.ctrlKey === true) || (e.keyCode >= 35 && e.keyCode <= 40)) 
           return;

    if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) 
       e.preventDefault();
});

Example here : http://jsfiddle.net/XezmB/1303/

Offboard
  • 27
  • 5
Bruno Ribeiro
  • 1,280
  • 16
  • 21
1

There may be a better solution, but this is what came to mind:

var value = $("#yourInput").val();
$("#yourInput").on('keyup change click', function () {
    if(this.value !== value) {
        value = this.value;
        //Do stuff
    }        
});

Here's a working example.

It simply binds an event handler to the keyup, change and click events. It checks whether or not the value has changed, and if so, stores the current value so it can check again next time. The check is required to deal with the click event.

James Allardice
  • 164,175
  • 21
  • 332
  • 312