20

I have markup like this:

<form name="myForm" ng-controller="myCtrl" novalidate>
    <input ng-model="theValue" type="range" min="0" max="100" required>
    <input ng-model="theValue" type="number" required></input>
    <span ng-show="theValue.$error.number">Hey! No letters, buddy!</span>
</form>

And I want the span to show when the user accidentally types a letter in the second input. Simple, right? As an (probably) related problem, the value in the second input disappears when the user moves the first slider input. Why? This doesn't happen if I remove type-number from the markup.

To be clear: I want the user to see the tooltip error immediately when it's typed, without any "submit" action. (I'd prefer not to have to use the form element at all in fact, but all the related demos seem to require it.)

http://jsfiddle.net/7FfWT/

Any workaround is most welcome. Please post a working fiddle if possible.

4 Answers 4

16

There seems to be a weird issue with type="number" playing nicely with other inputs.

The posts in this google groups post should get you on the right track. In particularly, the last post there: https://groups.google.com/forum/#!msg/angular/Ecjx2fo8Qvk/x6iNlZrO_mwJ

The jsfiddle link is: http://jsfiddle.net/ABE8U/

As a work around, he's made a directive:

.directive('toNumber', function () {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            ctrl.$parsers.push(function (value) {
                return parseFloat(value || '');
            });
        }
    };
});

Credit to Schmuli Raskin

Sign up to request clarification or add additional context in comments.

2 Comments

Awesome. Glad it's not just me then :) Thank you! (and Schmuli...) Finally got this going: jsfiddle.net/HQUgW/13
Nope 2dd will return true. you should check with !isNaN( parseFloat(obj) ) && isFinite( obj ) jsfiddle.net/ABE8U/148
16

Also you can use ng-pattern as validator:

<input type="number" ng-model="theValue" name="theValue" step="1" min="0" max="10"  ng-pattern="integerval" required>
<span ng-show="form.theValue.$invalid">Hey! No letters, buddy!</span>

$scope.integerval = /^\d*$/;

1 Comment

This is the best solution if you don't want to use html5 input[number]
2

I've updated the directive to work with ng-repeat filters. Notice the '$', which is a wildcard. This directive should handle 0 just fine. It fails over to wildcard on

.directive('toNumber', function() {
    return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
            ctrl.$parsers.push(function(value) {
                return value===0 ? 0 : (parseFloat(value) || '$');
            });
    };
})

Comments

0

jzm,s answer is really wonderful trick and saved my time.

I am just taking it to one step further and replacing parseFloat(value) with what it actually does.

directive('number', function () {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, ngModel) {

            ngModel.$parsers.push(function (value) {
                if (value==null)
                  return NaN;
            });
        }
    };
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.