0

I want to restrict the entries in a text element to numeric only. I found some code for that that works in the jsfiddle, which is referenced from here

...but on my page (Webpart) / *.ascx file, it does not. I see the alert every time I mash a key, but I can enter anything (a..z as well as 0..9). Here is the code:

<script type="text/javascript">
$(document).ready(function () {
    console.log('The ready function has been reached'); /* This is a "sanity check" so it can be verified that this jQuery script is running/ran */
});

/* When "Employee" checkbox changes state, set up txtbxSSNOrITIN accordingly */
$(document).on("change", '[id$=ckbxEmp]', function () {
    var ssnmaxlen = 4;
    var itinmaxlen = 11;
    var ssntextboxwidth = 40;
    var itintextboxwidth = 100;
    var ckd = this.checked;
    var $input = $('[id$=txtbxSSNOrITIN]');
    var $lbl = $('[id$=lblSSNOrITIN]');

    if (ckd) $input.data("oldValue", $input.val()); // Remember current value

    $input.prop("maxlength", ckd ? ssnmaxlen : itinmaxlen).css({
        background: ckd ? 'yellow' : 'lightgreen',
        width: ckd ? ssntextboxwidth : itintextboxwidth
    }).val(function (i, v) {
        /* If checked, trim textbox contents to ssnmaxlen characters */
        return ckd && v.length > ssnmaxlen ? v.slice(0, ssnmaxlen) : $input.data("oldValue");
    });

    $lbl.text(ckd ? "SSN - last 4 digits" : "ITIN");
    /* This sets focus to the end of the textbox (multiplication by 2 is because some characters are counted as two) */
    var strLength = $input.val().length * 2;
    $input.focus();
    $input[0].setSelectionRange(strLength, strLength);
});

$(document).on("keyup", '[id$=txtbxSSNOrITIN]', function (e) {
    alert('the textbox keyup event occurred');
    /* For now, just "eating" non-numeric entries (from http://jsfiddle.net/zpg8k/); will change when the business rules for ITIN are known */
    var a = [];
    var k = e.which;

    for (i = 48; i < 58; i++)
        a.push(i);

    if (!(a.indexOf(k) >= 0))
        e.preventDefault();
});
</script>

It works the same whether the "keyup" event is "standalone" or within the ready function - in both cases, the alert displays with each keyup, but does not restrict anything. Why?

UPDATE

Thanks to putvande and Brett (and Roko, for the "soul-saving" ID-finding tip elsewhere), it now works, and has been simplified to this:

$(document).on("keypress", '[id$=txtbxSSNOrITIN]', function (e) { 
    var k = e.which;
    if (k < 48 || k > 57) { e.preventDefault(); }
});
Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • Can you show your HTML? – putvande Jun 04 '15 at 18:58
  • Any errors in the console? Also, the code in the fiddle doesn't match the code in your question, so why post it? – j08691 Jun 04 '15 at 19:02
  • What the heck is this syntax, `'[id$=txtbxSSNOrITIN]'`? If this is an HTML element id, why are you not using the standard syntax of `'#txtbxSSNOrITIN'`? Also, it's completely silly and unnecessary to me that the `'keyup'` function builds an array holding numbers from 48 to 57 every time a key is pressed. No need to overcomplicate it. – Brett Jun 04 '15 at 19:08
  • That syntax is to find the ID that ends with that; that's the ID I gave it, but the ID generated is a bunch of "Welsh" (gobbledygook) followed by that. So, that's the name of that tune, as the breadmaker was wont to say. – B. Clay Shannon-B. Crow Raven Jun 04 '15 at 20:08
  • @Brett: For the nitty-gritty, see Roko's answer here: http://stackoverflow.com/questions/30607754/how-can-i-restrict-the-number-of-characters-entered-into-an-html-input-with-css/30607834 – B. Clay Shannon-B. Crow Raven Jun 04 '15 at 20:17

1 Answers1

2

It's because your function runs AFTER you pressed the key. So that way it won't prevent you from pressing and inputting that key. The JSFiddle you referenced does it before.
So change your function to be :

$(document).on("keypress", '[id$=txtbxSSNOrITIN]', function (e) {
//              ^^^^^^^^keypress instead of keyup
    alert('the textbox keyup event occurred');
    /* For now, just "eating" non-numeric entries (from http://jsfiddle.net/zpg8k/); will change when the business rules for ITIN are known */
    var a = [];
    var k = e.which;

    for (i = 48; i < 58; i++)
    a.push(i);

    if (!(a.indexOf(k) >= 0)) e.preventDefault();
});
putvande
  • 15,068
  • 3
  • 34
  • 50
  • 1
    The array is completely unnecessary. This `if (k < 48 || k > 57) { e.preventDefault(); }` does the same thing and is faster and much more understandable and readable. – Brett Jun 04 '15 at 19:16
  • 1
    The code is copied from what OP has. I've only changed the event type. The rest is up to OP. – putvande Jun 04 '15 at 19:27