angularjs: ng-repeat over half the length of an array - angularjs

I am using ngRepeat angularjs to fill out a grid in bootstrap. The grid needs periodic clearfixes.
So, for example, if the grid is:
<div class="container">
<div class="row">
<div class="col-md-4 col-sm-6">
foo bar
</div>
<div class="col-md-4 col-sm-6">
foo bar
</div>
<div class="clearfix visible-sm-block"></div>
<div class="col-md-4 col-sm-6">
foo bar
</div>
<div class="clearfix visible-md-block"></div>
<div class="col-md-4 col-sm-6">
foo bar
</div>
<div class="clearfix visible-sm-block"></div>
<div class="col-md-4 col-sm-6">
foo bar
</div>
<div class="col-md-4 col-sm-6">
foo bar
</div>
</div>
</div>
Is this accomplishable with ngRepeat? It seems that a structure like:
<div class="container">
<div class="row">
<div data-ng-repeat="i in [0,1,2,3,4,5]" class="col-md-4 col-sm-6">
foo bar
</div>
</div>
</div>
Couldn't get the clearfixes in there with the iterator.

Angular has an index property called $index when you're inside of the ng-repeat directive. You could use this to display your clearfix div when it is needed. If you want to shortcut it even more, you could use the $even or $odd (in your case, $odd) property to display it every two instances.
Combining the special ng-repeat-start and ng-repeat-end directives, you could do something like this to get at your required result:
<div class="container">
<div class="row">
<div ng-repeat-start="i in [0,1,2,3,4,5]" class="col-md-4 col-sm-6">
foo bar
</div>
<div ng-repeat-end ng-if="$odd" class="clearfix visible-sm-block"></div>
</div>
</div>
More Info: ng-repeat, ng-if
Here's a Plunker to show it's working: PLUNKER

Related

ng-repeat changing position left to right

I have one problem with angular ng-repeat and bootstrap. I tried divide view on two parts left image, right description, but next line oposite, left description and right image. I would like something like picture below
<div class="container">
<div class="row">
<div ng-repeat="item in items">
<div class="col-xs-6">
<img src="{{item.image}}" alt="#"/>
</div>
<div class="col-xs-6">
<div class="description">
<p>{{item.description}}</p>
</div>
</div>
</div>
</div>
</div>
You can check for odd or even iteration in the repeat loop and apply your class with either float left or right respectively.
<div class="container">
<div class="row">
<div ng-repeat="item in items" ng-class-odd="'img-left'">
<div class="col-xs-6 img-holder">
<img src=".." alt="#"/>
</div>
<div class="col-xs-6 text-holder">
<div class="description">
<p>........</p>
</div>
</div>
</div>
</div>
</div>
CSS
.img-left .img-holder{
float:left;
}
.img-left .text-holder{
float:right;
}
you can handle even condition directly in CSS or like above.
This is my solution. Using ng-class we check if the current index ($index) divided by 2 is zero then we add the float classes either .left or .right.
JSFiddle Demo
<div ng-controller='MyController'>
<div ng-repeat="val in arr">
<div class="row clearfix">
<div class="col-xs-6" ng-class="$index % 2 === 0 ? 'left':'right'">
{{val}}
</div>
<div class="col-xs-6" ng-class="$index % 2 === 0 ? 'right':'left'">
<img src="http://lorempixel.com/400/200/" alt="">
</div>
</div>
</div>
</div>

Advice for specific bootstrap layouts

I have a layout in mind that I'd like to look like this on a desktop monitor. It more or less works right now but I wonder if the 'D' and 'E' sections should be col-md-6 or col-md-3?
Desktop Layout
Also, (and this is where it gets interesting), on mobile I'd like it to be layed out like this:
Mobile Layout
Can one single layout work? I'm busy on the desktop layout but, yeah, everytime I switch to the mobile view things are not good. Therefore, I have a feeling my initial approach leaves something to be desired.
Solution code:
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-6 col-md-push-3">
<div class="row">
<div class="col-xs-12">
<section class="box">B</section>
</div>
<div class="col-xs-6">
<section class="box">D</section>
</div>
<div class="col-xs-6">
<section class="box">E</section>
</div>
</div>
</div>
<div class="col-xs-6 col-md-3 col-md-pull-6">
<section class="box">A</section>
</div>
<div class="col-xs-6 col-md-3">
<section class="box">C</section>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<section class="box">F</section>
</div>
<div class="col-xs-6">
<section class="box">G</section>
</div>
</div>
</div>

Angular JS - How to close and start DIV out of ng-repeat

