0

I have to validate the user input of an input field (type number) with a regex.

I reveice the following dynamic values:

  • minimum: i'm already validating that with angular
  • maximum: i'm already validating that with angular
  • increment: <- my problem

An example: minimum: 10; maximum: 100; increment: 10

Allowed user input with the dynamic increment of 10 should be:

10 - 20 - 30 - 40 - 50 - 60 - 70 - 80 - 90 - 100

Other examples:

  • minimum: 0; maximum: 2000; increment: 100
  • minimum: 1; maximum: 3.4; increment: 0.2

I have tried several regex expressions, but not even one worked with the dynamic values (different number length/decimal). Maybe it's easier to have one with numbers and one for numbers with decimal.

Thank you for your help!

bluepix
  • 107
  • 1
  • 11
  • Why do you _need_ to use regular expressions here? – Rubens Farias Oct 26 '15 at 08:45
  • 6
    `I have to validate the user input of an input field (type number) with a regex.`. No, you don't _have to_. Whoever told you so is wrong. Do it some other way. Related: [When you should not use regular expressions](http://programmers.stackexchange.com/questions/113237/when-you-should-not-use-regular-expressions) – PurkkaKoodari Oct 26 '15 at 08:45

3 Answers3

3

Use input tag with proper attributes. HTML5 provides you with a step attribute.

<input type="number" min=10 max=100 step=10 />
<input type="number" min=0 max=2000 step=100 />
<input type="number" min=0 max=3.4 step=0.2 />
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
0

Fast answer to your question (since you said angular, I assume you need it for JS):

function tenToHundred(num){
    return /^[1-9]{1}0{1}$|^100$/.test(num);
}
for(var i=1;i<=11;i++)console.log(tenToHundred(i*10));//10 ~ 100 test

Suggestion about those kind of checks (based on your examples), REGEX as a tool is for string patterns checks\matches etc... It's less suitable for numeric calculations so perhaps you should consider other methods for validation. for example - using remainder operator

function tenToHundred(num){
    var min=10, max=100, increment=10;//when need to maintain - just change those
    return num>=min && num<=max && num%increment==0;
}
for(var i=1;i<=10;i++)console.log(tenToHundred(i*10));//10 ~ 100 tests

This way it will be easier to maintain you code.

Nikita Kurtin
  • 5,889
  • 4
  • 44
  • 48
0

you are right. Now I'm setting the step value as hjpotter92 and added some logic as Nikita Kurtin mentioned. Angular is not able to validate the step out of the box..

<input type="number" step="10" validate-step />

Then I wrote a parser:

angular
    .module( '....validateStep', [] )
    .directive( 'validateStep', ValidateStepDirective );

/**
 * @namespace ValidateStepDirective
 * @example <validate-step></validate-step>
 * @memberOf Directives
 */
function ValidateStepDirective(){
    return {
        require: 'ngModel',
        link: ValidateStepDirectiveController
    };
}

function ValidateStepDirectiveController( scope, element, attrs, ctrl ){
    var step;
    if( attrs.step) {
        step = parseFloat( attrs.step );
    }

    function isValidStep( value, step ) {
        var checkValue = value * 100;
        // fixing js multiplication issue (2.3*100=229.999999)
        checkValue = checkValue.toFixed(0);
        var checkStep = step * 100;
        return checkValue%checkStep  === 0;
    }

    function stepValidator(viewValue){
        if( step && isValidStep(viewValue, step) ){
            ctrl.$setValidity( 'step', true );
            return viewValue;
        }else{
            ctrl.$setValidity( 'step', false );
            // if invalid, return undefined
            // (no model update happens)
            return;
        }
    }

    ctrl.$parsers.unshift( stepValidator );
}

I hope I can help others with my solution.

bluepix
  • 107
  • 1
  • 11