Apply mask to dynamic fields generated after page onload

Asked

Viewed 885 times

4

I am using a directive for Mask in monetary field, the work is performed on the screen inserir a descrição da imagem aqui

the problem is when I insert a new item ng-repeat inserts new fields without the Mask, I reference the class and use the created format="priceformat directive".

By clicking on + new items do not start with the mask used.

var myApp = angular.module('myApp', []);


myApp.controller('PushController', function ($scope, $http, $timeout) {

    $scope.discriminations = [];

    $scope.discrimination = {
        id: '',
        name: '',
        value: 'R$ 0,00',
        value_addition: 'R$ 0,00',
        value_discount: 'R$ 0,00'
    };

    			$scope.addDiscrimination = function() {
				var _length = $scope.discriminations.push({
                                                id: '', 
                                                value: 'R$ 0,00', 
                                                value_decimal: 0,
                                                value_addition: 'R$ 0,00', 
                                                value_addition_decimal: 0,
                                                value_discount: 'R$ 0,00', 
                                                value_discount_decimal: 0,
                                                observations: ''
				});
                                     
			};
    
    $scope.$watch('discrimination.id', function (value) {

        if (value != '') {

            alert(value);
            //     $scope.id_restaurant_menu = value;

        }
    });
});




// Angular
myApp.filter('priceformat', function () {
    var is_number = /[0-9]/;
    var prefix = 'R$ ';
    var suffix = '';
    var centsSeparator = ',';
    var thousandsSeparator = '.';
    var limit = false;
    var centsLimit = 2;
    var clearPrefix = false;
    var clearSufix = false;
    var allowNegative = false;
    var insertPlusSign = false;

    if (insertPlusSign) allowNegative = true;

    function to_numbers(str) {
        var formatted = '';
        for (var i = 0; i < (str.length); i++) {
            char_ = str.charAt(i);
            if (formatted.length == 0 && char_ == 0) char_ = false;
            if (char_ && char_.match(is_number)) {
                if (limit) {
                    if (formatted.length < limit) formatted = formatted + char_
                } else {
                    formatted = formatted + char_
                }
            }
        }
        return formatted
    }

    function fill_with_zeroes(str) {
        while (str.length < (centsLimit + 1)) str = '0' + str;
        return str
    }

    return function (str) {
        var formatted = fill_with_zeroes(to_numbers(str));
        var thousandsFormatted = '';
        var thousandsCount = 0;
        if (centsLimit == 0) {
            centsSeparator = "";
            centsVal = ""
        }
        var centsVal = formatted.substr(formatted.length - centsLimit, centsLimit);
        var integerVal = formatted.substr(0, formatted.length - centsLimit);
        formatted = (centsLimit == 0) ? integerVal : integerVal + centsSeparator + centsVal;
        if (thousandsSeparator || $.trim(thousandsSeparator) != "") {
            for (var j = integerVal.length; j > 0; j--) {
                char_ = integerVal.substr(j - 1, 1);
                thousandsCount++;
                if (thousandsCount % 3 == 0) char_ = thousandsSeparator + char_;
                thousandsFormatted = char_ + thousandsFormatted
            }
            if (thousandsFormatted.substr(0, 1) == thousandsSeparator) thousandsFormatted = thousandsFormatted.substring(1, thousandsFormatted.length);
            formatted = (centsLimit == 0) ? thousandsFormatted : thousandsFormatted + centsSeparator + centsVal
        }
        if (allowNegative && (integerVal != 0 || centsVal != 0)) {
            if (str.indexOf('-') != -1 && str.indexOf('+') < str.indexOf('-')) {
                formatted = '-' + formatted
            } else {
                if (!insertPlusSign) formatted = '' + formatted;
                else formatted = '+' + formatted
            }
        }
        if (prefix) formatted = prefix + formatted;
        if (suffix) formatted = formatted + suffix;
        return formatted
    }
});