I have one div as row and 4 div as column. I want to close row div after 4 cloumn div.
<div class="row">
<div class="clo"></div>
<div class="clo"></div>
<div class="clo"></div>
<div class="clo"></div>
</div>
<div class="row">
<div class="clo"></div>
<div class="clo"></div>
<div class="clo"></div>
<div class="clo"></div>
</div>
Now in ng-repeart
<div class="row">
<div class="col" ng-repeat="x in values">
{{x.name}}
</div>
<div ng-if="$index % 4==0">
<div class="clearfix"></div>
</div>
<div class="row">
</div>
it's not working for me
I also tried this as refrence but it only add clearfix div only. Not close the div class="row"> and not start again div class="row">
The clearfix solution assumes you are using Bootstrap CSS. If you're not then you'll have to grab the clearfix class from Bootstrap.css.
If you are including Bootstrap, and looking to use Bootstrap to do the layout then you can use:
<div ng-init="a = [1,2,3,4,5,6,7,8]"> <!-- sample data !-->
<div class="row">
<div ng-repeat="product in a">
<div class="clearfix" ng-if="$index % 4 == 0"></div>
<div class="col-sm-3">
<h2>{{a[$index]}}</h2>
</div>
</div>
</div>
</div>
Here's the demo: http://plnkr.co/edit/ibRsIfazxea2KpGmUg42?p=preview
Note I've reworked the answer from https://stackoverflow.com/a/32358013/1544886 to your requirements
Another option (based on https://stackoverflow.com/a/30259461/1544886)
<div ng-repeat="product in a" ng-if="$index % 4 == 0" class="row">
<div class="clearfix" ng-if="$index % 4 == 0"></div>
<div class="col-sm-3">{{a[$index]}}</div>
<div class="col-sm-3" ng-if="a.length > ($index + 1)">{{a[$index + 1]}}</div>
<div class="col-sm-3" ng-if="a.length > ($index + 2)">{{a[$index + 2]}}</div>
<div class="col-sm-3" ng-if="a.length > ($index + 3)">{{a[$index + 3]}}</div>
</div>
You likely don't need the clearfix div, but as you have indicated in the comments that you want it as well, I have included it above.
Change it below like this: $index is available inside your ng-repeat and not outside.
<div class="row">
<div class="col" ng-repeat="x in values">
{{x.name}}
<div ng-if="$index % 4==0" class="clearfix"></div>
<div class="row">
</div>
</div>
</div>

Using Twitter Bootstrap's .row element with ng-repeat

I have the following snippet in my AngularJS app:
<div ng-repeat="proverb in proverbs">
<div class="col-sm-6">
<div class="alert alert-warning">
{{proverb}}
</div>
</div>
</div>
This will generate a div element with the class col-sm-6 for every proverb in my proverbs array. My intention is to display two columns whenever a screen is big enough.
Despite not using Bootstrap's .row element, the above snippet works exactly as intended.
The question is, how could I include a .row element that would only appear every second iteration of ng-repeat so that I would get the following end result:
<div class="row">
<div class="col-sm-6">
<div class="alert alert-warning">
{{proverb}}
</div>
</div>
<div class="col-sm-6">
<div class="alert alert-warning">
{{proverb}}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="alert alert-warning">
{{proverb}}
</div>
</div>
<div class="col-sm-6">
<div class="alert alert-warning">
{{proverb}}
</div>
</div>
</div>
Also, given that whenever the sum of the spans of .col elements in Bootstrap is greater than 12 the next element gets pushed down, is there even any reason to use the .row class other than to guarantee a new row is generated before all columns are completely filled?
If you don't need the .row then you could do this
<div ng-repeat="proverb in proverbs">
<div class="col-sm-6">
<div class="alert alert-warning">
{{proverb}}
<ng-show="$index % 2 == 0" br/>
</div>
</div>
</div>

Creating bootstrap grid with ng-repeat

I have an array of products. I would like to display them in rows, with 4 products per row. Right now my code is
<div ng-repeat="product in products" class="col-md-3">
<p> {{product.name}} </p>
<p> {{product.price}} </p>
</div>
However, this is not displaying properly. I have tried to incorporate rows with an ng-if, but this is as close as I've come:
<div ng-repeat="product in products">
<div ng-if="$index %4 == 0" class="row">
<div class="col-md-3">
(content)
</div>
</div>
<div ng-if="$index %4 != 0" class="col-md-3">
(content)
</div>
</div>
I think I know why the above doesn't work: if index %4 != 0then the column that is created is not actually put inside of the row made before.
Is there an angular way to do this? Do I need a custom directive? Note: I have managed a solution not using angular directives but it doesn't seem clean, so I would like to do it "angularly" if possible.
You should be able to use your first method just fine, here's the html I wired up in a js fiddle:
<div ng-app="app">
<div ng-controller="ParentCtrl">
<div class="container">
<div class="row">
<div data-ng-repeat="option in options" class="col-md-3">
{{ option }}
</div>
</div>
</div>
</div>
</div>
Fiddle: http://jsfiddle.net/ubexop9p/
You will have to play around with the frame sizes if your monitor is too small, but I was able to get it do what you wanted.
Do you have that wrapped in a container or container-fluid? I believe that's required for the grid system to work.
<div class="container">
<div class="col-md-3">Col 1</div>
<div class="col-md-3">Col 2</div>
<div class="col-md-3">Col 3</div>
<div class="col-md-3">Col 4</div>
<div class="col-md-3">Col 5</div>
</div>
Turns out it was a problem with the content I was putting inside the columns, the code I posted does in fact work.

Resources