Create directive for mask

1

I want to use the xx/xx/xxxx mask in a date field and return the object with the mask, not just the value. I used a ui-mask directive, but it does not return with the mask, I already used model-view-value="true" but it does not work, so I want to create a directive that just takes the value and add the bars "//" via javascript with substring , only this. But how do you use it with ui-mask ? by logic, would the directive have to be executed after the date is all typed?

Here's what I did:

angular.module("modulo").directive("uiDate", function ($filter) {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ctrl) {
            var _formatDate = function (date) {
                date = date.replace(/[^0-9]+/g, "");
                if(date.length > 2) {
                    date = date.substring(0,2) + "/" + date.substring(2);
                }
                if(date.length > 5) {
                    date = date.substring(0,5) + "/" + date.substring(5,9);
                }
                return date;
            };
        }
    };
});

But it still does not work, because the execution of it is not calling agreement, it is called only when loading the page, it would have to be after the field already have the date, to return only to my ng-model the value with the mask . How would it look?

    
asked by anonymous 13.01.2016 / 03:39

3 answers

1

Use the $watch function inside the link function, where you will observe the changes that occur in the property, and then you can apply the mask logic to the date value.

scope.$watch('propriedade', function (valorAtual, valorAnterior) {
    //código.
});

Documentation for $ watch

    
13.01.2016 / 10:43
0

You can have the function run whenever the user types, or, put a timeout to always execute n seconds after it has stopped typing.

What to use then?

If you want the user to see the change in real time, use without timeout . But if it's okay for the user to type everything and only after formatting the date, you can use it with timeout . Or as you see fit.

To do this, simply use the element.onkeypress = function()... method, see:

return {
    require: "ngModel",
    link: function (scope, element, attrs, ctrl) {

        element.onkeypress = function() { //É aqui que ele executa a função sempre que uma tecla for pressionada
            var _formatDate = function (date) {
                date = date.replace(/[^0-9]+/g, "");
                if(date.length > 2) {
                    date = date.substring(0,2) + "/" + date.substring(2);
                }
                if(date.length > 5) {
                    date = date.substring(0,5) + "/" + date.substring(5,9);
                }
                return date;
            };
        } //finaliza o element.onkeypress

    }
};

Or, if you're going to use it with timeout , use it as follows:

element.onkeypress = function() {
    $timeout(function(){
        var _formatDate = function(date) {
        //... restante do código aqui
    }, 1000);
}

Why am I giving this answer and how does it differ from the previous answer, which uses $watch ?

There is a lot of controversy in using the $watch property when we refer to performance, since it is associated with $digest firing, which is the cycle that updates all $scope variables of your page. So the more variables you have, the heavier your application will be with $watch , since it will need to parse all variables whenever the field changes value.

The onkeypress method does not pass this, because it depends on the values of variables, it depends only on the interaction with the field.

    
13.01.2016 / 11:07
0

It worked fine for me like this:

angular.module("aeronaves").directive("uiDate", function() {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ctrl){
            var _formatDate = function(date){
                date = date.replace(/[^0-9]+/g, "");
                if(date.length > 2) {
                    date = date.substring(0,2) + "/" + date.substring(2);
                }
                if(date.length > 5){
                    date = date.substring(0,5) + "/" + date.substring(5,9);
                }

                return date;
            };

            element.bind("keyup", function (){
                ctrl.$setViewValue(_formatDate(ctrl.$viewValue));
                ctrl.$render();
            });
        }
    };

});

    
12.02.2016 / 04:11