myApp.directive('format', ['$filter',

function ($filter) {
    return {
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            $(elem).priceFormat({
                    prefix: 'R$ ',
                    centsSeparator: ',',
                    thousandsSeparator: '.',
                    centsLimit: 2,
                    limit: 14,
                });            
            
            ctrl.$formatters.unshift(function (a) {
                return $filter('priceformat')(ctrl.$modelValue)
            });
            ctrl.$parsers.unshift(function (viewValue) {
                return $filter('priceformat')(viewValue)
            });
        }
    };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://unionerp.com.br/media/javascript/production/unionerp.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp" ng-controller="PushController">
    <div style="float: left; width: 25%; margin-right: 10px;">Valor
        <br />
        <input type="text" style="width: 100%; text-align: right;" ng-model="discrimination.value" format="priceformat" placeholder="R$ 0,00" class="money" />
    </div>
    <div style="float: left; width: 25%; margin-right: 10px;">Adicional
        <br />
        <input type="text" style="width: 100%; text-align: right;" ng-model="discrimination.value_addition" format="priceformat" placeholder="R$ 0,00" class="money" />
    </div>
    <div style="float: left; width: 20%; margin-right: 10px;">Desconto
        <br />
        <input type="text" style="width: 100%; text-align: right;" ng-model="discrimination.value_discount" format="priceformat" placeholder="R$ 0,00" class="money" />
        
       
    </div>
    
             <a ng-click="addDiscrimination()" style="float: left;" style="width: 5%;">
            +
        </a>
        
    
    <div style="clear: both;"></div>
    <div ng-repeat="obj in discriminations">
        <input type="text" style="width: 100%; text-align: right;" ng-model="obj.value" format="priceformat" placeholder="R$ 0,00" class="money" />
    </div>
    <br />
    <div>
        <table border="1">
            <thead>
                <tr role="row">
                    <th>VALOR</th>
                    <th>ADICIONAL</th>
                    <th>DESCONTO</th>
                    <th>TOTAL</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td style="text-align: right;">{{ discrimination.value }}</td>
                    <td style="text-align: right;">{{ discrimination.value_addition }}</td>
                    <td style="text-align: right;">{{ discrimination.value_discount }}</td>
                    <td style="text-align: right;">R$ 0,00</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

Jsfiddle

  • Solved by applying a Monetary Field Mask plugin https://github.com/assisrafael/angular-input-masks

  • You can post the code with resolution to help other people with the same problem?

  • Complementing what @Giovaniracipaganini said, it would be nice to say why you chose this solution. I turned your reply into a comment, but if you want you can edit the original reply and undo the deletion. Thank you.

1 answer

2

You are applying the plugin like this:

$('.money').priceFormat({
    prefix: 'R$ ',
    centsSeparator: ',',
    thousandsSeparator: '.',
    centsLimit: 2,
    limit: 14,
});

This snippet will only run once and will apply the plugin only to elements that are already in the GIFT.

An alternative is you call $.priceFormat in each element directly function link of its directive:

myApp.directive('format', ['$filter',

function ($filter) {
    return {
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            $(elem).priceFormat({
                    prefix: 'R$ ',
                    centsSeparator: ',',
                    thousandsSeparator: '.',
                    centsLimit: 2,
                    limit: 14,
                });            

            ctrl.$formatters.unshift(function (a) {
                return $filter('priceformat')(ctrl.$modelValue)
            });
            ctrl.$parsers.unshift(function (viewValue) {
                return $filter('priceformat')(viewValue)
            });
        }
    };
}]);

This way each time the angular process a new item that contains the directive the plugin will already be applied directly.

See working:

var myApp = angular.module('myApp', []);


myApp.controller('PushController', function ($scope, $http, $timeout) {

    $scope.discriminations = [];

    $scope.discrimination = {
        id: '',
        name: '',
        value: 'R$ 0,00',
        value_addition: 'R$ 0,00',
        value_discount: 'R$ 0,00'
    };

    			$scope.addDiscrimination = function() {
				var _length = $scope.discriminations.push({
                                                id: '', 
                                                value: 'R$ 0,00', 
                                                value_decimal: 0,
                                                value_addition: 'R$ 0,00', 
                                                value_addition_decimal: 0,
                                                value_discount: 'R$ 0,00', 
                                                value_discount_decimal: 0,
                                                observations: ''
				});
                                     
			};
    
    $scope.$watch('discrimination.id', function (value) {

        if (value != '') {

            alert(value);
            //     $scope.id_restaurant_menu = value;

        }
    });
});




// Angular
myApp.filter('priceformat', function () {
    var is_number = /[0-9]/;
    var prefix = 'R$ ';
    var suffix = '';
    var centsSeparator = ',';
    var thousandsSeparator = '.';
    var limit = false;
    var centsLimit = 2;
    var clearPrefix = false;
    var clearSufix = false;
    var allowNegative = false;
    var insertPlusSign = false;

    if (insertPlusSign) allowNegative = true;

    function to_numbers(str) {
        var formatted = '';
        for (var i = 0; i < (str.length); i++) {
            char_ = str.charAt(i);
            if (formatted.length == 0 && char_ == 0) char_ = false;
            if (char_ && char_.match(is_number)) {
                if (limit) {
                    if (formatted.length < limit) formatted = formatted + char_
                } else {
                    formatted = formatted + char_
                }
            }
        }
        return formatted
    }

    function fill_with_zeroes(str) {
        while (str.length < (centsLimit + 1)) str = '0' + str;
        return str
    }

    return function (str) {
        var formatted = fill_with_zeroes(to_numbers(str));
        var thousandsFormatted = '';
        var thousandsCount = 0;
        if (centsLimit == 0) {
            centsSeparator = "";
            centsVal = ""
        }
        var centsVal = formatted.substr(formatted.length - centsLimit, centsLimit);
        var integerVal = formatted.substr(0, formatted.length - centsLimit);
        formatted = (centsLimit == 0) ? integerVal : integerVal + centsSeparator + centsVal;
        if (thousandsSeparator || $.trim(thousandsSeparator) != "") {
            for (var j = integerVal.length; j > 0; j--) {
                char_ = integerVal.substr(j - 1, 1);
                thousandsCount++;
                if (thousandsCount % 3 == 0) char_ = thousandsSeparator + char_;
                thousandsFormatted = char_ + thousandsFormatted
            }
            if (thousandsFormatted.substr(0, 1) == thousandsSeparator) thousandsFormatted = thousandsFormatted.substring(1, thousandsFormatted.length);
            formatted = (centsLimit == 0) ? thousandsFormatted : thousandsFormatted + centsSeparator + centsVal
        }
        if (allowNegative && (integerVal != 0 || centsVal != 0)) {
            if (str.indexOf('-') != -1 && str.indexOf('+') < str.indexOf('-')) {
                formatted = '-' + formatted
            } else {
                if (!insertPlusSign) formatted = '' + formatted;
                else formatted = '+' + formatted
            }
        }
        if (prefix) formatted = prefix + formatted;
        if (suffix) formatted = formatted + suffix;
        return formatted
    }
});


myApp.directive('format', ['$filter',

function ($filter) {
    return {
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            $(elem).priceFormat({
                    prefix: 'R$ ',
                    centsSeparator: ',',
                    thousandsSeparator: '.',
                    centsLimit: 2,
                    limit: 14,
                });            
            
            ctrl.$formatters.unshift(function (a) {
                return $filter('priceformat')(ctrl.$modelValue)
            });
            ctrl.$parsers.unshift(function (viewValue) {
                return $filter('priceformat')(viewValue)
            });
        }
    };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://unionerp.com.br/media/javascript/production/unionerp.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp" ng-controller="PushController">
    <div style="float: left; width: 25%; margin-right: 10px;">Valor
        <br />
        <input type="text" style="width: 100%; text-align: right;" ng-model="discrimination.value" format="priceformat" placeholder="R$ 0,00" class="money" />
    </div>
    <div style="float: left; width: 25%; margin-right: 10px;">Adicional
        <br />
        <input type="text" style="width: 100%; text-align: right;" ng-model="discrimination.value_addition" format="priceformat" placeholder="R$ 0,00" class="money" />
    </div>
    <div style="float: left; width: 20%; margin-right: 10px;">Desconto
        <br />
        <input type="text" style="width: 100%; text-align: right;" ng-model="discrimination.value_discount" format="priceformat" placeholder="R$ 0,00" class="money" />
        
       
    </div>
    
             <a ng-click="addDiscrimination()" style="float: left;" style="width: 5%;">
            +
        </a>
        
    
    <div style="clear: both;"></div>
    <div ng-repeat="obj in discriminations">
        <input type="text" style="width: 100%; text-align: right;" ng-model="obj.value" format="priceformat" placeholder="R$ 0,00" class="money" />
    </div>
    <br />
    <div>
        <table border="1">
            <thead>
                <tr role="row">
                    <th>VALOR</th>
                    <th>ADICIONAL</th>
                    <th>DESCONTO</th>
                    <th>TOTAL</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td style="text-align: right;">{{ discrimination.value }}</td>
                    <td style="text-align: right;">{{ discrimination.value_addition }}</td>
                    <td style="text-align: right;">{{ discrimination.value_discount }}</td>
                    <td style="text-align: right;">R$ 0,00</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.