AngularJS Dropdown ng-if on ng-repeat element - angularjs

I'm building a twitter bootstrap list using angular's ng-repeat:
<ul class="dropdown dropdown-menu">
<li class="menuOption" ng-repeat="option in options">
<a data-ng-click="option.value>0 ? foo() : goo()">
{{option.label}}
</a>
</li>
</ul>
Now, I want to include a divider (<li class="divider"></li>) inside this list. It should be before the last element in the list (which is also indicated by option.value with a negative value, which is probably an easier indication).
My problem is that since the ng-repeat iteration is on the li element itself, I couldn't find a way to use ng-if on this element.

Try ng-repeat-start and ng-repeat-end:
<ul class="dropdown dropdown-menu">
<li class="menuOption" ng-repeat-start="option in options" ng-if="option.value>0">
<a data-ng-click="option.value>0 ? foo() : goo()">
{{option.value}}
</a>
</li>
<li class="divider" ng-repeat-end ng-if="option.value<0">
option < 0 ({{option.value}})
</li>
</ul>
DEMO

Related

ng-repeat list item is not rendering inside the anchor

So heres what the html looks like in the text editor...
<div ng-repeat="x in Result">
<a ng-href="https://domain.com/{{x.short_url}}">
<li class="viewer" id="{{x.user_id}}" style="background-image: url(https://domain.com/{{x.user_id}})">
</a>
</div>
But when its rendered in the browser it looks like this...
<a ng-href="https://domain.com/ucmzda" href="https://domain.com/ucmzda"></a>
<li class="viewer" id="b5599b09bcb3467ba3ade4e5b30721a4" style="background-image: url(https://domain.com/image/user/b5599b09bcb3467ba3ade4e5b30721a4)">
I cant figure out why the list item is not rendering inside the anchor?
<div ng-repeat="x in Result">
<a ng-href="https://domain.com/{{x.short_url}}">
<li class="viewer" id="{{x.user_id}}" style="background-image: url(https://domain.com/{{x.user_id}})"><li>
</a>
</div>
refer:
ng-repeat inserting empty anchor tags
In your case li is not closed:
It is not a good practies to use li inside a tag:
use like this
<ul ng-repeat="x in Result">
<li class="viewer" id="{{x.user_id}}" style="background-image: url(https://domain.com/{{x.user_id}})"><a ng-href="https://domain.com/{{x.short_url}}">
</a>
</li>
</ul>
Have you by any chance configured your $locationProvider to html5Mode? If yes this would cause your problems. You could force it to always go to the url by adding target="_self" to your tag. Give it a shot.**
use HTML5 so adding the target="_self" it will work

how to select a li which is nested within another ng-repeat in angular js

(please do not update the english grammer in this question/ I wont be able to approve it and this question wont get resolved.)
This is my UI
It contains various li elements whose values are populated using this angular html
<div class="row">
<li class="no-bullet-li li-12 monaco-font"> {{selectedChangeEligibilityPlan}}</li>
<ul class="ul-plan-1">
<li class="no-bullet-li" ng-repeat="plan in fewThings">
<div ng-class="{ 'selected-class-name': $index == selectedIndex }" ng-click="itemClicked($index)" class="li-alt monaco-font"> p2|{{plan.planName}} | {{plan.planId}}
<a class="iconing-sub" ng-click="addClick(item)" href=""><i class="glyphicon glyphicon-plus"></i></a>
<a ng-click="deleteClick(item)" ng-class="{ active : active.one }" href=""><i class="glyphicon glyphicon-remove iconing_1-sub"></i></a>
</div>
<ul class="ul-plan">
<li class="no-bullet-li li-8 monaco" ng-repeat="item in plan.planIds">
p1| {{ plan.planNames[$index]}} | {{item}}
<a <a ng-click="editClick(item)" href=""><i class="glyphicon glyphicon-pencil iconing"></i></a>
<a ng-click="deleteClick(item)" href=""><i class="glyphicon glyphicon-remove iconing_1"></i></a>
</li>
</ul>
</li>
</ul>
</div>
It uses the nested ng-repeat.
The whole UI is contained within a one controller ( no directives used)
the following code gets triggered when someone clicks the blue lis.
$scope.itemClicked = function ($index) {
console.log($index);
// console.log($(item).closest('li') );
$scope.selectedIndex = $index;
};
here's how to ui looks and its great.
problem arises when I try to do the same logic for the pink ones (nested ng-repeat li). It selects other pink lis in all the other stack too.
here's the screenshot.
second part of question:
I have I have the above UI plus I also have this second UI that is loaded along with this on the same page. It contains a bunch of horizontal rows.
Once the user click the blue pink colored lis it goes into the active state. Then the user can click the row which he likes. upon clicking it the plan name of currently selected li will get replaced.
Here is the html for it.
<div class="row">
<li class="no-bullet-li li-12 monaco-font"> {{selectedChangeEligibilityPlan}}</li>
<ul class="ul-plan-1">
<li class="no-bullet-li" ng-repeat="plan in fewThings">
<div class="li-alt monaco-font"> p2|{{plan.planName}} | {{plan.planId}}
<a class="iconing-sub" ng-click="addClick(item)" href=""><i class="glyphicon glyphicon-plus"></i></a>
<a ng-click="deleteClick(item)" ng-class="{ active : active.one }" href=""><i class="glyphicon glyphicon-remove iconing_1-sub"></i></a>
</div>
<ul class="ul-plan">
<li ng-class="{ 'selected-class-name': $index == selectedIndex }" ng-click="itemClicked($index)" class="no-bullet-li li-8 monaco" ng-repeat="item in plan.planIds">
p1| {{ plan.planNames[$index]}} | {{item}}
<a ng-click="editClick(item)" href=""><i class="glyphicon glyphicon-pencil iconing"></i></a>
<a ng-click="deleteClick(item)" href=""><i class="glyphicon glyphicon-remove iconing_1"></i></a>
</li>
</ul>
</li>
</ul>
</div>
The problem lies in the fact that you are trying to save the state of the data (which one is selected) inside your controller using $index. The $index property isn't unique among different ng-repeats, so when you set your $scope.selectedIndex to $index, each of your sub lists will see that their $index matches, and so will each trigger the ng-class and add the selected-class-name class.
What you could do instead is have each item in the data have a unique index and use that id to store which item is selected in $scope.selectedIndex.
<ul class="ul-plan">
<li ng-class="{ 'selected-class-name': item.id == selectedIndex }" ng-click="itemClicked(item.id)" class="no-bullet-li li-8 monaco" ng-repeat="item in plan.planIds">
p1| {{ plan.planNames[$index]}} | {{item}}
<a ng-click="editClick(item)" href=""><i class="glyphicon glyphicon-pencil iconing"></i></a>
<a ng-click="deleteClick(item)" href=""><i class="glyphicon glyphicon-remove iconing_1"></i></a>
</li>
</ul>
This line looks strange.
<a ng-click="select('one')" href="">
Did you really mean to pass a hardcoded 'one' to the function? Or was it supposed to be the index, like the deleteClick() call.

