Kieran Senior
Kieran Senior

Reputation: 18230

JavaScript Decimal Place Restriction With RegEx

I have some client-side validation against a text box, which only allows numbers up to two decimal places with no other input.

This script was a basis for entering numeric values only, however it needs to be adapted so it can take a decimal point followed by only up to two decimal places.

I've tried things such as /[^\d].\d{0,2}, but then the replacement call wouldn't work, and I've got no idea how to do it.

Code

<script type="text/JavaScript">
  function valid(f) {
    if (!/^\d*$/.test(f.value)) {
      f.value = f.value.replace(/[^\d]/g,"");
      alert("Invalid number");
    }
  }
</script>

Note

I need to match an empty string. If an empty string is provided and the form is submitted, the value defaults back to zero.

Upvotes: 13

Views: 45243

Answers (7)

John Slegers
John Slegers

Reputation: 47111

Regex

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

JavaScript

function valid(f) {
  if(!f.value) { // Test if text field is empty
    f.value = 0; // Initialize value to 0
    console.log("Valid number"); // Let user know input is OK
  } else if (!/^\d+(\.\d{1,2})?$/.test(f.value)) { // Test regex
    f.value = ""; // Empty the text box
    console.error("invalid number"); // Let user know input is not OK
  } else {
    console.log("Valid number"); // Let user know input is OK
  }
}

document.getElementById("testbutton").addEventListener( // Add event listener to button
  "click",
  valid.bind( // Bind the text field to the `value` function
    this, 
    document.getElementById("testfield")
  )
);
<input id="testfield" value="15.1" />
<button id="testbutton">Test expression</button>


Explanation

  1. / / : the beginning and end of the expression
  2. ^ : whatever follows should be at the beginning of the string you're testing
  3. \d+ : there should be at least one digit
  4. ( )? : this part is optional
  5. \. : here goes a dot
  6. \d{1,2} : there should be between one and five digits here
  7. $ : whatever precedes this should be at the end of the string you're testing

Tip

You can use regexr.com or regex101.com for testing regular expressions directly in the browser!

Upvotes: 2

zlsmith86
zlsmith86

Reputation: 380

You could use a javascript function instead of regex

function IsValid(value) {
    var split = value.split('.');

    if (split.length != 2) {
        return false;
    }
    else if (split[1].length > 2 || !Number(split[1])) {
        return false;
    }
    else if (!(split[0] == '' || split[0] == '0')) {
        return false;
    }

    return true;
}

Upvotes: 1

Raj Thakur
Raj Thakur

Reputation: 1

If we need to validate numric value in a textbox where we want to prevent more than one decimals(e.g 2..3,.2. etc)

Below is the Javascript funcion for that.

 if (MoreThanOnePoint(document.getElementById("txtNoofHrs").value) == false) {
     alert("Please enter one decimal only");
     document.forms[0].txtNoofHrs.focus();
     return false;
 }

 function MoreThanOnePoint(strString) {
     var strChar;
     var blnResult = true;
     var varcount = 0;

     for (i = 0; i < strString.length && blnResult == true; i++) {

         if (strString.charAt(i) == ".") {
             varcount++;
             if (varcount > 1) {
                 //alert("Please enter one decimal only");
                 blnResult = false;
             }
         }
     }
     return blnResult;
 }

Upvotes: 0

Georg Sch&#246;lly
Georg Sch&#246;lly

Reputation: 126175

. means in RegEx: any character, you have to put a backslash infront of it. \.

This would be better:

/^\d+(\.\d{0,2})?$/

Parts I included:

  • You need at least 1 number in front of the dot. If you don't want this, replace + with * but then also empty strings would be matched.
  • If you have decimal values you need the dot in front.
  • There shouldn't be anything after the number, $ stands for the end of the input.

and for the replacing part you should also include the dot

f.value.replace(/[^\d\.]/g, "")

Edit:

If it's for the live validation of inputs, why don't you just either intercept keyevents and test for their validity (by creating the string in memory) or just delete the last character in the field?

Upvotes: 7

Ken
Ken

Reputation: 78922

Do you really want to do this with a regex?

function valid(f) {
    if(isNaN(f)){return false;}
    return 100 * f == parseInt(100*f,10);
}

Upvotes: 3

Kieran Senior
Kieran Senior

Reputation: 18230

gs: This is very close, but the line

f.value = f.value.replace(/[^\d\.]/g, "");

Doesn't actually appear to work. In fact I lose focus of the text box for some reason. Although perhaps it's my code ;)

Upvotes: 2

AnthonyWJones
AnthonyWJones

Reputation: 189555

The . character has special meaning in RegEx so needs escaping.

/^(?:\d*\.\d{1,2}|\d+)$/

This matches 123.45, 123.4, 123 and .2, .24 but not emtpy string, 123., 123.456

Upvotes: 23

Related Questions