Access parent index in nested ng-repeat - javascript

I would like to do this really basic example :
<div ng-controller="ctrl">
<li ng-repeat="config in configs">
<span >Config : {{config}}</span>
<li ng-repeat="version in versions">
{{config}}
</li>
</li>
</div>
So basically, I got 2 imbricated ng-repeat loop, and I would like to access a value of the first loop from the second one.
I thought it was really basic, but no way to make it work. My result of that is 1 liwith the config printed, and 3 empty sub lis
I already tried a lot of combination list {{$parent.index}}, {{$parent.config}} etc ...

I'm pretty sure this has to do with the structure of your HTML.
Here is a working plunker.
Since you are omitting the <ul> tags that are required for lists. The nested <li> is causing a display issue.
I have simple wrapped the <li> with <ul> and it seems to work fine:
<div ng-controller="ctrl">
<ul>
<li ng-repeat="config in configs">
<span >Config : {{ config }}</span>
<ul>
<li ng-repeat="version in versions">
VersionConfig: {{ config }}
</li>
</ul>
</li>
</ul>
</div>

Related

Using <h3> within <ol> with ng-repeat

<ol ng-repeat="item in ctrl.items">
<h3 ng-bind-html="item.title"></h3>
<li ng-repeat="description in item.items" ng-bind-html="description"> </li>
</ol>
This is how it is rendered on screen:
**Title1**
1. Desciption1
2. Description2
**Title2**
1. Description1
But as per the HTML standards, ol should only contain li, not h3.
Any idea how we can achieve this?
Why don't you just wrap this construction in one more block? Placing h3 tag in this case will be correct enough.
<div ng-repeat="item in ctrl.items">
<h3 ng-bind-html="item.title"></h3>
<ol>
<li ng-repeat="description in item.items" ng-bind-html="description"></li>
</ol>
</div>
In other case, if you would like to create list of lists and you really want to use <ol> for both you can do in the next way:
<ol ng-repeat="item in ctrl.items">
<li>
<h3 ng-bind-html="item.title"></h3>
<ol>
<li ng-repeat="description in item.items" ng-bind-html="description"></li>
</ol>
</li>
</ol>
In this way you have nested lists, but all h3 tags are inside the li tag, not inside the oldirectly. That is fine. HTML syntax rules allow headings tags in the li elements. I would prefer to use first variant, because it looks clearer and more understandable.
But second one also is a valid HTML structure according to W3 validator:
Use div inside li tag
as follows:
<li ng-repeat="description in item.items">
<div>
<h3 ng-bind-html="item.title"></h3>
<div ng-bind-html="description"></div>
</div></li>

how to properly show and hide elements in my case

I have a weird question regarding the no-show
I have something like
<ul>
<li ng-repeat="item in items" >
<a ng-click="showNew =! showNew">{{item.text}}
<span ng-show="showNew">New Items!</span>
</a>
</li>
<li ng-show="showNew">
<a >Category 1 </a>
</li>
</ul>
For some reason, only the 'New Items!' was shown when I click a tag. The Category 1 would never show. I thought showNew would be in the same scope for everything in my case. How do I solve this? Thanks a lot!
You can use ng-init to create the variable higher up in the template and that should help. This is not an ideal fix but it is quick and easy if you don't want to edit other files.
EDIT: you will need to use dot notation in your model so the angular scope magic can work. (this is the equivolent of $scope.nested = {showNew: false}
<ul ng-app ng-init="nested.showNew=false">
<li ng-repeat="item in [1,2,3]" >
<a ng-click="nested.showNew =! nested.showNew">{{$index}}
<span ng-show="nested.showNew">New Items!</span>
</a>
</li>
<li ng-show="nested.showNew">
<a >Category 1 </a>
</li>
</ul>
http://jsfiddle.net/0692dbak/

Multiple Iterations with AngularJS ng-repeat

I've searched for a while and did find a lot about multiple iterations. The problem is that i don't see a plain solution for my problem.
I have a list of checkbox that is filled dinamically with ng-repeat. Due to layout purposes i need to create a new div inline-block whenever i reach 3 checkboxes. Like that:
CheckBoxList = {1,2,3,4,5}
<div class="form-group-content">
<div class="form-col-secondary">
<ul class="list-checkboxes">
<li>
<input type="checkbox"/>1
</li>
<li>
<input type="checkbox"/>2
</li>
<li>
<input type="checkbox"/>3
</li>
</ul>
</div>
<div class="form-col-secondary">
<ul class="list-checkboxes">
<li>
<input type="checkbox"/>4
</li>
<li>
<input type="checkbox"/>5
</li>
</ul>
</div>
</div>
I tried using a iterator and two ng-repeat but didn't work like i wanted to.
If somebody already had this struggle and could help i would appreciate it.
To achieve this you will have to make 2 updates.
2 ng-repeat
Change structure
HTML Code
<div class="form-group-content">
<div class="form-col-secondary" ng-repeat="block in blocks">
<ul class="list-checkboxes">
<li ng-repeat="checkbox in block">
<input type="checkbox{{$index + 1}}"/>
</li>
</ul>
</div>
</div>
JS Code
$scope.blocks = [
['1','2','3'],
['4','5']
];
Here is a plunker for you - http://plnkr.co/edit/BWcFI5d02yPkAYDiQxvO?p=preview
If you split your CheckBoxList in parts of 3, you can use your ng-repeat on each div.
So change checkboxlist to something like:
divs = [[1,2,3],[4,5,6]];
then your html:
<div class="form-col-secondary" ng-repeat="div in divs">
<ul class="list-checkboxes">
<li ng-repeat="checkbox in div">
<input type="checkbox" ng-attr-id="{{checkbox}}">
</li>
</ul>
</div>
This might nog exactly match what you want as result, but it reflects the principle on which you should be able to create your own working version :-)
Edit
Worth noting: As far as I am aware, you can't have <input type="checkbox1" />, I think you mean <input type="checkbox" id="1" name="checkbox1" /> instead.
You'll have to track by $index in your ng-repeat and either ng-if or ng-show and $index < 3 for your first set and $index > 2 for the second set.