Skip first item in ng-repeat

I want to skip the first item in ng-repeat
..first item here
<ul class="highlight-topright">
<li ng-repeat="item in hpHeadlines | filter:$index>0">
...
</li>
</ul>
it doesn't work, anything wrong here ?
I understand that i can use ng-if, ng-show to hide things but I just cannot get why the filter doesn't work in 1.3.x in this case.
Thanks.
<ul class="highlight-topright">
<li ng-repeat="item in hpHeadlines" ng-if="$index > 0">
...
</li>
</ul>
Use $first for this:
<ul class="highlight-topright">
<li ng-repeat="item in hpHeadlines" ng-hide="$first">
...
</li>
</ul>
Or,
<ul class="highlight-topright">
<li ng-repeat="item in hpHeadlines" ng-if="!$first">
...
</li>
</ul>
You can also use the limitTo filter.
As a negative index, begin indicates an offset from the end of input. Defaults to 0.
<li ng-repeat="item in hpHeadlines | limitTo: 1 - hpHeadlines.length">
...
</li>
Maybe I am late to answer this. But just for newbies, I am providing solution. As you want to skip the first record, so you can use either $index or $first for achieving, as shown below:
<li ng-repeat="item in hpHeadlines" ng-if="$index"> OR
<li ng-repeat="item in hpHeadlines" ng-if="!($first)">
As you could see, in both, ng-if is skipping '0' value.
You can use ng-show or ng-if without using it as a filter. It's easier because you know the index you want to skip.
Use filters usually when you want to do something that concerns all the array, such as formatting for instance, or parts that you don't know where they reside.
<ul class="highlight-topright">
<li ng-repeat="item in hpHeadlines" ng-show="$index != 0">
{{item.name}}
</li>
</ul>
JS Fiddle
You can use ng-show instead, like this:
<ul class="highlight-topright">
<li ng-repeat="item in hpHeadlines" ng-show="$index > 0">
...
</li>
</ul>
Or you can use ng-if directive in case you don't want to add invisible dom elements.

angular binding span within custom dropdown

I have a custom dropdown like the one below which I use in a form to create roles. The purpose of the dropdown is to select a css-class to associate with a role. The name of the css-classes are role0, role1, role2.... role9
<ul class="dropdown-menu dropdown-select">
<li ng-repeat="i in [1,2,3,4,5,6,7,8,9,10]">
<a href="#"><input type="radio" ng-model="roleCss" value="role{{$index}}" name="d-s-r">
<span class="label role{{$index}}"> </span>
</a>
</li>
</ul>
how do I bind the value of roleCss, so it saves the correct value (eg. role1) ?
Thanks
Thomas
You pretty much have it correct. The only problem is that ng-repeat creates its own scope, so the roleCss you are saving into is in that scope, not your controllers scope. All you need to do is add $parent like this.
<ul class="dropdown-menu dropdown-select">
<li ng-repeat="i in [1,2,3,4,5,6,7,8,9,10]">
<a href="#"><input type="radio" ng-model="$parent.roleCss" value="role{{$index}}" name="d-s-r">
<span class="label role{{$index}}"> </span>
</a>
</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