Yass
Yass

Reputation: 602

jQuery current regular expression

I would like to assign a regular expression with the following format.

This can go upto 10 digits, followed by a . (dot) and 2 decimals. I tried something like this,

$(document).on("keypress", "#Amount", function (e) {
    var regex = new RegExp("^\d{1,10}(\.\d{2})?$");
    var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);

    if (regex.test(str)) {
        return true;
    }
    return false;
});

The above script is not allowing me to type anything in the text box.

but it didn't work.

JSFiddle

https://jsfiddle.net/Lag7gu7k/

Upvotes: 1

Views: 116

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627488

It seems you need to implement two things:

  • restrict live input so that a user could onlytype the numbers Iin the desired format
  • perform final validation of the user input.

Regexes for live and final input validation should be different and they must be used on different events.

See the JS demo showing how you can achieve that.

For live validation, on keypress event, use

var regex = /^\d{0,10}(?:\.\d{0,2})?$/;

For final validation, on, say, blur event, use

var regex = /^\d{1,10}(?:\.\d{2})?$/;

UPDATE

I enhanced the demo to allow more complex scenarios:

  • It won't allow typing . before the 3rd and more characters from the end
  • It should allow deleting the input by selecting the value with a mouse and typing another digit.

var regex_final = /^\d{1,10}(?:\.\d{2})?$/;
var regex = /^\d{0,10}(?:\.\d{0,2})?$/;
var last_input_char = '';
$(document).on("keypress", "#Amount", function (e) {
   last_input_char = String.fromCharCode(e.charCode);
   var containsDecimalPoint = /\./.test($(this).val());
   if (containsDecimalPoint && /\.[^.]*\./.test($(this).val() + last_input_char)) {
       return false;
   } else {
     var sel_idx = $(this).getCursorPosition();
     var real_new_value = $(this).val().splice(sel_idx, 0, last_input_char);
     var pass = regex.test(real_new_value);
     return (e.charCode === 0 || /\d/.test(last_input_char) || 
            /\./.test(last_input_char) && !containsDecimalPoint) && pass;
   }
});

$(document).on("blur", "#Amount", function (e) {
   var isValidAsPerRx = regex_final.test($(this).val());
   if (!isValidAsPerRx) {
      $('#Amount').removeClass("right");
   		$('#Amount').addClass( "wrong" );
   } else {
      $('#Amount').addClass( "right" );
      $('#Amount').removeClass("wrong");
   }
});

// Adding the string.insert function
String.prototype.splice = function(idx, rem, str) {
    return this.slice(0, idx) + str + this.slice(idx + Math.abs(rem));
};

// Adding the function to get caret position
(function ($, undefined) {
    $.fn.getCursorPosition = function() {
        var el = $(this).get(0);
        var pos = 0;
        if('selectionStart' in el) {
            pos = el.selectionStart;
        } else if('selection' in document) {
            el.focus();
            var Sel = document.selection.createRange();
            var SelLength = document.selection.createRange().text.length;
            Sel.moveStart('character', -el.value.length);
            pos = Sel.text.length - SelLength;
        }
        return pos;
    }
})(jQuery);
.right {
    background: white;
    color: black;
  }
  .wrong {
    background: yellow;
    color: red;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="myform">
  <input type="text" id="Amount" /><br/><span id="Error"></span>
</form>

Upvotes: 1

ndnenkov
ndnenkov

Reputation: 36110

^\d{1,10}(\.\d{2})?$

See it in action

The idea is:

  • ^$ - from the start til the end of the string
  • \d{1,10} - one to ten digits
  • \.\d{2} - followed by a dot and two digits
  • ()? - which are optional

Upvotes: 0

Related Questions