Search code examples
javascriptangularjsangular-ngmodel

insert character automatically while typing a date in angularJS


Say I have this html:

<input class="input-date" type="text" placeholder="DD.MM.YY" ng-model="hctrl.dateInput">

While the user is typing the date I want to automatically insert . at the proper places.

I tried solving this with $watch like this:

.controller('homeController', ['$scope', function($scope){
        var controller = this;
        controller.pageClass = 'page-home'
        controller.dateInput = '';

        $scope.$watch(angular.bind(this, function() {
            return this.dateInput;
        }), function(newVal, oldVal){

            var str = newVal.replace(/[.]/g, "");

            console.log('oldVal: ' + oldVal + ' newVal: ' + newVal + ' str: ' + str);

            if(str.length % 2 == 0 && str.length >= 2 && str.length <= 6) {
                console.log(str.length); 
                controller.dateInput += '.';
            }    
        });

    }])

But this causes an infinite loop due to me adding to controller.dateInput while being inside the $watch.

What would be a proper way to solve this?


Solution

  • As Wawy suggested, you should use a directive. If you don't want to choose angular-ui which has a Mask directive, you can roll your own. Here is some code to get you started.

    myApp.directive("dateFormat", function() {
                var directive = {};
    
                directive.restrict = 'A'; // only as attribute
                directive.require = 'ngModel'; // communicate with the parent HTML tags ngModelController
                directive.link = function(scope, element, attrs, ctrl) {
                    scope.$watch(function() { return ctrl.$modelValue }, function(newVal, oldVal){
                        console.log("value in my parent is: " + newVal);
                        // logic here, such as if (newVal.endsWith('.'))...
                    });
                }
                return directive;
            });
    

    And then in your HTML: <input type="text" ng-model="my.model" date-format>