I have the following code, I want to add 1 to the current index of the second Name, because if I don't, it will output the same name in a single line. How do I add to the current index of ngRepeat?
<ul id="speakerlist" ng-repeat="data in result">
<li>
<div class="col">
<h3>{{data.Name}}</h3>
</div >
<div class="col">
<h3>{{data.Name | $index+1}}</h3>
</div>
</li>
</ul>
I solved this by using jQuery, but I want to do it in angularjs way.
EDIT: additional info
var app=angular.module("myApp",[])
app.controller("myController",function($scope){
$scope.result=[{"Name":"Michael Jordan"},{"Name":"Kobe Bryant"},{"Name":"Kevin Durant"},{"Name":"Stephen Curry"} ];
});
The result I want Is:
Michael Jordan Kobe Bryant
Kevin Durant Stephen Curry
If I understand correctly, you want to display a li for every two items. You can do it something like this:
<ul id="speakerlist" ng-repeat="data in result">
<li ng-if="$even">
<div class="col">
<h3>{{result[$index].Name}}</h3>
</div >
<div class="col">
<h3>{{result[$index + 1].Name}}</h3>
</div>
</li>
</ul>
Of course you would also have to include some kind of check if the $index can reach the last one (if the collection has an un-even amount of items)
See this jsfiddle
You could even remove the double col html if you don't like duplicate html code:
<ul id="speakerlist" ng-repeat="data in result">
<li ng-if="$even">
<div class="col"
ng-repeat="item in [result[$index], result[$index + 1]]">
<h3>{{item.Name}}</h3>
</div >
</li>
</ul>
Try this code <h3>{{data.Name }} {{$index+1}}</h3> instead of your code
<h3>{{data.Name | $index+1}}</h3>
The result format looks like
Ramesh
Ramesh1
Rajendran
Rajendran1
I think you can make it simple this way.
var app=angular.module("myApp",[])
app.controller("myController",function($scope){
$scope.result=[{"Name":"hari"},{"Name":"ram"} ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myController">
<ul id="speakerlist" ng-repeat="data in result track by $index">
<li>
<div class="col">
<h3 >{{data.Name}} {{data.Name+1 }}</h3>
</div >
</li>
</ul>
</body>
">
Why don't you do this ?
<ul id="speakerlist" >
<li ng-repeat="data in result">
<div class="col">
<h3>{{data.Name}}</h3>
</div >
</li>
</ul>
This way you don't need to change de $index, it will be automatic
AngularJS
How can i get first element and add class 'active' automatically .
There is 2 ng-repeat , I want get first group --> first item --> first element and add class.
<div class="first" ng-repeat="group in group ">
<div class="second" ng-repeat="item in items">
<div ng-class="{'active': selectedGame.id === prematchGame.id}"></div>
</div>
</div>
You can do like this:
<div ng-class='{active:$first}' > {{item.data}}</div>
If you want to make active only the first element of the first ng-repeat, then try:
<div class="first" ng-repeat="group in groups">
<div class="second" ng-repeat="item in items">
<div ng-class='{active: $first && $parent.$first}'>{{item.data}}</div>
</div>
</div>
Demo on JSFiddle
simple way if all you want is first element
<div class="first" ng-repeat="group in group">
<div class="second" ng-repeat="item in items">
<div ng-class="{'active': $index == 1}" ></div>
</div>
</div>
you can do same for other ng-repeat all will have different $index
Use $first to do check for the first element of ng-repeat : Fiddle
<div class="first" ng-repeat="group in group" ng-init="firstGroup = $first">
<div class="second" ng-repeat="item in items">
<div ng-class="{'active': selectedGame.id === prematchGame.id}" ng-class='{active: $first && firstGroup}'></div>
</div>
</div>
How to increment init variable value in ng-repeat
<div ng-if="feedData.carouselMode == true" ng-init='start=0' ng-repeat="a in carousel_data">
<div class="owl-demo" class="owl-carousel" owl-carousel >
<div class="item" ng-repeat="(key, item) in a.carouselFeeds" ng-init="start=start+1">
{{start}}
<div ng-click="go('{{key}}', item.feedUrls.length, 'rtl')" ng-swipe-left="go('{{key}}', item.feedUrls.length, 'rtl')">
<img class="lazyOwl" ng-src="{{item.img}}" />
<span class="innersquare" image-ja="{{item.img}}">
<p ng-style="folderStyle">{{item.name }} </p> </span>
</div>
</div>
</div>
</div>
ng-init start=0 after increment start=start+1 in ng-repeat but no count only show 1.
This is because each ng-repeat has its own scope and each ng-init will just increase its own scoped variable. You can try access the parent scope with $parent.
In case you are looking for a continuous numeration try this
<div ng-controller="MyCtrl">
<div ng-repeat="a in ['a','b','c']" ng-init="current = $parent.start; $parent.start=$parent.start+3;">
<div ng-repeat="x in ['alpha','beta','gamma']">
{{current + $index}}
</div>
</div>
Where the +3 should be +[LENGTH OF INNER ARRAY].
http://jsfiddle.net/rvgvs2jt/2/
For your specific code it would look like this
<div ng-if="feedData.carouselMode == true" ng-init='current=$parent.start; $parent.start=$parent.start+a.carouselFeeds.length' ng-repeat="a in carousel_data">
<div class="owl-demo" class="owl-carousel" owl-carousel>
<div class="item" ng-repeat="(key, item) in a.carouselFeeds">
{{current + $index}}
<div ng-click="go('{{key}}', item.feedUrls.length, 'rtl')" ng-swipe-left="go('{{key}}', item.feedUrls.length, 'rtl')">
<img class="lazyOwl" ng-src="{{item.img}}" />
<span class="innersquare" image-ja="{{item.img}}">
<p ng-style="folderStyle">{{item.name }} </p> </span>
</div>
</div>
</div>
</div>
I guess you achieve this by simple {{$parent.$index}}
Update
As per comments
<div ng-controller="MyCtrl">
<div ng-repeat="a in one">
<div ng-repeat="x in two">
{{($parent.$index*two.length)+($index+1)}}
</div>
</div>
Controller:-
$scope.one= ['alpha','beta','gamma'] ;
$scope.two=['alpha','beta','gamma'];
Fiddle
You can be accessed with $index, check this code,
<div ng-app ng-controller="TestController">
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item.value" type="text"/>
</div>
{{list}}
</div>
and
function TestController($scope) {
$scope.list = [ { value: 'value 1' }, { value: 'value 2' }, { value: 'value 3' } ];
}
AngularJS is giving $index variable. We can use it.
<ul>
<li ng-repeat="item in items">{{ $index + 1 }}</li>
</ul>
I'm looking for the right pattern to inject a bootstrap row class every each 3 columns. I need this because cols doesn't have a fixed hight (and I don't want to fix one), so it breaks my design !
Here is my code :
<div ng-repeat="product in products">
<div ng-if="$index % 3 == 0" class="row">
<div class="col-sm-4" >
...
</div>
</div>
</div>
But it does only display one product in each row. What I want as final result is :
<div class="row">
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
</div>
<div class="row">
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
</div>
Can I achieve this with only ng-repeat pattern (without directive or controller) ? The docs introduce ng-repeat-start and ng-repeat-end but I can't figure out how to use it is this use case ! I feel like this is something we often use in bootstrap templating ! ? Thanks
The top voted answer, while effective, is not what I would consider to be the angular way, nor is it using bootstrap's own classes that are meant to deal with this situation. As #claies mentioned, the .clearfix class is meant for situations such as these. In my opinion, the cleanest implementation is as follows:
<div class="row">
<div ng-repeat="product in products">
<div class="clearfix" ng-if="$index % 3 == 0"></div>
<div class="col-sm-4">
<h2>{{product.title}}</h2>
</div>
</div>
</div>
This structure avoids messy indexing of the products array, allows for clean dot notation, and makes use of the clearfix class for its intended purpose.
I know it's a bit late but it still might help someone. I did it like this:
<div ng-repeat="product in products" ng-if="$index % 3 == 0" class="row">
<div class="col-xs-4">{{products[$index]}}</div>
<div class="col-xs-4" ng-if="products.length > ($index + 1)">{{products[$index + 1]}}</div>
<div class="col-xs-4" ng-if="products.length > ($index + 2)">{{products[$index + 2]}}</div>
</div>
jsfiddle
Okay, this solution is far simpler than the ones already here, and allows different column widths for different device widths.
<div class="row">
<div ng-repeat="image in images">
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">
... your content here ...
</div>
<div class="clearfix visible-lg" ng-if="($index + 1) % 6 == 0"></div>
<div class="clearfix visible-md" ng-if="($index + 1) % 4 == 0"></div>
<div class="clearfix visible-sm" ng-if="($index + 1) % 3 == 0"></div>
<div class="clearfix visible-xs" ng-if="($index + 1) % 2 == 0"></div>
</div>
</div>
Note that the % 6 part is supposed to equal the number of resulting columns. So if on the column element you have the class col-lg-2 there will be 6 columns, so use ... % 6.
This technique (excluding the ng-if) is actually documented here: Bootstrap docs
While what you want to accomplish may be useful, there is another option which I believe you might be overlooking that is much more simple.
You are correct, the Bootstrap tables act strangely when you have columns which are not fixed height. However, there is a bootstrap class created to combat this issue and perform responsive resets.
simply create an empty <div class="clearfix"></div> before the start of each new row to allow the floats to reset and the columns to return to their correct positions.
here is a bootply.
Thanks for your suggestions, you got me on the right way !
Let's go for a complete explanation :
By default AngularJS http get query returns an object
So if you want to use #Ariel Array.prototype.chunk function you have first to transform object into an array.
And then to use the chunk function IN YOUR CONTROLLER otherwise if used directly into ng-repeat, it will brings you to an infdig error. The final controller looks :
// Initialize products to empty list
$scope.products = [];
// Load products from config file
$resource("/json/shoppinglist.json").get(function (data_object)
{
// Transform object into array
var data_array =[];
for( var i in data_object ) {
if (typeof data_object[i] === 'object' && data_object[i].hasOwnProperty("name")){
data_array.push(data_object[i]);
}
}
// Chunk Array and apply scope
$scope.products = data_array.chunk(3);
});
And HTML becomes :
<div class="row" ng-repeat="productrow in products">
<div class="col-sm-4" ng-repeat="product in productrow">
On the other side, I decided to directly return an array [] instead of an object {} from my JSON file. This way, controller becomes (please note specific syntax isArray:true) :
// Initialize products to empty list
$scope.products = [];
// Load products from config file
$resource("/json/shoppinglist.json").query({method:'GET', isArray:true}, function (data_array)
{
$scope.products = data_array.chunk(3);
});
HTML stay the same as above.
OPTIMIZATION
Last question in suspense is : how to make it 100% AngularJS without extending javascript array with chunk function ... if some people are interested in showing us if ng-repeat-start and ng-repeat-end are the way to go ... I'm curious ;)
ANDREW'S SOLUTION
Thanks to #Andrew, we now know adding a bootstrap clearfix class every three (or whatever number) element corrects display problem from differents block's height.
So HTML becomes :
<div class="row">
<div ng-repeat="product in products">
<div ng-if="$index % 3 == 0" class="clearfix"></div>
<div class="col-sm-4"> My product descrition with {{product.property}}
And your controller stays quite soft with removed chunck function :
// Initialize products to empty list
$scope.products = [];
// Load products from config file
$resource("/json/shoppinglist.json").query({method:'GET', isArray:true}, function (data_array)
{
//$scope.products = data_array.chunk(3);
$scope.products = data_array;
});
You can do it without a directive but i'm not sure it's the best way.
To do this you must create array of array from the data you want to display in the table,
and after that use 2 ng-repeat to iterate through the array.
to create the array for display use this function like that products.chunk(3)
Array.prototype.chunk = function(chunkSize) {
var array=this;
return [].concat.apply([],
array.map(function(elem,i) {
return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
})
);
}
and then do something like that using 2 ng-repeat
<div class="row" ng-repeat="row in products.chunk(3)">
<div class="col-sm4" ng-repeat="item in row">
{{item}}
</div>
</div>
Based on Alpar solution, using only templates with anidated ng-repeat. Works with both full and partially empty rows:
<div data-ng-app="" data-ng-init="products='soda','beer','water','milk','wine']" class="container">
<div ng-repeat="product in products" ng-if="$index % 3 == 0" class="row">
<div class="col-xs-4"
ng-repeat="product in products.slice($index, ($index+3 > products.length ?
products.length : $index+3))"> {{product}}</div>
</div>
</div>
JSFiddle
I've just made a solution of it working only in template.
The solution is
<span ng-repeat="gettingParentIndex in products">
<div class="row" ng-if="$index<products.length/2+1"> <!-- 2 columns -->
<span ng-repeat="product in products">
<div class="col-sm-6" ng-if="$index>=2*$parent.$index && $index <= 2*($parent.$index+1)-1"> <!-- 2 columns -->
{{product.foo}}
</div>
</span>
</div>
</span>
Point is using data twice, one is for an outside loop.
Extra span tags will remain, but it depends on how you trade off.
If it's a 3 column layout, it's going to be like
<span ng-repeat="gettingParentIndex in products">
<div class="row" ng-if="$index<products.length/3+1"> <!-- 3 columns -->
<span ng-repeat="product in products">
<div class="col-sm-4" ng-if="$index>=3*$parent.$index && $index <= 3*($parent.$index+1)-1"> <!-- 3 columns -->
{{product.foo}}
</div>
</span>
</div>
</span>
Honestly I wanted
$index<Math.ceil(products.length/3)
Although it didn't work.
Just another little improvement about #Duncan answer and the others answers based on clearfix element.
If you want to make the content clickable you will need a z-index > 0 on it or clearfix will overlap the content and handle the click.
This is the example not working (you can't see the cursor pointer and clicking will do nothing):
<div class="row">
<div ng-repeat="product in products">
<div class="clearfix" ng-if="$index % 3 == 0"></div>
<div class="col-sm-4" style="cursor: pointer" ng-click="doSomething()">
<h2>{{product.title}}</h2>
</div>
</div>
</div>
While this is the fixed one:
<div class="row">
<div ng-repeat-start="product in products" class="clearfix" ng-if="$index % 3 == 0"></div>
<div ng-repeat-end class="col-sm-4" style="cursor: pointer; z-index: 1" ng-click="doSomething()">
<h2>{{product.title}}</h2>
</div>
</div>
I've added z-index: 1 to have the content raise over the clearfix and I've removed the container div using instead ng-repeat-start and ng-repeat-end (available from AngularJS 1.2) because it made z-index not working.
Hope this helps!
Update
Plunker: http://plnkr.co/edit/4w5wZj
i solved this using ng-class
<div ng-repeat="item in items">
<div ng-class="{ 'row': ($index + 1) % 4 == 0 }">
<div class="col-md-3">
{{item.name}}
</div>
</div>
</div>
The best way to apply a class is to use ng-class.It can be used to apply classes based on some condition.
<div ng-repeat="product in products">
<div ng-class="getRowClass($index)">
<div class="col-sm-4" >
<!-- your code -->
</div>
</div>
and then in your controller
$scope.getRowClass = function(index){
if(index%3 == 0){
return "row";
}
}
After combining many answers and suggestion here, this is my final answer, which works well with flex, which allows us to make columns with equal height, it also checks the last index, and you don't need to repeat the inner HTML. It doesn't use clearfix:
<div ng-repeat="prod in productsFiltered=(products | filter:myInputFilter)" ng-if="$index % 3 == 0" class="row row-eq-height">
<div ng-repeat="i in [0, 1, 2]" ng-init="product = productsFiltered[$parent.$parent.$index + i]" ng-if="$parent.$index + i < productsFiltered.length" class="col-xs-4">
<div class="col-xs-12">{{ product.name }}</div>
</div>
</div>
It will output something like this:
<div class="row row-eq-height">
<div class="col-xs-4">
<div class="col-xs-12">
Product Name
</div>
</div>
<div class="col-xs-4">
<div class="col-xs-12">
Product Name
</div>
</div>
<div class="col-xs-4">
<div class="col-xs-12">
Product Name
</div>
</div>
</div>
<div class="row row-eq-height">
<div class="col-xs-4">
<div class="col-xs-12">
Product Name
</div>
</div>
<div class="col-xs-4">
<div class="col-xs-12">
Product Name
</div>
</div>
<div class="col-xs-4">
<div class="col-xs-12">
Product Name
</div>
</div>
</div>
Little bit modification in #alpar 's solution
<div data-ng-app="" data-ng-init="products=['A','B','C','D','E','F', 'G','H','I','J','K','L']" class="container">
<div ng-repeat="product in products" ng-if="$index % 6 == 0" class="row">
<div class="col-xs-2" ng-repeat="idx in [0,1,2,3,4,5]">
{{products[idx+$parent.$index]}} <!-- When this HTML is Big it's useful approach -->
</div>
</div>
</div>
jsfiddle
This worked for me, no splicing or anything required:
HTML
<div class="row" ng-repeat="row in rows() track by $index">
<div class="col-md-3" ng-repeat="item in items" ng-if="indexInRange($index,$parent.$index)"></div>
</div>
JavaScript
var columnsPerRow = 4;
$scope.rows = function() {
return new Array(columnsPerRow);
};
$scope.indexInRange = function(columnIndex,rowIndex) {
return columnIndex >= (rowIndex * columnsPerRow) && columnIndex < (rowIndex * columnsPerRow) + columnsPerRow;
};
Born Solutions its best one, just need a bit tweek to feet the needs, i had different responsive solutions and changed a bit
<div ng-repeat="post in posts">
<div class="vechicle-single col-lg-4 col-md-6 col-sm-12 col-xs-12">
</div>
<div class="clearfix visible-lg" ng-if="($index + 1) % 3 == 0"></div>
<div class="clearfix visible-md" ng-if="($index + 1) % 2 == 0"></div>
<div class="clearfix visible-sm" ng-if="($index + 1) % 1 == 0"></div>
<div class="clearfix visible-xs" ng-if="($index + 1) % 1 == 0"></div>
</div>
Building on Alpar's answer, here's a more generalised way to split a single list of items into multiple containers (rows, columns, buckets, whatever):
<div class="row" ng-repeat="row in [0,1,2]">
<div class="col" ng-repeat="item in $ctrl.items" ng-if="$index % 3 == row">
<span>{{item.name}}</span>
</div>
</div>
for a list of 10 items, generates:
<div class="row">
<div class="col"><span>Item 1</span></div>
<div class="col"><span>Item 4</span></div>
<div class="col"><span>Item 7</span></div>
<div class="col"><span>Item 10</span></div>
</div>
<div class="row">
<div class="col"><span>Item 2</span></div>
<div class="col"><span>Item 5</span></div>
<div class="col"><span>Item 8</span></div>
</div>
<div class="row">
<div class="col"><span>Item 3</span></div>
<div class="col"><span>Item 6</span></div>
<div class="col"><span>Item 9</span></div>
</div>
The number of containers can be quickly coded into a controller function:
JS (ES6)
$scope.rowList = function(rows) {
return Array(rows).fill().map((x,i)=>i);
}
$scope.rows = 2;
HTML
<div class="row" ng-repeat="row in rowList(rows)">
<div ng-repeat="item in $ctrl.items" ng-if="$index % rows == row">
...
This approach avoids duplicating the item markup (<span>{{item.name}}</span> in this case) in the source template - not a huge win for a simple span, but for a more complex DOM structure (which I had) this helps keep the template DRY.
Update 2019 - Bootstrap 4
Since Bootstrap 3 used floats, it required clearfix resets every n (3 or 4) columns (.col-*) in the .row to prevent uneven wrapping of columns.
Now that Bootstrap 4 uses flexbox, there is no longer a need to wrap columns in separate .row tags, or to insert extra divs to force cols to wrap every n columns.
You can simply repeat all of the columns in a single .row container.
For example 3 columns in each visual row is:
<div class="row">
<div class="col-4">...</div>
<div class="col-4">...</div>
<div class="col-4">...</div>
<div class="col-4">...</div>
<div class="col-4">...</div>
<div class="col-4">...</div>
<div class="col-4">...</div>
(...repeat for number of items)
</div>
So for Bootstrap the ng-repeat is simply:
<div class="row">
<div class="col-4" ng-repeat="item in items">
... {{ item }}
</div>
</div>
Demo: https://www.codeply.com/go/Z3IjLRsJXX
I did it only using boostrap, you must be very careful in the location of the row and the column, here is my example.
<section>
<div class="container">
<div ng-app="myApp">
<div ng-controller="SubregionController">
<div class="row text-center">
<div class="col-md-4" ng-repeat="post in posts">
<div >
<div>{{post.title}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
I need to create a strcuture as below in my app through ng-repeat.
<div class="row">
<div class="col-50">1</div>
<div class="col-50">2</div>
</div>
<div class="row">
<div class="col-50">3</div>
<div class="col-50">4</div>
</div>
Right now my code is as below:
<div class="row">
<label class="item item-radio col col-50" ng-repeat="a in question.answer">
<input type="radio" name="answers" class="a-{{ a.correct }}" value="{{ a.correct }}" ng-click='ansValue("{{ a.correct }}")'>
<div class="item-content">
<img src="img/ans/{{ a.option }}" />
</div>
<i class="radio-icon ion-checkmark"></i>
</label>
</div>
But in the above code, its just a single row tag that I have. I wan't to somehow get the row tag contain/wrap every 2 items in the loop. What is the best way to achieve this?
Ref: Ionic Grid Doc
I managed to do it using $even.
<div ng-repeat="number in numbers">
<div class="row" ng-if="$even">
<div class="col col-50">{{numbers[$index]}}</div>
<div class="col col-50">{{numbers[$index + 1]}}</div>
</div>
</div>
Here's a working JSFiddle.
The solution from #Patrick Reck is excellent, but it forces you to repeat your code twice,
I suggest this improvement:
<div ng-repeat="number in numbers">
<div class="row" ng-if="$even">
<div class="col col-50"
ng-repeat="num in [numbers[$index],numbers[$index + 1]]">
{{num}}
</div>
</div>
</div>
this way you will write your code one time as if it is a normal ng-repeat
You can add flex-wrap: wrap to class row
http://jsfiddle.net/0momap0n/99/
<div ng-controller="MyCtrl">
<div class="row" style="flex-wrap: wrap">
<div class="col col-50" ng-repeat="number in numbers">{{number}}</div>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.numbers = [1, 2, 3, 4, 5, 6];
}
I would write it like this, you can increase the $index % 3 to match the number of columns that you would like, this one will create 3 columns ...
<div class="row">
<div class="" ng-repeat="i in range(1, 9)">
<div class="clearfix" ng-if="$index % 3 == 0"></div>
<div class="col">
<h1>{{ i }}</h1>
</div>
</div>
</div>
This solution is using flex-flow and solves this brilliantly:
CSS
.container {
display: flex;
flex-flow: row wrap;
}
.item {
width: 50%;
}
HTML
<div class="container">
<div class="item" *ngFor="let number of numbers">
{{number}}
</div>
Try like below. you can create any number of columns by using the below code. all you need to use the size property of the ionic grid and replace noOfColumns with your what number of columns you want. in this case just use 2 for noOfColumns. it will work like a charm.
Angular grid is based on a 12 column layout with different breakpoints based on the screen size. ref: https://ionicframework.com/docs/layout/grid
<ion-grid>
<ion-row >
<ion-col ng-repeat="n in numbers" size="{{12/noOfColumns}}">
{{ n }}
</ion-col>
</ion-row>
</ion-grid>