AngularJs- Calculation inside a controller - angularjs

Hello I want to be able to calculate some numbers inside a controller that contains elements. This is what have tried (ionic APP too btw) :
.controller('tasksCtrl', function($scope) {
$scope.tasksCollection = [
{ info: 'Go studying', measured: 'no', total: 1, done: 1, id: 1 },
{ info: 'Go to the beach', measured: 'no', total: 1, done: 1, id: 2},
{ info: 'Run', measured: 'yes', total: 30, done: 15, id: 3}
];
$scope.calculateProductivity = function(){
var total = 0;
for(var i = 0; i < $scope.tasksCollection.length; i++){
var product = $scope.tasksCollection[i];
total += (tasksCollection.done / tasksCollection.total);
}
return total;
};
})
and the page has:
<div class="item tabs tabs-secondary tabs-icon-left">
<div ng-app="starter" ng-controller="tasksCtrl" class="tab-item tab-main-left">
<span class="title-red"> {{ calculateProductivity() }} </span><span class="medium-text">Productivity Ratio</span>
</div>
<div class="tab-item tab-main-right">
<span class="title-red">20 </span><span class="medium-text">PMoney</span>
</div>
</div>
On the output I only see "{{ calculateProductivity() }}" and not the result, but if I write tasksCollection.info it gets correctly displayed.
thanks!

you are calculating total as:
total += (tasksCollection.done / tasksCollection.total);
and it should probably be:
total += (product.done / product.total);

PLease see this: http://stackoverflow.com/questions/20942878/angularjs-use-a-function-in-a-controller-to-return-data-from-a-service-to-be-use
The following changes should work:
<span class="title-red"> {{ productivity_ratio }} </span><span class="medium-text">Productivity Ratio</span>
for(var i = 0; i < $scope.tasksCollection.length; i++){
var product = $scope.tasksCollection[i];
total += (tasksCollection.done / tasksCollection.total);
}
$scope.productivity_ratio = total;

Related

AngularJS checkbox filter directive

I have a AngularJS directive that allows users to select a values from a list to filter on. Pretty simple concept which is represented here:
Problem is when I click one of the checkboxes they all select unintended. My directive is pretty simple so I'm not sure why this is happening. The code around the selection and checkboxes is as follows:
$scope.tempFilter = {
id: ObjectId(),
fieldId: $scope.available[0].id,
filterType: 'contains'
};
$scope.toggleCheck = function (id) {
var values = $scope.tempFilter.value;
if (!values || !values.length) {
values = $scope.tempFilter.value = [];
}
var idx = values.indexOf(id);
if (idx === -1) {
values.push(id);
} else {
values.splice(idx, 1);
}
};
$scope.valuesListValues = function (id) {
return $scope.available.find(function (f) {
return f.id === id;
}).values;
};
and the data resembles:
$scope.available = [{
id: 23,
name: 'Store'
values: [
{ id: 124, name: "Kansas" },
{ id: 122, name: "Florida" }, ... ]
}, ... ]
the view logic is as follows:
<ul class="list-box">
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
<div class="checkbox">
<label ng-click="toggleCheck(val.id)">
<input ng-checked="tempFilter.value.indexOf(val.id) === -1"
type="checkbox"> {{val.name}}
</label>
</div>
</li>
</ul>
First off, it toggleCheck fires twice but populates the correct data ( second time given my code it removes it though ).
After the second fire, it checks all boxes... Any ideas?
Perhaps its that the local variable doesn't get reassigned to the property of the scope property used in the view. Since your values are then non-existent and not found, the box is checked.
$scope.tempFilter.value = values
I took the interface concept you were after and created a simpler solution. It uses a checked property, found in each item of available[0].values, as the checkbox model. At the top of the list is a button that clears the selected items.
JavaScript:
function DataMock($scope) {
$scope.available = [{
id: 23,
name: 'Store',
values: [{
id: 124,
name: "Kansas"
}, {
id: 122,
name: "Florida"
}]
}];
$scope.clearSelection = function() {
var values = $scope.available[0].values;
for (var i = 0; i < values.length; i++) {
values[i].checked = false;
}
};
}
HTML:
<body ng-controller="DataMock">
<ul class="list-box">
<li>
<button ng-click="clearSelection()">Clear Selection</button>
</li>
<li ng-repeat="val in available[0].values">
<div class="checkbox">
<label>
<input ng-model="val.checked"
type="checkbox" /> {{val.name}}
</label>
</div>
</li>
</ul>
</body>
Demo on Plunker
The repeat that I used to grab the values based on the id, was the problem area.
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
removing that and simple listening and setting a static variable resolved the problem.
$scope.$watch('tempFilter.fieldId', function () {
var fId = $scope.tempFilter.fieldId;
if ($scope.isFieldType(fId, 'valuesList')) {
$scope.valuesListValues = $scope.valuesListValues(fId);
}
}, true);
});
and then in the view:
ng-repeat="value in valuesListValues"