Angularjs-UI sortable multiple div list

I am trying to get sortable to work.
<ul ui-sortable='data.sortableOptions' ng-model="dp.claims" class="list-unstyled">
<li ng-repeat="c in dp.claims">
<div> {{c.field1}} </div>
<div> {{c.field2}} </div>
<div> {{c.field3}} </div>
</li>
</ul>
I can't seem to grab and drag anything. The important part of this question is the 3 div's in the li
I admit, I don't understand what this line in the docs means: "ui-sortable element should only contain one ng-repeat and not any other elements (above or below)."
And I am able to get it to work with a table.
Any insights?
Yes, the docs do say "ui-sortable element should only contain one ng-repeat and not any other elements (above or below)." which makes it hard to have 3 divs in the li. However, there is a solution.
You can use tg-dynamic-directive (at https://github.com/thgreasi/tg-dynamic-directive) to solve this. Don't forget to include it, and put 'tg.dynamicDirective' in your dependencies. Basically you take out the middle part in between the li tags, in this case the 3 divs, and you put it in another file and link to it.
<ul ui-sortable='data.sortableOptions' ng-model="dp.claims" class="list-unstyled">
<li ng-repeat="c in dp.claims">
</li>
</ul>
Then in another file put the innards, like innards.html:
<div> {{c.field1}} </div>
<div> {{c.field2}} </div>
<div> {{c.field3}} </div>
And replace the innards with:
<ul ui-sortable='data.sortableOptions' ng-model="dp.claims" class="list-unstyled">
<li ng-repeat="c in dp.claims">
<tg-dynamic-directive ng-model="c" tg-dynamic-directive-view="getView">
</tg-dynamic-directive>
</li>
</ul>
And in your controller put something like:
$scope.getView = function(item) {
if item {
return 'innards.html';
return null;
};
Anyways the docs go over it pretty well. I realize this question is pretty old but I just ran into this myself and got it working so hopefully it helps someone else.

Angular ng-repeat without html element

I'm in trouble with a foreach that I need to do with Angular.
Thats's what I want to do :
<ul>
<div ng-repeat="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li class="divider"></li>
</div>
</ul>
How can I do something like that, but in valid HTML structure ? (without a <div> between <ul> and <li>)
I see only one solution :
Replace the <div> with a <ul> and make a lot of css rules to make it like it doesn't exists
In addition, I use Angular 1.4.8.
Thanks !
You shouldn't have to alter your data structure at all. Instead just utilize the ng-repeat-start & ng-repeat-end directive. You'll have separate <ul>s but in terms of rendering, you can easily modify the CSS to make it appear to be a seamless list.
<ul ng-repeat-start="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li ng-repeat-end class="divider"></li>
</ul>
http://codepen.io/jusopi/pen/KVZBLv
Probably the easiest way is to use a custom collection groupedCommands that is bound to the angular scope in code and contains the items in the correct order.
Then use ng-repeat-start for the enhanced repeat directive. There is a special ng-repeat-start and ng-repeat-end attribute combination that you can use for this case:
<ul>
<li ng-repeat-start="c in groupedCommands">{{c.text}}</li>
<li class="divider" ng-repeat-end></li>
</ul>
Try This one,
<ul>
<!-- ng-repeat: g in groups -->
<span ng-repeat="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li class="divider"></li>
</span>
</ul>
This may solve your problem.
Caution : It is not a good way to use <span> between <ul> and <li>.

Categories