1

I have an html <input> and some pattern (e.g. -?\d*\.?\d* float-signed value).
I should prevent typing the not matched value.
I did it in next way

jQuery.fn.numeric = function (pattern) 
{
   var jqElement = $(this), prevValue;
    jqElement.keydown(function()
    {
                          prevValue = jqElement.val();
    })
    jqElement.keyup(function(e)
    {
       if (!pattern.test(jqElement.val()))
       {
          jqElement.val(prevValue);
          e.preventDefault();
       }
       prevValue = ""
    }) 
};  

JSFiddle DEMO

But in this case, value is shown to user and then corrected to right value.
Is it way to vaidate value before it is shown to user?

I can use pattern attribute from html5

Ilya
  • 29,135
  • 19
  • 110
  • 158

4 Answers4

1
$("#validateMe").on('keydown', function() {
    var charBeingTyped = String.fromCharCode(e.charCode || e.which); // get character being typed
    var cursorPosition = $(this)[0].selectionStart;        // get cursor position
    // insert char being typed in our copy of the value of the input at the position of the cursor.
    var inValue = $(this).value().substring(0, cursorPosition) + charBeingTyped + $(this).value().substring(cursorPosition, $(this).value().length);
    if(inValue.match(/-?\d*\.?\d*/)) return true;
    else return false;
});
11684
  • 7,356
  • 12
  • 48
  • 71
1

How about this POJS, I'm using a cross-browser addEvent function instead of jquery and not using any regexs, but I believe it achieves what you are looking for. Pressing + or - changes the sign of the value.

HTML

<input id="test" type="text" />

Javascript

/*jslint maxerr: 50, indent: 4, browser: true */


(function () {
    "use strict";

    function addEvent(elem, event, fn) {
        if (typeof elem === "string") {
            elem = document.getElementById(elem);
        }

        function listenHandler(e) {
            var ret = fn.apply(null, arguments);

            if (ret === false) {
                e.stopPropagation();
                e.preventDefault();
            }

            return ret;
        }

        function attachHandler() {
            window.event.target = window.event.srcElement;

            var ret = fn.call(elem, window.event);

            if (ret === false) {
                window.event.returnValue = false;
                window.event.cancelBubble = true;
            }

            return ret;
        }

        if (elem.addEventListener) {
            elem.addEventListener(event, listenHandler, false);
        } else {
            elem.attachEvent("on" + event, attachHandler);
        }
    }

    function verify(e) {
        var target = e.target, // shouldn't be needed: || e.srcElement;
            value = target.value,
            char = String.fromCharCode(e.keyCode || e.charCode);

        if (value.charAt(0) === "-") {
            if (char === "+") {
                e.target.value = value.slice(1);
            }
        } else if (char === "-") {
            e.target.value = char + value;
            return false;
        }

        value += char;
        return parseFloat(value) === +value;
    }

    addEvent("test", "keypress", verify);
}());

On jsfiddle

I think I used the correct values keyCode || charCode but you may want to search and check. A summary of the correct ones are available here

Xotic750
  • 22,914
  • 8
  • 57
  • 79
  • `5` -> `left arrow` -> `-` -> bug – Ilya Jun 21 '13 at 18:28
  • 1
    1) Press `5`; 2) Press `left arrow`; 3) press `-`; **Expected**: -5, **Actual**: 5 – Ilya Jun 21 '13 at 19:51
  • I think the only way to deal with that is for the `+` or `-` to change the sign of the input, because there is no way to know the position of the cursor on keypress (at least not that I know of). I have updated the code. – Xotic750 Jun 21 '13 at 22:15
  • this solution is better then other, thx. **P.S.** Use `e.srcElement` instead of `e.target` for IE compatibility. – Ilya Jun 25 '13 at 05:47
  • Updated with `srcElement` as a comment, but it shouldn't be needed as it is taken care of in `addEvent` -> `window.event.target = window.event.srcElement;`. – Xotic750 Jun 25 '13 at 09:35
0

You could use this code to find out what character is pressed. Validate that character and, if it validates, append it to the input field.

Community
  • 1
  • 1
Walter81
  • 493
  • 2
  • 8
  • 21
  • I can validate already typed value, and current pressed key. But I cann't validate full text that will be in input – Ilya Jun 21 '13 at 12:08
  • @Ilya In an `onkeydown` listener get the symbol that is being typed, then retrieve the value of the input of which you want the content validated. Then append the symbol being typed to that and `return false` if that doesn't validate, `return true` otherwise. – 11684 Jun 21 '13 at 12:46
0

Try this code:

jQuery.fn.numeric = function (pattern) 
{
    $(this).keypress(function(e)
    {
         var sChar = String.fromCharCode(!e.charCode ? e.which : event.charCode);
        e.preventDefault();
        var sPrev = $(this).val();
        if(!pattern.test(sChar)){
            return false;
        } else {
            sPrev = sPrev + sChar;
        }

        $(this).val(sPrev);

    });

};

$("#validateId").numeric(/^-?\d*\.?\d*$/);

jsfiddle.net/aBNtH/

UPDATE: My example validates each charachter while typing. If you prefer to check the entire value of the input field instead, I would suggest to validate the value on an other Event, like Input blur().

predkony
  • 101
  • 3