Very basic: ng-repeat - angularjs

I struggle with very basic Angular stuff.
And I don't know exactly, what to search for.
Like this one:
<div ng-repeat="i in [1,2,3]">
{{i}}
</div>
<hr/>
The output is (as expected): <div>1</div>...<div>3</div><hr/>
What I actually want is: <div>1</div><hr/> <div>2</div><hr/> <div>3</div> (no hr after 3)
So like: 1 | 2 | 3
How can I do that?
Please note: No hr after the last div.
Please note: I cannot put the hr-tag into the div.

You just have to create a parent div wrapping the div and hr and also to hide the last hr, use a comparison check with $last
<div ng-repeat="i in [1,2,3]">
<div>{{i}}</div>
<hr ng-if="!$last" />
</div>

As #Vivz answered you can just wrap it in a parent div. If for some reason you cannot however, you can use the ng-repeat-start and ng-repeat-end directive:
<div ng-repeat-start="i in [1,2,3]">
{{i}}
</div>
<hr ng-repeat-end ng-if="!$last" />

You can put your ng-repeat at a level higher. For example:
<span ng-repeat="i in [1,2,3]">
<div>{{i}}</div>
<hr/>
</span>
The result will be:
<span>
<div>1</div>
<hr/>
</span>
<span>
<div>2</div>
<hr/>
</span>
<span>
<div>3</div>
<hr/>
</span>
Note: I used a span for the parenet, but you can use another HTML element, such as a div.

nr-repeat is directive in angular which can can used with html element or itself as a tag
<ng-repeat ng-repeat="i in [1,2,3]">
<div>{{i}}</div>
<hr ng-if="!$last" />
</ng-repeat>

Related

AngularJS access loop length outside of ng-repeat

I basically want to hide the header if there are no items in the loop:
<div class="header" ng-if="notifications.length">
<h3>Title</h3>
</div>
<div ng-repeat="item in notifications" ng-if="!item.read">Stuff</div>
Is it possible to do this inside the template?
Maybe not the most elegant way, but if you actually need it to be done inside template, you can use filter: https://docs.angularjs.org/api/ng/filter/filter
In your case it would be something like:
<div class="header" ng-if="(notifications | filter:read=false).length">
<h3>Title</h3>
</div>
Also, you can use filter in ng-repeat:
<div ng-repeat="item in notifications | filter:read=false">Stuff</div>
Also, you can define new array inside template, in parent of those div's. This will be probably most readable solution.
<div ng-init="unreadNotifications = (notifications | filter:read=false)">
<div class="header" ng-if="unreadNotifications.length">
<h3>Title</h3>
</div>
<div ng-repeat="item in unreadNotifications">Stuff</div>
</div>
Yes you use this inside the tempate
<ng-template [ngIf]="notifications.length">
<div class="header">
<h3>Title</h3>
</div>
....
</ng-template>

accessing index of one array for another array

I want to access the index of dashboardCtrl.labels in dashboardCtrl.labelColors which is another array.I have tried the following but no success. If I print just {{$index}} it is getting printed successfully}}
<div class="row" ng-repeat="i in dashboardCtrl.labels">
<div id="circle" style="background:green"></div>{{i}}
<label>{{dashboardCtrl.labelColors[{{$index}}]}}</label>
</div>
You don't need nested brackets {{ }}. Try this
<div class="row" ng-repeat="i in dashboardCtrl.labels">
<div id="circle" style="background:green"></div>{{i}}
<label>{{dashboardCtrl.labelColors[$index]}}</label>
</div>
Do the following. Just $index in {{dashboardCtrl.labelColors[$index]}} instead of {{dashboardCtrl.labelColors[{{$index}}]}}
<div class="row" ng-repeat="i in dashboardCtrl.labels">
<div id="circle" style="background:green"></div>{{i}}
<label>{{dashboardCtrl.labelColors[$index]}}</label>
</div>
EDIT
Apply CSS style attribute dynamically in Angular JS
ng-style="{'background-color': dashboardCtrl.labelColors[$index]}"

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.

AngularJS conditional style if input value is empty

I have simple question but i can't find answer so many hours...
I would like to make something like google search. If it's empty then only one styled input box is on center of the screen, but when typing some text inside, div with filtered ng-repeat is shown, and input is on the top of the page. That input is also filter.
It looks something like this, and that works, but i can't figure out how to change style of div that is parrent to input, based on input value, or more precisely if it is empty or not.
Also any more elegant solution to this would be appreciated.
<div ng-class="header">
Search: <input type="text" ng-model="query"/> {{query}}
</div>
<div ng-switch on="query">
<div ng-switch-when="">
</div>
<div ng-switch-default>
<div class="product_list">
<div ng-repeat="product in products | filter:query" class="product_block">
<p id="name">{{ product.name }}</p>
</div>
</div>
</div>
Just use ng-show, ng-hide.
<div ng-class="{HeaderNoInput: query=='', HeaderHasInput: query!=''}">
Search: <input type="text" ng-model="query"/> {{query}}
</div>
<div ng-hide="query">Nothing to list.</div>
<div ng-show="query">
<div class="product_list">
<div ng-repeat="product in products | filter:query" class="product_block">
<p id="name">{{ product.name }}</p>
</div>
</div>
</div>

:first-child with ng-repeat

I have an ng-repeat and only want to apply a style to the first div with the class type in the ng-repeat.
<div class="my-list" ng-repeat="item in list">
<div class="type">
<span>{{item.label}}</span>
</div>
<div class="check">
<span>{{item.ischecked}}</span>
</div>
</div>
I have tried the following but it applied the CSS to all the divs with a class of type
.my-list .type:first-child
You can use $first, that indicates the first iteration within a ng-repeat.
<div class="my-list" ng-repeat="item in list">
<div class="type" ng-class="{myClass:$first}">
<span>{{item.label}}</span>
</div>
<div class="check">
<span>{{item.ischecked}}</span>
</div>
</div>
Basically you need to do the other way around.
.my-list:first-child .type{
color:red;
}
ng-repeat will put multiple .my-list divs and you want to target the .type of the first div alone. So apply selector on .my-list.

Resources