How to add a class to specific html elements created by ngRepeat? - angularjs

I need to add a class to the last <li> in an <li>group created using Angular's ngRepeat. So the code below
<ul>
<li class="columns small-3" ng-repeat="tag in tags">
{{tag}}
</li>
<ul>
creates something like
<ul>
<li>Art</li>
<li>Science</li>
<li>Beauty</li>
<ul>
What I need is for the class .end to be added to the last <li> so the end result would be
<ul>
<li>Art</li>
<li>Science</li>
<li class="end">Beauty</li>
<ul>
How is this possible?

You should be able to do this using a combination of ng-class and $last.
<ul>
<li class="columns small-3" ng-class="{'end':$last}" ng-repeat="tag in tags">
{{tag}}
</li>
<ul>

Try with ng class with a condition on the index

Related

css selector to retrieve nodes without any id

I only want to catch the first list item with a css selector.
That can i do?
<ul>
<li class="someclass"> </li>
<li id="thisId" class="someclass"> </li>
<li id="thatId" class="someclass"> </li>
<li id="someId" class="someclass"> </li>
<ul>
ul li.someclass:first-child{
}

ng-click firing multiple times inside ul li

<ul>
<li ng-click="setSelectedItem(member.id)">test
<ul>
<li ng-click="setSelectedItem(member.id)">test 2
<ul>
<li ng-click="setSelectedItem(member.id)">inner test2
</li>
</ul>
</li>
</ul>
</li>
</ul>
The above tree structure is generated by two directives by using this stack overflow question.
When test is clicked setSelectedItem() gets called once. When test2 is clicked setSelectedItem() gets called twice. When inner test2 is clicked setSelectedItem() gets called thrice.
Can anyone help me solve this. I want the click to be called only once when clicking the inner li tags. Thanks
To stop event propogation, use below code.
<li ng-click="setSelectedItem(member.id); $event.stopPropagation();">test</li>
Use $event.stopPropagation();. To prevent bubling of click event to the parents.
<ul>
<li ng-click="setSelectedItem(member.id);$event.stopPropagation();">test
<ul>
<li ng-click="setSelectedItem(member.id);$event.stopPropagation();">test 2
<ul>
<li ng-click="setSelectedItem(member.id);$event.stopPropagation();">inner test2
</li>
</ul>
</li>
</ul>
</li>
</ul>

How to wrap parts of an ngRepeat

How can one, if at all possible, do the following:
<ul>
<li ng-reapeat="a in c"></li>
</ul>
with an output like this:
<ul>
<div>
<li></li> <--- from a to b (say first till 3rd element)
<li></li>
...
</div>
<div>
<li></li> <--- from b to c (4th element till end)
<li></li>
...
</div>
</ul>
Or even multiple <ul></ul> blocks. First one closing at a designated index, second one opening and continuing until the end.
What about slicing the array (probably not an "angular way"), for example
<ul>
<div>
<li ng-repeat="a in c.slice(0, 3)"></li>
</div>
<div>
<li ng-repeat="a in c.slice(3)"></li>
</div>
</ul>
General idea, you should be able to get what you want using this pattern
<ul>
<li ng-repeat-start="a in c" ng-show="$index<3"></li>
<li ng-repeat-end ng-show="$index>=3"></li>
</ul>
Try this:
I think you need multiple ul blocks.
<ul>
<div ng-reapeat="a in c">
<li ng-if="$index<3"></li>
</div>
</ul>
<ul>
<div ng-reapeat="a in c">
<li ng-if="$index>2"></li>
</div>
</ul>
Hope it helps...!

How can I use the same piece of html with different data in AngularJS without duplication?

