I'm trying to achieve a kind of generic remaining function. I have a bunch of fields in my form, for example: name and address. These fields have a limit of characters size, my goal is to make a generic function to limit it's size when reached. So I made a sample function that works:
First on the page:
label(for='name') Name {{remaining()}} of {{totalChars}}
Second, the code to handle it:
$scope.totalChars = 10;
$scope.remaining = function() {
var count = 0;
if ($scope.mName) {
count = $scope.mName.length;
if (count > $scope.totalChars) {
$scope.mName = $scope.mName.trim().substr(0, $scope.mName.length - 1);
count = $scope.mName.length;
}
}
return count;
//return calculateChars($scope.mName, $scope.totalChars);
};
When I type some input value into name field, angular stops typing when 10 chars are reached as well. But I've remade the function to turn it in a generic way and try to use it for any field I want to, but doesn't work as expected:
$scope.totalChars = 10;
$scope.remaining = function() {
return calculateChars($scope.mName, $scope.totalChars);
};
...
function calculateChars(obj, size) {
var count = 0;
if (obj && obj !== 'undefined') {
count = obj.length;
if (count > size) {
$scope.obj = obj.trim().substr(0, obj.length - 1);
console.log('Result: ' + $scope.obj);
count = obj.length;
}
}
return count;
}
The calculateChars works partiality fine, the problem is $scope.obj = obj.trim().substr(0, obj.length - 1); because angularjs doesn't know what "obj" is and doesn't stop typing when 10 chars are reached, even counting the amount correctly.
I don't know how to make the first approach works for any case without duplicate any code for any text field I want to.
Thanks in advance!
It sounds like you're looking for a directive. Here's an example of a directive named remaining that, given a model and a "max length" attribute, displays how many characters are remaining. It also prevents the user from typing more than the max number of characters; this can be removed by getting rid of the first branch of the if (remaining < 0) check in the link function.
app.directive('remaining', function() {
return {
template: "{{remaining}} of {{maxLen}}",
scope: {
maxLen: '@max',
model: '=ngModel'
},
link: function(scope, elem, attrs) {
scope.$watch('model', function(val) {
if (val == null || val == undefined) return;
var maxLen = parseInt(scope.maxLen, 10);
var remaining = maxLen - val.length;
if (remaining < 0)
scope.model = val.substr(0, maxLen);
else
scope.remaining = remaining;
});
}
};
});
Here's a jsFiddle to demonstrate: http://jsfiddle.net/BinaryMuse/JanZm/. Note I'm using version 1.1.x of AngularJS to get access to the ngTrim directive, which tells Angular not to strip off whitespace in text fields.