15

Please find the fiddle http://jsfiddle.net/q2SgJ/5/

<div ng-app="">
  <div ng-controller="Ctrl">

      WANTS:  {{val | number:2}} in "input" elelent<br>
    2 decimal in input:  <input  ng-model='val'> <br>
    2 decimal in input:  <input  type="number" step="0.01" ng-model='val'><br>
    2 decimal in input:  <input  ng-model='val' value="{{val |number:2}}"> <br>

  </div>
</div>

How can I restrict the decimal places to 2 digits in an INPUT field. As in the example {{val | number:2}} works, but not sure how to use it to format the ng-model attached to an field. I could have formatted the data/model itself, but I have few values I like to keep the extra decimal, but only display 2 decimal.

Thanks.

4 Answers 4

8

You can write a directive to control this functionality. It is not something that ships with angular, but directives can control how things look and work on the page.

I wrote a simple one: http://jsfiddle.net/q2SgJ/8/

This is the linking function that does the trick:

   link:function(scope,ele,attrs){
        ele.bind('keypress',function(e){
            var newVal=$(this).val()+(e.charCode!==0?String.fromCharCode(e.charCode):'');
            if($(this).val().search(/(.*)\.[0-9][0-9]/)===0 && newVal.length>$(this).val().length){
                e.preventDefault();
            }
        });
    }

This works at limiting the input to 2 decimal places, but doesn't format the input to two decimal places. Anyways, it is a starting point. I am sure you can look up other examples and write your own directive to handle this the way you want. The thing about Angular is that it is not a framework with an answer to every question, but a framework that allows you to create additional functionality than what HTML5 provides alone and makes it very simple.

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

3 Comments

Tim, thanks for confirming it is not natively possible with html5, and also the approach necessary in Angular.
this directive will stop you entering any values once 2dp has been reached ie. you won't be able to change the numbers to the left of the decimal point
^ Agreed. It assumes the user is only entering a number (user input is always right-most), so doesn't handle numbers being edited in any other position.
8

You can do this without JQuery, and without a directive. Your original attempt with step was very close. I found this site that shows how to use HTML5 inputs to restrict using the step and AngularJS regular expression input filters.

<div ng-app="app">
    <div ng-controller="Ctrl"> @*Just an empty controller in this example*@
        <form name="myForm">
            <input type="number" name="myDecimal" placeholder="Decimal" ng-model="myDecimal" ng-pattern="/^[0-9]+(\.[0-9]{1,2})?$/" step="0.01" /><br />
            Is a valid decimal?<span ng-show="!myForm.myDecimal.$valid">{{myForm.myDecimal.$valid}}</span>
        </form>
    </div>
</div>

Comments

4

I expanded on the accepted answer to look at the step attribute when determining how many decimal places to limit.

directive('forcePrecision', function () {
    return {
        restrict: 'A',
        scope: {
           step: '@'
        },
        link: function (scope, element, attrs) {
            if (!scope.step || scope.step == 'any') {
               return;
            }

            var prec = 1;
            for (var i = scope.step; i != 1; i *= 10) {
                prec *= 10;
            }

            element.on('keypress', function (e) {
                var val = Number(element.val() + (e.charCode !== 0  ? String.fromCharCode(e.charCode) : ''));

                if (val) {
                    var newVal = Math.floor(val * prec) / prec;

                    if (val != newVal) {
                        e.preventDefault();
                    }
                }
            });
        }
    };
});

Comments

0

I have extended the Tim's fiddle incase some one is looking for working solution

http://jsfiddle.net/q2SgJ/653/

modified the keypress event to retrieve the original typed value based on the cursor position

ele.bind('keypress',function(e){
        var value = $(this).val();
                    var decimalPointPosition = value.indexOf(".");
                    if(!((e.charCode === 46) || (e.charCode > 47 && e.charCode <= 57)))
                        e.preventDefault();

                    else if (decimalPointPosition >= 0) {
                        var decimalCount = value.substring(decimalPointPosition + 1).length;
                        if ((decimalCount == 2 && $(this).prop("selectionStart") > decimalPointPosition)) {
                            e.preventDefault();                     
            }
           }       

        }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.