I am using ng-repeat to iterate over an array to generate <li>. But i want to stack every 2 li into div.
<li ng-repeat="item in items">{{item.name}}</li>
I want the output to be like this:
<ul>
<div>
<li>A</li>
<li>B</li>
</div>
<div>
<li>C</li>
<li>D</li>
</div>
</ul>
How should i achieve this with ng-repeat?
Thanks in advance for any help.
Although it is invalid to put div inside ul but to illustrate. i have made a function to split your array into group of 2 element array contained in wrapper array
Or You can also use splice method
Working Demo 1
angular.module('testApp',[]).controller('testCtrl', function($scope) {
$scope.items=['1','2','3'];
$scope.groupByTwo = function (array)
{
var newarray =[];
index=0;
for(a=0;a<array.length;a++){
if(a==0 || a%2==0){
newarray[index]=[];
newarray[index].push(array[a]);
}else{
newarray[index].push(array[a]);
}
if(a!=0)
index++;
}
return newarray;
}
$scope.items=$scope.groupByTwo($scope.items);
});
div {
background:pink;
border:1px dotted black;
margin-top:15px;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="testApp" ng-controller="testCtrl">
<ul>
<div ng-repeat="item in items">
<li ng-repeat="i in item">{{i}}</li>
</div>
</ul>
Working Demo 2
You can also use splice method
angular.module('testApp',[]).controller('testCtrl', function($scope) {
$scope.items=['1','2','3'];
var i,j,temparray=[],chunk = 2;
for (index=0,i=0,j=$scope.items.length; i<j; i+=chunk,index++) {
temparray [index]= $scope.items.slice(i,i+chunk);
}
$scope.items =temparray;
});
div {
background:pink;
border:1px dotted black;
margin-top:15px;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="testApp" ng-controller="testCtrl">
<ul>
<div ng-repeat="item in items">
<li ng-repeat="i in item">{{i}}</li>
</div>
</ul>
Apply ng-repeat on ul and li will act as a template which will be generated for each item.
Ex :
<ul ng-repeat="item in items">
<li>{{item.name}}</li>
</ul>
This will result in
<ul>
<li>name1</li>
<li>name2</li>
<li>name2</li>
</ul>
If you have a collection consisting of 10 items , you can split them in multiple collections each of size 2 and then apply ng-repeat with each collection on div to get the output you want.
Related
Iam trying to make thymeleaf page into angular js .Below is my code
</ul>
<ul class="list">
<span class="columns">
<li ng-repeat="item in list">{{item.name}}</li>
</span>
</ul>
Each span should have 9 elements. after that another span should be open. But right now all items are in single span.
An <li> element can only be a child of a <ul> or <ol>.
The only children a <ul> can have are <li>
… so you can't group them with span elements.
If you want to organise them in groups of 9 for rendering purposes, then consider using CSS grid (and setting up the ul as a grid with 9 columns).
ul {
list-style: none;
display: grid;
grid-template-columns: repeat(9, 1fr);
}
li:nth-child(odd) {
background: #afa;
}
<ul><li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x<li>x</ul>
The <span> element is not valid content for <ul> elements.
From the Docs:
The HTML <ul> element represents an unordered list of items, typically rendered as a bulleted list.
Permitted content: zero or more <li> elements, which in turn often contain nested <ol> or <ul> elements.
For more information, see
MDN HTML Reference: <ul> Element
In your controller, you can make a new array out of list:
let newList = [];
let tempList = [];
for (let i=0; i<list.length; i++) {
tempList.push(list[i]);
if (i%9 === 0) {
newList.push(tempList);
tempList = [];
}
}
newList will be like this:
[
[
obj1,
obj2,
obj3,
obj4,
obj5,
obj6,
obj7,
obj8,
obj9,
],
[
obj10,
obj11,
obj12,
obj13,
obj14,
obj15,
obj16,
obj17,
obj18
],
[
obj19,
obj20,
obj21,
obj22,
obj23,
obj24,
obj25,
obj26,
obj27
],
so on...
]
and then you can use this newly formed array to suit your purpose
<span ng-repeat="item in list" class="columns">
<li ng-repeat="item2 in item">{{item2.name}}</li>
</span>
However, as many people have mentioned here, you should be using <ul> to group your list element like so:
<div class="columns">
<ul ng-repeat="item in list" class="list">
<li ng-repeat="item2 in item">{{item2.name}}</li>
</ul>
</div>
I haven't tested the code but you should get the idea.
I am creating this grocery list application with Angular4, so I need the user to be able to click on an item and it will be added to the bookmarked section.
I used Jquery to access the innerHTML of the li when we hover over it, take the value and add it into the bookmark array, but the innerHTML keeps returning "undefined".
javascript:I used this bit to get the innerHTML
$('li').hover(function(){
console.log($(this).innerHTML);
});
html:I've used *ngfor to spit out all the list items
<div class="col-m-6">
<h3 class="text-primary">All Items</h3>
<ol>
<li class="listItem" *ngFor="let g of groceries">{{g}}</li>
</ol>
</div>
In the console it keeps showing "undefined", please help. TIA
Avoid using Jquery or any other way of direct DOM manipulation while developing SPA.
Try following
Template
<li class="listItem" *ngFor="let g of groceries" (click)="onClick(g.id)">
{{g}}
</li>
Component
onClick(id) {
//add to bookmark
}
Solution1: Use html() jQuery.
Stack Snippet
$('li').hover(function(){
console.log($(this).html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-m-6">
<h3 class="text-primary">All Items</h3>
<ol>
<li class="listItem" *ngFor="let g of groceries">{{g}}</li>
</ol>
</div>
Solution2: Use this.innerHTML.
Stack Snippet
$('li').hover(function(){
console.log(this.innerHTML);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-m-6">
<h3 class="text-primary">All Items</h3>
<ol>
<li class="listItem" *ngFor="let g of groceries">{{g}}</li>
</ol>
</div>
you have need to use jQuery html() method to gett innerHTML.
So, use the following:
$('li').hover(function(){
console.log($(this).html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-m-6">
<h3 class="text-primary">All Items</h3>
<ol>
<li class="listItem" *ngFor="let g of groceries">{{g}}</li>
</ol>
</div>
For jQuery to work on dynamic elements you should be doing it this way
$(document).on('hover', 'li', function(){
console.log($(this).innerHTML);
});
I want to list an item inside a specific key using a filter. Now listing like this.
Sanal
Jin
John
Tim
Jeff
Sam
John
Tim
I want like this using a filterJeffSam
Here is the Fiddle
function testCtrl($scope) {
$scope.items = {"id":"B716","day":8,"di":{"type":"normal","one":[{"name":"Sanal","age":"18"},{"name":"Jin","age":"25"}],"two":[{"name":"Jeff","age":"55"},{"name":"Sam","age":"32"}],"three":[{"name":"John","age":"34"},{"name":"Tim","age":"39"}]}};
}
<div ng-app="" ng-controller="testCtrl">
<ul>
<li ng-repeat="val in items.di">
<ul>
<li ng-repeat="value in val">{{value.name}}</li>
</ul>
</li>
</ul>
</div>
in your ng repeat change it as
<li ng-repeat="value in val | filter: val.name='jeff'">{{value.name}}</li>
I have used name you can use the value that you want ot test
I am trying to iterate over an array using ng-repeat to display in a list. The number of records to display should be equal to the length of a second array.
<ul>
<li ng-repeat="item in firstArray"></li>
</ul>
var firstArray = ["a","b","c","d","e","f"]
var secondArray = ["x","y","z"]
The expected result for the above example :
var output = ["a","b","c"]
Since the length of secondArray is 3, the number of li elements would be 3 with the first three values from firstArray.
Should i use filter? I am using angularjs.
Thanks
The simplest solution is to use limitTo
<ul>
<li ng-repeat="item in firstArray | limitTo:secondArray.length">{{item}}</li>
</ul>
http://plnkr.co/edit/LWh1uqNPxTy09u3MP677?p=preview
<ul>
<li ng-repeat="item in firstArray" ng-if=" $index < secondArray.length "></li>
</ul>
Use the above code, it will work
You can use AngularJs filter limitTo in ng-repeat. Refer to the below example:
At angular application side:
var app = angular.module('sampleapp', [])
app.controller('samplecontrol', function ($scope) {
$scope.firstArray = ["a","b","c","d","e","f"]
$scope.secondArray = ["x","y","z"]
});
In your view:
<ul>
<li ng-repeat="item in firstArray | limitTo:secondArray.length">{{item}}</li>
</ul>
Maybe you should use $index to test if it has to be displayed :
<ul >
<li ng-repeat="item in firstArray" ng-if="$index < secondArray.length()" > </li>
</ul>
Just loop over your second array and access the items of the first array using firstArray[$index].
angular.module('myApp', [])
.controller('myCtrl', function ($scope) {
$scope.firstArray = ["a","b","c","d","e","f"];
$scope.secondArray = ["x","y","z"];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul>
<li ng-repeat="i in secondArray">
{{firstArray[$index]}}
</li>
</ul>
</div>
</div>
I have a set of JSON data that I would like to display in a nested list:
The JSON comes in the following format:
["Item 1", "Item 2", "Item 3", ["Nested Item 1", "Nested Item 2"]]
The html should be:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>
<ul>
<li>Nested Item 1</li>
<li>Nested Item 2</li>
</ul>
</li>
</ul>
I don't have control of the JSON, and it may be deeper than 2 levels.
Of course, I tried this:
<ul>
<li ng-repeat="item in data">{{item}}</li>
</ul>
but it doesn't work because for nested items, it simply displays the json.
How can I achieve nested lists in AngularJs?
Fiddle: http://jsfiddle.net/m7ax7tsa/
Have a look at this nice blog post that has a complete example at the end. In short you need to build nested directives, where inner directive will have recursive call to outer directive:
<body>
<div ng-controller="IndexCtrl">
<collection collection='tasks'></collection>
</div>
</body>
angular.module('APP', [])
.directive('collection', function () {
return {
...
template: "<ul><member ng-repeat='member in collection' member='member'></member></ul>"
}
})
.directive('member', function ($compile) {
return {
...
template: "<li>{{member.name}}</li>",
link: function (scope, element, attrs) {
if (angular.isArray(scope.member.children)) {
element.append("<collection collection='member.children'></collection>");
$compile(element.contents())(scope)
}
}
}
I found a solution thanks to zsong and Blackhole.
Resulting HTML:
<div ng-app="testApp">
<div ng-controller="TestCtrl">
<script type="text/ng-template" id="/nestedList.html">
<ul>
<li ng-repeat="item in data">
<div ng-switch="isString( item )">
<div ng-switch-when="true">{{item}}</div>
<div ng-switch-when="false">
<!-- Recursive template!! -->
<div ng-include="'/nestedList.html'" ng-init="data = item">
</div>
</div>
</div>
</li>
</ul>
</script>
<div ng-include="'/nestedList.html'"></div>
</div>
</div>
I used a recursive template which included itself. It borrows heavily on the answer of Unknown number of sublists with AngularJS. In addition, I had to add the following code to the controller:
$scope.isString = function (item) {
return typeof item === "string";
};