19


I am trying to allow users enter only numbers and copy and paste control to the textbox. I am able to restrict user to enter only numbers but copy,paste is not working for me help me to fix this.

Here is my script:

$(".allow_only_numbers").keydown(function (e) {
    var ctrlDown = false;
    var ctrlKey = 17, vKey = 86, cKey = 67;
    if (e.keyCode === ctrlKey){
        ctrlDown = true;
    }
    // Allow: backspace, delete, tab, escape, enter and .
    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110]) !== -1 ||
            // Allow: Ctrl
        (e.keyCode === ctrlKey) ||
            // Allow: Ctrl+A
        (e.keyCode === 65 && e.ctrlKey === true) ||
            // Allow: Ctrl+v
        (e.keyCode === vKey && ctrlDown) ||
            // Allow: Ctrl+c
        (e.keyCode === cKey && ctrlDown) ||
            // Allow: home, end, left, right, down, up
        (e.keyCode >= 35 && e.keyCode <= 40)) {
        // let it happen, don't do anything
        return;
    }
    // Ensure that it is a number and stop the keypress
    if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
        e.preventDefault();
    }
});

Here is the jsfiddle link:

https://jsfiddle.net/sureshpattu/stwzhceL/1/

Suresh Pattu
  • 6,083
  • 16
  • 59
  • 91

8 Answers8

27

Try with event.keyCode and event.metaKey like this.

$(document).ready(function() {
  $(".allow_only_numbers").keydown(function(e) {
    // Allow: backspace, delete, tab, escape, enter and .
    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
      // Allow: Ctrl+A,Ctrl+C,Ctrl+V, Command+A
      ((e.keyCode == 65 || e.keyCode == 86 || e.keyCode == 67) && (e.ctrlKey === true || e.metaKey === true)) ||
      // Allow: home, end, left, right, down, up
      (e.keyCode >= 35 && e.keyCode <= 40)) {
      // let it happen, don't do anything
      return;
    }
    // Ensure that it is a number and stop the keypress
    if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
      e.preventDefault();
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<input type="number" class="allow_only_numbers" />

EDIT:

Remove the following code snippets from your code.

var ctrlDown = false;
var ctrlKey = 17, vKey = 86, cKey = 67;
if (e.keyCode === ctrlKey) {
    ctrlDown = true;
}

Because ctrlDown will be false while pressing C and V for copy and paste. And hence your ctr+c and ctrl+v is not working.

John R
  • 2,741
  • 2
  • 13
  • 32
  • Probably shouldn't use metaKey. "Warning: At least as of Firefox 48, the ⊞ Windows key is no longer considered the "Meta" key. KeyboardEvent.metaKey is false when the ⊞ Windows key is pressed." -https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey. Also you should use KeyboardEvent.code or key. keyCode is deprecated. – Gregory Bologna May 27 '22 at 12:20
9

$(".allow_only_numbers").on("input",function (e) {
  e.target.value = e.target.value.replace(/[^0-9]/g,'')
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="allow_only_numbers" />
Shanimal
  • 11,517
  • 7
  • 63
  • 76
  • 1
    Underrated. Clean solution without the need to whitelist a bunch of keycodes and ctrl-key combos. Thanks. – Ishmaeel Jun 23 '18 at 20:18
  • 1
    I'm not setup to verify with IE8, but there's an SO answer that says you can use `on('propertychange input')` instead of just `on('input')` https://stackoverflow.com/questions/19160902/jquery-oninput-doesnt-get-fired-in-ie8-alone – Shanimal Jul 08 '18 at 22:29
  • Best solution i've found so far! +1 – Andrew Magill Feb 02 '21 at 06:24
2
$(".allow_only_numbers").keydown(function (e) {
        var isModifierkeyPressed = (e.metaKey || e.ctrlKey || e.shiftKey);
        var isCursorMoveOrDeleteAction = ([46,8,37,38,39,40].indexOf(e.keyCode) != -1);
        var isNumKeyPressed = (e.keyCode >= 48 && e.keyCode <= 58) || (e.keyCode >=96 && e.keyCode <= 105);
        var vKey = 86, cKey = 67,aKey = 65;
        switch(true){
            case isCursorMoveOrDeleteAction:
            case isModifierkeyPressed == false && isNumKeyPressed:
            case (e.metaKey || e.ctrlKey) && ([vKey,cKey,aKey].indexOf(e.keyCode) != -1):
                break;
            default:
                e.preventDefault();
        }
});

here is working example

https://jsfiddle.net/stwzhceL/8/

this allow you ctrl+a,ctrl+c and ctrl+v as well as arrow keys,delete key and backspace key.

plus this code covers mac as well.(which is cmd+a/cmd+c/cmd+v)

suish
  • 3,253
  • 1
  • 15
  • 34
  • Good solve, cleaner to read than John R.'s answer even though it's essentially the same thing – rkd Dec 31 '16 at 01:45
1

From @Shanimal answer. this is my angular js directive. to use only number to your input.

.directive('onlyNumber', function() {
        return  {
            restrict: 'A',
            link: function (scope, elm, attrs, ctrl) {
                elm.on("propertychange input",function (event) {
                    event.target.value = event.target.value.replace(/[^0-9]/g,'');
                });
            }
        };
    })

just use 'only-number' to your element. example :

<input type="text" data-ng-model="number" placeholder="number"id="cifNumber" only-number/>
Johan
  • 207
  • 4
  • 14
1
$('.numericOnly').on('keydown keyup', function (e) {
    // Allow: backspace, delete, tab, escape, enter and .
    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
        // Allow: Ctrl+A,Ctrl+C,Ctrl+V, Command+A
        ((e.keyCode == 65 || e.keyCode == 86 || e.keyCode == 67) && (e.ctrlKey === true || e.metaKey === true)) ||
        // Allow: home, end, left, right, down, up
        (e.keyCode >= 35 && e.keyCode <= 40)) {
        // let it happen, don't do anything
        return;
    }
    // Ensure that it is a number and stop the keypress
    if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
        e.preventDefault();
    }
    //Ensure that bulk number pasted is numeric only
    let n = $(this).val()
    if (!isNaN(parseFloat(n)) && isFinite(n)) {
    } else {
        $(this).val("")
    }
})
Gullu Mutullu
  • 427
  • 4
  • 3
0

If you change your keydown event to a keyup event, you can use e.ctrlKey, which will be true when ctrl key is pressed.

Moishe Lipsker
  • 2,974
  • 2
  • 21
  • 29
0
function numbersonly(evt) {
    evt = (evt) ? evt : window.event;
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    }
    return true;
}
-1

That should give you an idea. Sorry I am on a Mac and as far as I know the e.ctrlKey and the like don't work on Mac.

var mod;

var ouput = jQuery('#output');


var numeric = jQuery('#numeric').keydown(function(e){
  mod = e.which;
  
  if(!(e.which >= 48 && e.which <= 57) && (e.which != 8)
  && (mod && (e.which == 67 || e.which != 86))){
      e.preventDefault();
  }
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' id='numeric'/>

<label id='output'></label>
Gacci
  • 1,388
  • 1
  • 11
  • 23