Angular ng-repeat with a specific value [duplicate]

Angular does provide some support for a for loop using numbers within its HTML directives:
<div data-ng-repeat="i in [1,2,3,4,5]">
do something
</div>
But if your scope variable includes a range that has a dynamic number then you will need to create an empty array each time.
In the controller
var range = [];
for(var i=0;i<total;i++) {
range.push(i);
}
$scope.range = range;
In the HTML
<div data-ng-repeat="i in range">
do something
</div>
This works, but it is unnecessary since we won't be using the range array at all within the loop. Does anyone know of setting a range or a regular for min/max value?
Something like:
<div data-ng-repeat="i in 1 .. 100">
do something
</div>
I tweaked this answer a bit and came up with this fiddle.
Filter defined as:
var myApp = angular.module('myApp', []);
myApp.filter('range', function() {
return function(input, total) {
total = parseInt(total);
for (var i=0; i<total; i++) {
input.push(i);
}
return input;
};
});
With the repeat used like this:
<div ng-repeat="n in [] | range:100">
do something
</div>
I came up with an even simpler version, for creating a range between two defined numbers, eg. 5 to 15
See demo on JSFiddle
HTML:
<ul>
<li ng-repeat="n in range(5,15)">Number {{n}}</li>
</ul>
Controller:
$scope.range = function(min, max, step) {
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step) {
input.push(i);
}
return input;
};
Nothing but plain Javascript (you don't even need a controller):
<div ng-repeat="n in [].constructor(10) track by $index">
{{ $index }}
</div>
Very useful when mockuping
I came up with a slightly different syntax which suits me a little bit more and adds an optional lower bound as well:
myApp.filter('makeRange', function() {
return function(input) {
var lowBound, highBound;
switch (input.length) {
case 1:
lowBound = 0;
highBound = parseInt(input[0]) - 1;
break;
case 2:
lowBound = parseInt(input[0]);
highBound = parseInt(input[1]);
break;
default:
return input;
}
var result = [];
for (var i = lowBound; i <= highBound; i++)
result.push(i);
return result;
};
});
which you can use as
<div ng-repeat="n in [10] | makeRange">Do something 0..9: {{n}}</div>
or
<div ng-repeat="n in [20, 29] | makeRange">Do something 20..29: {{n}}</div>
For those new to angularjs.
The index can be gotten by using $index.
For example:
<div ng-repeat="n in [] | range:10">
do something number {{$index}}
</div>
Which will, when you're using Gloopy's handy filter, print:
do something number 0
do something number 1
do something number 2
do something number 3
do something number 4
do something number 5
do something number 6
do something number 7
do something number 8
do something number 9
A short way of doing this would be to use Underscore.js's _.range() method. :)
http://underscorejs.org/#range
// declare in your controller or wrap _.range in a function that returns a dynamic range.
var range = _.range(1, 11);
// val will be each number in the array not the index.
<div ng-repeat='val in range'>
{{ $index }}: {{ val }}
</div>
I use my custom ng-repeat-range directive:
/**
* Ng-Repeat implementation working with number ranges.
*
* #author Umed Khudoiberdiev
*/
angular.module('commonsMain').directive('ngRepeatRange', ['$compile', function ($compile) {
return {
replace: true,
scope: { from: '=', to: '=', step: '=' },
link: function (scope, element, attrs) {
// returns an array with the range of numbers
// you can use _.range instead if you use underscore
function range(from, to, step) {
var array = [];
while (from + step <= to)
array[array.length] = from += step;
return array;
}
// prepare range options
var from = scope.from || 0;
var step = scope.step || 1;
var to = scope.to || attrs.ngRepeatRange;
// get range of numbers, convert to the string and add ng-repeat
var rangeString = range(from, to + 1, step).join(',');
angular.element(element).attr('ng-repeat', 'n in [' + rangeString + ']');
angular.element(element).removeAttr('ng-repeat-range');
$compile(element)(scope);
}
};
}]);
and html code is
<div ng-repeat-range from="0" to="20" step="5">
Hello 4 times!
</div>
or simply
<div ng-repeat-range from="5" to="10">
Hello 5 times!
</div>
or even simply
<div ng-repeat-range to="3">
Hello 3 times!
</div>
or just
<div ng-repeat-range="7">
Hello 7 times!
</div>
Simplest no code solution was to init an array with the range, and use the $index + however much I want to offset by:
<select ng-init="(_Array = []).length = 5;">
<option ng-repeat="i in _Array track by $index">{{$index+5}}</option>
</select>
Without any change in your controller, you can use this:
ng-repeat="_ in ((_ = []) && (_.length=51) && _) track by $index"
Enjoy!
Method definition
The code below defines a method range() available to the entire scope of your application MyApp. Its behaviour is very similar to the Python range() method.
angular.module('MyApp').run(['$rootScope', function($rootScope) {
$rootScope.range = function(min, max, step) {
// parameters validation for method overloading
if (max == undefined) {
max = min;
min = 0;
}
step = Math.abs(step) || 1;
if (min > max) {
step = -step;
}
// building the array
var output = [];
for (var value=min; value<max; value+=step) {
output.push(value);
}
// returning the generated array
return output;
};
}]);
Usage
With one parameter:
<span ng-repeat="i in range(3)">{{ i }}, </span>
0, 1, 2,
With two parameters:
<span ng-repeat="i in range(1, 5)">{{ i }}, </span>
1, 2, 3, 4,
With three parameters:
<span ng-repeat="i in range(-2, .7, .5)">{{ i }}, </span>
-2, -1.5, -1, -0.5, 0, 0.5,
You can use 'after' or 'before' filters in angular.filter module (https://github.com/a8m/angular-filter)
$scope.list = [1,2,3,4,5,6,7,8,9,10]
HTML:
<li ng-repeat="i in list | after:4">
{{ i }}
</li>
result:
5, 6, 7, 8, 9, 10
Shortest answer: 2 lines of code
JS (in your AngularJS controller)
$scope.range = new Array(MAX_REPEATS); // MAX_REPEATS should be the most repetitions you will ever need in a single ng-repeat
HTML
<div data-ng-repeat="i in range.slice(0,myCount) track by $index"></div>
...where myCount is the number of stars that should appear in this location.
You can use $index for any tracking operations. E.g. if you want to print some mutation on the index, you might put the following in the div:
{{ ($index + 1) * 0.5 }}
Hi you can achieve this using pure html using AngularJS (NO Directive is required!)
<div ng-app="myapp" ng-controller="YourCtrl" ng-init="x=[5];">
<div ng-if="i>0" ng-repeat="i in x">
<!-- this content will repeat for 5 times. -->
<table class="table table-striped">
<tr ng-repeat="person in people">
<td>{{ person.first + ' ' + person.last }}</td>
</tr>
</table>
<p ng-init="x.push(i-1)"></p>
</div>
</div>
Using UnderscoreJS:
angular.module('myModule')
.run(['$rootScope', function($rootScope) { $rootScope.range = _.range; }]);
Applying this to $rootScope makes it available everywhere:
<div ng-repeat="x in range(1,10)">
{{x}}
</div>
Very simple one:
$scope.totalPages = new Array(10);
<div id="pagination">
<a ng-repeat="i in totalPages track by $index">
{{$index+1}}
</a>
</div>
Set Scope in controller
var range = [];
for(var i=20;i<=70;i++) {
range.push(i);
}
$scope.driverAges = range;
Set Repeat in Html Template File
<select type="text" class="form-control" name="driver_age" id="driver_age">
<option ng-repeat="age in driverAges" value="{{age}}">{{age}}</option>
</select>
An improvement to #Mormegil's solution
app.filter('makeRange', function() {
return function(inp) {
var range = [+inp[1] && +inp[0] || 0, +inp[1] || +inp[0]];
var min = Math.min(range[0], range[1]);
var max = Math.max(range[0], range[1]);
var result = [];
for (var i = min; i <= max; i++) result.push(i);
if (range[0] > range[1]) result.reverse();
return result;
};
});
usage
<span ng-repeat="n in [3, -3] | makeRange" ng-bind="n"></span>
3 2 1 0 -1 -2 -3
<span ng-repeat="n in [-3, 3] | makeRange" ng-bind="n"></span>
-3 -2 -1 0 1 2 3
<span ng-repeat="n in [3] | makeRange" ng-bind="n"></span>
0 1 2 3
<span ng-repeat="n in [-3] | makeRange" ng-bind="n"></span>
0 -1 -2 -3
I tried the following and it worked just fine for me:
<md-radio-button ng-repeat="position in formInput.arrayOfChoices.slice(0,6)" value="{{position}}">{{position}}</md-radio-button>
Angular 1.3.6
Late to the party. But i ended up just doing this:
In your controller:
$scope.repeater = function (range) {
var arr = [];
for (var i = 0; i < range; i++) {
arr.push(i);
}
return arr;
}
Html:
<select ng-model="myRange">
<option>3</option>
<option>5</option>
</select>
<div ng-repeat="i in repeater(myRange)"></div>
This is jzm's improved answer (i cannot comment else i would comment her/his answer because s/he included errors).
The function has a start/end range value, so it's more flexible, and... it works. This particular case is for day of month:
$scope.rangeCreator = function (minVal, maxVal) {
var arr = [];
for (var i = minVal; i <= maxVal; i++) {
arr.push(i);
}
return arr;
};
<div class="col-sm-1">
<select ng-model="monthDays">
<option ng-repeat="day in rangeCreator(1,31)">{{day}}</option>
</select>
</div>
<div ng-init="avatars = [{id : 0}]; flag = true ">
<div ng-repeat='data in avatars' ng-if="avatars.length < 10 || flag"
ng-init="avatars.length != 10 ? avatars.push({id : $index+1}) : ''; flag = avatars.length <= 10 ? true : false">
<img ng-src="http://actual-names.com/wp-content/uploads/2016/01/sanskrit-baby-girl-names-400x275.jpg">
</div>
</div>
If you want to achieve this in html without any controller or factory.
I whipped this up and saw it might be useful for some. (Yes, CoffeeScript. Sue me.)
Directive
app.directive 'times', ->
link: (scope, element, attrs) ->
repeater = element.html()
scope.$watch attrs.times, (value) ->
element.html ''
return unless value?
element.html Array(value + 1).join(repeater)
To use:
HTML
<div times="customer.conversations_count">
<i class="icon-picture></i>
</div>
Can this get any simpler?
I'm wary about filters because Angular likes to re-evaluate them for no good reason all the time, and it's a huge bottleneck if you have thousands of them like I do.
This directive will even watch for changes in your model, and update the element accordingly.
Suppose $scope.refernceurl is an array then
for(var i=0; i<$scope.refernceurl.length; i++){
$scope.urls+=$scope.refernceurl[i].link+",";
}
This is the simplest variant:
just use array of integers....
<li ng-repeat="n in [1,2,3,4,5]">test {{n}}</li>

Check-all checkbox is not changes object properties from select

My Code - Plunker
I'm trying to changes status of all my list objects by using a master checkbox that
checks all objects and changes their properties by selecting the required status from the
select element.
The problem is that when I'm trying to apply change on all elements by using the "Check All" 'checkbox' it is not working.
e.g.
When I check manually all the checkboxes without using the master checkbox it is working.
My Code
var webApp = angular.module('webApp', []);
//controllers
webApp.controller ('VotesCtrl', function ($scope, Votes) {
$scope.votes = Votes;
$scope.statuses = ["Approved","Pending","Trash","Spam"];
$scope.expand = function(vote) {
console.log("show");
$scope.vote = vote;
$scope.ip = vote.ip;
$scope.date = vote.created;
};
$scope.change = function() {
for(var i = 0; i < $scope.votes.length; i++) {
if($scope.votes[i].cb) {
$scope.votes[i].status = $scope.votes.status;
$scope.votes[i].cb = false;
}
$scope.show = false;
}
};
});
//services
webApp.factory('Votes', [function() {
//temporary repository till integration with DB this will be translated into restful get query
var votes = [
{
id: '1',
created: 1381583344653,
updated: '222212',
ratingID: '3',
rate: 5,
ip: '198.168.0.0',
status: 'Pending',
},
{
id: '111',
created: 1381583344653,
updated: '222212',
ratingID: '4',
rate: 5,
ip: '198.168.0.1',
status: 'Spam'
},
{
id: '2',
created: 1382387322693,
updated: '222212',
ratingID: '3',
rate: 1,
ip: '198.168.0.2',
status: 'Approved'
},
{
id: '4',
created: 1382387322693,
updated: '222212',
ratingID: '3',
rate: 1,
ip: '198.168.0.3',
status: 'Spam'
}
];
return votes;
}]);
My HTML
<body ng-controller='VotesCtrl'>
<div>
<ul>
<li class="check" ng-click=>
<input type="checkbox" ng-model="master"></input>
</li>
<li class="created">
<a>CREATED</a>
</li>
<li class="ip">
<b>IP ADDRESS</b>
</li>
<li class="status">
<b>STATUS</b>
</li>
</ul>
<ul ng-repeat="vote in votes">
<li class="check">
<input type="checkbox" ng-model="vote.cb" ng-checked="master"></input>
</li>
<li class="created">
{{vote.created|date}}
</li>
<li class="ip">
{{vote.ip}}
</li>
<li class="status">
{{vote.status}}
</li>
</ul>
</div>
<br></br>
<div class="details">
<h3>Details:</h3>
<div>DATE: {{date|date}}</div>
<div>IP: {{ip}}</div>
<div>STATUS:
<select ng-change="change()" ng-init="votes.status='Approved'"
ng-model="votes.status"
ng-options="status for status in statuses">
</select>
<p>{{vote.status|json}}</p>
</div>
</div>
</body>
Why is master checkbox not working?
I changed your method change a bit to make it work.
From Plunker you can see that on master change all children still have old value. So I added onMasterChange method
HTML
<input type="checkbox"
ng-model="master"
ng-change="onMasterChange(master)"></input>
I created as default: $scope.master = false;
....
$scope.master = false;
$scope.onMasterChange = function(master){
for(var i = 0; i < $scope.votes.length; i++) {
$scope.votes[i].cb = master;
}
};
$scope.change = function(value) {
for(var i = 0; i < $scope.votes.length; i++) {
//if($scope.votes[i].cb == undefined){
// $scope.votes[i].cb = false;
// }
if($scope.master == true){
$scope.votes[i].cb = $scope.master;
$scope.votes[i].status = value;
}
else if( $scope.votes[i].cb == true) {
$scope.votes[i].status = value;
}
}
};
See Plunker
Hope it will help,
It is working, but I believe ng-model is taking precedence over ng-checked. If you remove ng-model from the checkboxes, ng-checked is working as expected.
<input type="checkbox" ng-checked="master"></input>
http://plnkr.co/edit/q35JlhOVSGxmu6QW8e98?p=preview
It is important to note, however, that ng-checked does not update your model, it only changes the presentation of the checkbox. A way of tackling this would be to remove the master binding, and call a method with ng-click on your master checkbox which changes .cb on each box.
Edit: Working version using a watch on the master checkbox.
http://plnkr.co/edit/3NwGtp1FX8g9bfMrbWU5?p=preview

angularjs execute expression from variable

How to execute expression from variable?
I need something like formula which depends from another inputs.
For example my data:
$scope.items = [{
name: 'first',
formula: '',
value: 1,
type: 'text',
},{
name: 'second',
formula: '',
value: 2,
type: 'text',
},{
name: 'third',
formula: '{first}+{second}',
type: 'formula',
}];
and my view:
<ul>
<li ng-repeat="item in items">
<div ng-switch on="item.type">
<div ng-switch-when="text">
<input type="text" ng-model="item.value" name="{{item.name}}">
</div>
<div ng-switch-when="formula">
<span>{{item.formula}}</span>
</div>
</div>
</li>
I want that the result was 3
But it's {first}+{second} ofcourse
<div ng-switch-when="formula">
<span>
{{getFormulaResult(item.formula)}}
</span>
</div>
Controller method:
$scope.getFormulaResult = function(formula){
var formulaSplits = formula.split("+");
var left = formulaSplits[0];
left = left.substr(1);
left = left.substring(0, left.length-1);
var right = formulaSplits[1];
right = right.substr(1);
right = right.substring(0, right.length-1);
var sum = 0;
for(var i = 0; i < $scope.items.length; i++){
if($scope.items[i].name == left || $scope.items[i].name == right){
sum = sum + parseInt($scope.items[i].value, 10);
}
}
return sum || 0;
}

AngularJS For Loop with Numbers & Ranges

Angular does provide some support for a for loop using numbers within its HTML directives:
<div data-ng-repeat="i in [1,2,3,4,5]">
do something
</div>
But if your scope variable includes a range that has a dynamic number then you will need to create an empty array each time.
In the controller
var range = [];
for(var i=0;i<total;i++) {
range.push(i);
}
$scope.range = range;
In the HTML
<div data-ng-repeat="i in range">
do something
</div>
This works, but it is unnecessary since we won't be using the range array at all within the loop. Does anyone know of setting a range or a regular for min/max value?
Something like:
<div data-ng-repeat="i in 1 .. 100">
do something
</div>
I tweaked this answer a bit and came up with this fiddle.
Filter defined as:
var myApp = angular.module('myApp', []);
myApp.filter('range', function() {
return function(input, total) {
total = parseInt(total);
for (var i=0; i<total; i++) {
input.push(i);
}
return input;
};
});
With the repeat used like this:
<div ng-repeat="n in [] | range:100">
do something
</div>
I came up with an even simpler version, for creating a range between two defined numbers, eg. 5 to 15
See demo on JSFiddle
HTML:
<ul>
<li ng-repeat="n in range(5,15)">Number {{n}}</li>
</ul>
Controller:
$scope.range = function(min, max, step) {
step = step || 1;
var input = [];
for (var i = min; i <= max; i += step) {
input.push(i);
}
return input;
};
Nothing but plain Javascript (you don't even need a controller):
<div ng-repeat="n in [].constructor(10) track by $index">
{{ $index }}
</div>
Very useful when mockuping
I came up with a slightly different syntax which suits me a little bit more and adds an optional lower bound as well:
myApp.filter('makeRange', function() {
return function(input) {
var lowBound, highBound;
switch (input.length) {
case 1:
lowBound = 0;
highBound = parseInt(input[0]) - 1;
break;
case 2:
lowBound = parseInt(input[0]);
highBound = parseInt(input[1]);
break;
default:
return input;
}
var result = [];
for (var i = lowBound; i <= highBound; i++)
result.push(i);
return result;
};
});
which you can use as
<div ng-repeat="n in [10] | makeRange">Do something 0..9: {{n}}</div>
or
<div ng-repeat="n in [20, 29] | makeRange">Do something 20..29: {{n}}</div>
For those new to angularjs.
The index can be gotten by using $index.
For example:
<div ng-repeat="n in [] | range:10">
do something number {{$index}}
</div>
Which will, when you're using Gloopy's handy filter, print:
do something number 0
do something number 1
do something number 2
do something number 3
do something number 4
do something number 5
do something number 6
do something number 7
do something number 8
do something number 9
A short way of doing this would be to use Underscore.js's _.range() method. :)
http://underscorejs.org/#range
// declare in your controller or wrap _.range in a function that returns a dynamic range.
var range = _.range(1, 11);
// val will be each number in the array not the index.
<div ng-repeat='val in range'>
{{ $index }}: {{ val }}
</div>
I use my custom ng-repeat-range directive:
/**
* Ng-Repeat implementation working with number ranges.
*
* #author Umed Khudoiberdiev
*/
angular.module('commonsMain').directive('ngRepeatRange', ['$compile', function ($compile) {
return {
replace: true,
scope: { from: '=', to: '=', step: '=' },
link: function (scope, element, attrs) {
// returns an array with the range of numbers
// you can use _.range instead if you use underscore
function range(from, to, step) {
var array = [];
while (from + step <= to)
array[array.length] = from += step;
return array;
}
// prepare range options
var from = scope.from || 0;
var step = scope.step || 1;
var to = scope.to || attrs.ngRepeatRange;
// get range of numbers, convert to the string and add ng-repeat
var rangeString = range(from, to + 1, step).join(',');
angular.element(element).attr('ng-repeat', 'n in [' + rangeString + ']');
angular.element(element).removeAttr('ng-repeat-range');
$compile(element)(scope);
}
};
}]);
and html code is
<div ng-repeat-range from="0" to="20" step="5">
Hello 4 times!
</div>
or simply
<div ng-repeat-range from="5" to="10">
Hello 5 times!
</div>
or even simply
<div ng-repeat-range to="3">
Hello 3 times!
</div>
or just
<div ng-repeat-range="7">
Hello 7 times!
</div>
Simplest no code solution was to init an array with the range, and use the $index + however much I want to offset by:
<select ng-init="(_Array = []).length = 5;">
<option ng-repeat="i in _Array track by $index">{{$index+5}}</option>
</select>
Without any change in your controller, you can use this:
ng-repeat="_ in ((_ = []) && (_.length=51) && _) track by $index"
Enjoy!
Method definition
The code below defines a method range() available to the entire scope of your application MyApp. Its behaviour is very similar to the Python range() method.
angular.module('MyApp').run(['$rootScope', function($rootScope) {
$rootScope.range = function(min, max, step) {
// parameters validation for method overloading
if (max == undefined) {
max = min;
min = 0;
}
step = Math.abs(step) || 1;
if (min > max) {
step = -step;
}
// building the array
var output = [];
for (var value=min; value<max; value+=step) {
output.push(value);
}
// returning the generated array
return output;
};
}]);
Usage
With one parameter:
<span ng-repeat="i in range(3)">{{ i }}, </span>
0, 1, 2,
With two parameters:
<span ng-repeat="i in range(1, 5)">{{ i }}, </span>
1, 2, 3, 4,
With three parameters:
<span ng-repeat="i in range(-2, .7, .5)">{{ i }}, </span>
-2, -1.5, -1, -0.5, 0, 0.5,
You can use 'after' or 'before' filters in angular.filter module (https://github.com/a8m/angular-filter)
$scope.list = [1,2,3,4,5,6,7,8,9,10]
HTML:
<li ng-repeat="i in list | after:4">
{{ i }}
</li>
result:
5, 6, 7, 8, 9, 10
Shortest answer: 2 lines of code
JS (in your AngularJS controller)
$scope.range = new Array(MAX_REPEATS); // MAX_REPEATS should be the most repetitions you will ever need in a single ng-repeat
HTML
<div data-ng-repeat="i in range.slice(0,myCount) track by $index"></div>
...where myCount is the number of stars that should appear in this location.
You can use $index for any tracking operations. E.g. if you want to print some mutation on the index, you might put the following in the div:
{{ ($index + 1) * 0.5 }}
Hi you can achieve this using pure html using AngularJS (NO Directive is required!)
<div ng-app="myapp" ng-controller="YourCtrl" ng-init="x=[5];">
<div ng-if="i>0" ng-repeat="i in x">
<!-- this content will repeat for 5 times. -->
<table class="table table-striped">
<tr ng-repeat="person in people">
<td>{{ person.first + ' ' + person.last }}</td>
</tr>
</table>
<p ng-init="x.push(i-1)"></p>
</div>
</div>
Using UnderscoreJS:
angular.module('myModule')
.run(['$rootScope', function($rootScope) { $rootScope.range = _.range; }]);
Applying this to $rootScope makes it available everywhere:
<div ng-repeat="x in range(1,10)">
{{x}}
</div>
Very simple one:
$scope.totalPages = new Array(10);
<div id="pagination">
<a ng-repeat="i in totalPages track by $index">
{{$index+1}}
</a>
</div>
Set Scope in controller
var range = [];
for(var i=20;i<=70;i++) {
range.push(i);
}
$scope.driverAges = range;
Set Repeat in Html Template File
<select type="text" class="form-control" name="driver_age" id="driver_age">
<option ng-repeat="age in driverAges" value="{{age}}">{{age}}</option>
</select>
An improvement to #Mormegil's solution
app.filter('makeRange', function() {
return function(inp) {
var range = [+inp[1] && +inp[0] || 0, +inp[1] || +inp[0]];
var min = Math.min(range[0], range[1]);
var max = Math.max(range[0], range[1]);
var result = [];
for (var i = min; i <= max; i++) result.push(i);
if (range[0] > range[1]) result.reverse();
return result;
};
});
usage
<span ng-repeat="n in [3, -3] | makeRange" ng-bind="n"></span>
3 2 1 0 -1 -2 -3
<span ng-repeat="n in [-3, 3] | makeRange" ng-bind="n"></span>
-3 -2 -1 0 1 2 3
<span ng-repeat="n in [3] | makeRange" ng-bind="n"></span>
0 1 2 3
<span ng-repeat="n in [-3] | makeRange" ng-bind="n"></span>
0 -1 -2 -3
I tried the following and it worked just fine for me:
<md-radio-button ng-repeat="position in formInput.arrayOfChoices.slice(0,6)" value="{{position}}">{{position}}</md-radio-button>
Angular 1.3.6
Late to the party. But i ended up just doing this:
In your controller:
$scope.repeater = function (range) {
var arr = [];
for (var i = 0; i < range; i++) {
arr.push(i);
}
return arr;
}
Html:
<select ng-model="myRange">
<option>3</option>
<option>5</option>
</select>
<div ng-repeat="i in repeater(myRange)"></div>
This is jzm's improved answer (i cannot comment else i would comment her/his answer because s/he included errors).
The function has a start/end range value, so it's more flexible, and... it works. This particular case is for day of month:
$scope.rangeCreator = function (minVal, maxVal) {
var arr = [];
for (var i = minVal; i <= maxVal; i++) {
arr.push(i);
}
return arr;
};
<div class="col-sm-1">
<select ng-model="monthDays">
<option ng-repeat="day in rangeCreator(1,31)">{{day}}</option>
</select>
</div>
<div ng-init="avatars = [{id : 0}]; flag = true ">
<div ng-repeat='data in avatars' ng-if="avatars.length < 10 || flag"
ng-init="avatars.length != 10 ? avatars.push({id : $index+1}) : ''; flag = avatars.length <= 10 ? true : false">
<img ng-src="http://actual-names.com/wp-content/uploads/2016/01/sanskrit-baby-girl-names-400x275.jpg">
</div>
</div>
If you want to achieve this in html without any controller or factory.
I whipped this up and saw it might be useful for some. (Yes, CoffeeScript. Sue me.)
Directive
app.directive 'times', ->
link: (scope, element, attrs) ->
repeater = element.html()
scope.$watch attrs.times, (value) ->
element.html ''
return unless value?
element.html Array(value + 1).join(repeater)
To use:
HTML
<div times="customer.conversations_count">
<i class="icon-picture></i>
</div>
Can this get any simpler?
I'm wary about filters because Angular likes to re-evaluate them for no good reason all the time, and it's a huge bottleneck if you have thousands of them like I do.
This directive will even watch for changes in your model, and update the element accordingly.
Suppose $scope.refernceurl is an array then
for(var i=0; i<$scope.refernceurl.length; i++){
$scope.urls+=$scope.refernceurl[i].link+",";
}
This is the simplest variant:
just use array of integers....
<li ng-repeat="n in [1,2,3,4,5]">test {{n}}</li>

Resources