I have a form and want to create a 'completion progress tracker'. If we have ten inputs that are filled in, each input will add 10 to an array, which will render some text: '100% complete'. If you remove or don't have any data in an input, 10 will be remove from the array.
In other words I want to:
Watch some items for changes
If an item has X length (or some other argument), push 10 to an array
If an item has X length removed, remove 10 from the array
Create a total of the array
I've been trying things out with $scope.$watch
and different array methods like pop()
, splice()
etc, but i'm not sure how to get this working correctly, and with nice, DRY code.
This is what I have so far (simplified outside of the app with just 3 items).
controller:
$scope.userName = 'homer';
$scope.userDescription = 'I really like...';
$scope.userUrl = 'http://something.com'
$scope.theArray = [];
$scope.$watch('userName + userDescription + userUrl', function(){
$scope.theTotal = 0;
if($scope.userName.length >= 3) {
//$scope.theArray.pop(10);
//$scope.theArray.splice(1,1);
$scope.theArray.push(10);
}
if($scope.userName.length < 3) {
console.info('oh no!');
$scope.theArray.pop(10);
}
if($scope.userDescription.length > 3) {
$scope.theArray.push(10);
}
if($scope.userUrl.length > 3) {
$scope.theArray.push(10);
}
var x = 0;
while (x < $scope.theArray.length) {
$scope.theTotal += $scope.theArray[x];
x++;
}
console.log($scope.theArray)
});
template:
<input type="text" ng-model="userName" placeholder="name" />
<input type="text" ng-model="userDescription" placeholder="description" />
<input type="url" ng-model="userUrl" placeholder="url" />
<p>userName length: {{userName.length}}</p>
<p>userDescription length: {{userDescription.length}}</p>
<p>userURL length: {{userUrl.length}}</p>
<br/>
<p><strong>completion: {{theTotal}}</strong></p>
But, obviously, this doesn't work correctly. Right now the array just keeps adding and adding, regardless of if the length is below or above the desired amount. I expect this with $scope.$watch
, I know the changes are triggered when the $watch is in action - is there a way to limit an array push()
here?
I've tried doing a pop()
and push()
at the same time and this 'works', to some degree, but it's not elegant and doesn't help to get it working as desired.
How can I achieve this? Do I need to approach $scope.$watch
and array methods differently? Or maybe something completely different?
If you don't the array for other purposes, you can avoid the array, and only add to the total if a condition is met:
$scope.theTotal = 0;
if($scope.userName.length >= 3) {
$scope.theTotal += 10;
}
if($scope.userDescription.length > 3) {
$scope.theTotal += 10;
}
if($scope.userUrl.length > 3) {
$scope.theTotal += 10;
}
Check this pen .
Tony, let's go through your $watch
func. For example I've changed userName
(and now it's length < 3) we getting into $watch
function:
if
statement ignoring (we get length < 3) if
statement and pop()
some val from the array if($scope.userDescription.length > 3)
. I didn't change userDescription
and it's length > 3 - so we add some val to the array. That's why you still keep adding new items to array.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.