I need the following:
<ul>
<li data-ng-repeat="person in row1">
<img data-ng-src="img/{{person.code}}.jpg">
<h3>{{person.name}}</h3>
<p>{{person.description}}</p>
</li>
</ul>
<ul>
<li data-ng-repeat="person in row2">
<img data-ng-src="img/{{person.code}}.jpg">
<h3>{{person.name}}</h3>
<p>{{person.description}}</p>
</li>
</ul>
but I don't want to duplicate the html - I want to be able to pass in the two different arrays (row1 and row2) to ng-include or something similar. How can I do this in AngularJS?
You can give the array of rows to another model and use ng-repeat in ul tag
In your controller:
$scope.rows = [row1, row2];
In your template:
<ul ng-repeat="row in rows">
<li ng-repeat="person in row">
<img data-ng-src="img/{{person.code}}.jpg">
<h3>{{person.name}}</h3>
<p>{{person.description}}</p>
</li>
</ul>

passing 2 $index values within nested ng-repeat

So I have an ng-repeat nested within another ng-repeat in order to build a nav menu. On each <li> on the inner ng-repeat loop I set an ng-click which calls the relevant controller for that menu item by passing in the $index to let the app know which one we need. However I need to also pass in the $index from the outer ng-repeat so the app knows which section we are in as well as which tutorial.
<ul ng-repeat="section in sections">
<li class="section_title {{section.active}}" >
{{section.name}}
</li>
<ul>
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu($index)" ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}
</li>
</ul>
</ul>
here's a Plunker http://plnkr.co/edit/bJUhI9oGEQIql9tahIJN?p=preview
Each ng-repeat creates a child scope with the passed data, and also adds an additional $index variable in that scope.
So what you need to do is reach up to the parent scope, and use that $index.
See http://plnkr.co/edit/FvVhirpoOF8TYnIVygE6?p=preview
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu($parent.$index)" ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}
</li>
Way more elegant solution than $parent.$index is using ng-init:
<ul ng-repeat="section in sections" ng-init="sectionIndex = $index">
<li class="section_title {{section.active}}" >
{{section.name}}
</li>
<ul>
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu(sectionIndex)" ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}
</li>
</ul>
</ul>
Plunker: http://plnkr.co/edit/knwGEnOsAWLhLieKVItS?p=info
What about using this syntax (take a look in this plunker). I just discovered this and it's pretty awesome.
ng-repeat="(key,value) in data"
Example:
<div ng-repeat="(indexX,object) in data">
<div ng-repeat="(indexY,value) in object">
{{indexX}} - {{indexY}} - {{value}}
</div>
</div>
With this syntax you can give your own name to $index and differentiate the two indexes.
Just to help someone who get here... You should not use $parent.$index as it's not really safe. If you add an ng-if inside the loop, you get the $index messed!
Right way
<table>
<tr ng-repeat="row in rows track by $index" ng-init="rowIndex = $index">
<td ng-repeat="column in columns track by $index" ng-init="columnIndex = $index">
<b ng-if="rowIndex == columnIndex">[{{rowIndex}} - {{columnIndex}}]</b>
<small ng-if="rowIndex != columnIndex">[{{rowIndex}} - {{columnIndex}}]</small>
</td>
</tr>
</table>
Check: plnkr.co/52oIhLfeXXI9ZAynTuAJ
Just use ng-repeat="(sectionIndex, section) in sections"
and that will be useable on the next level ng-repeat down.
<ul ng-repeat="(sectionIndex, section) in sections">
<li class="section_title {{section.active}}" >
{{section.name}}
</li>
<ul>
<li ng-repeat="tutorial in section.tutorials">
{{tutorial.name}}, Your section index is {{sectionIndex}}
</li>
</ul>
</ul>
When you are dealing with objects, you want to ignore simple id's as much as convenient.
If you change the click line to this, I think you will be well on your way:
<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu(tutorial)" ng-repeat="tutorial in section.tutorials">
Also, I think you may need to change
class="tutorial_title {{tutorial.active}}"
to something like
ng-class="tutorial_title {{tutorial.active}}"
See http://docs.angularjs.org/misc/faq and look for ng-class.

Resources