AngularJS ng-repeat rows/ul - javascript

I have a JSON array with various objects and I want to show these objects in the HTML using ng-repeat, but as follows:
<ul>
<li>object 1</li>
<li>object 2</li>
<li>object 3</li>
<li>object 4</li>
</ul>
<ul>
<li>object 5</li>
<li>object 6</li>
<li>object 7</li>
<li>object 8</li>
</ul>
Basically I want to show only 4 items per row (ul)
How can I do that?
Thanks!

You can use the filter limitTo
ng-repeat="item in items | limitTo:4"
UPDATE:This should work
<ul ng-repeat="item in arr" ng-if="$index%4==0">
<li ng-repeat="item in arr|limitTo:4:$index" >
{{item}}
</li>
</ul>
Plnkr

Try this sample out, In your controller:
var list = {'1','2','3','4','5','6','7','8','9','10','11','12','13','14','15'};
// Using lodash
var chunkedList = _.chunk(list, 4);
In your HTML:
<ul ng-repeat="items in chunkedList">
<li ng-repeat="item in items">Object {{item}}</li>
</ul>

Didn't test but give it a try:
<ul ng-repeat="n in getNumber(number)">
<li ng-repeat="item in items | limitTo:4:n*4">object 1</li>
</ul>
JS
$scope.number = Math.round(items.length/4);
scope.getNumber = function(num) {
return new Array(num);
}

The basic idea is to chunk your array to multidimensional array, and then ng-repeat it twice with nested structure.
If you would like to change the chunk number, you may just change it to any integers you like.
Live demo is here.
HTML
<body ng-app="myApp" ng-controller="MainCtrl as ctrl">
<ul ng-repeat-start="chunk in ctrl.chunkList">
<li ng-repeat="item in chunk">{{item}}</li>
</ul>
<hr ng-repeat-end/>
</body>
JS
angular
.module('myApp', [])
.controller('MainCtrl', [function() {
var self = this;
var listLength;
var groupNum;
var i;
self.list = [
'item1', 'item2', 'item3', 'item4', 'item5',
'item6', 'item7', 'item8'
];
listLength = self.list.length;
groupNum = (listLength % 4 === 0)? listLength / 4 : Math.ceil(listLength / 4);
self.chunkList = [];
for (i = 0; i < groupNum; i++) {
self.chunkList[i] = self.list.slice(i * 4, (i + 1) * 4);
}
}]);
Also notice that if you there's no need for other elements in the loop, you can just remove ng-repeat-start and ng-repeat-end and use ng-repeat directly instead.
<body ng-app="myApp" ng-controller="MainCtrl as ctrl">
<ul ng-repeat="chunk in ctrl.chunkList">
<li ng-repeat="item in chunk">{{item}}</li>
</ul>
</body>
Notes
This is approach is similar to #Shivas Jayram's, but without the need for underscore library.

Related

How can I read the Ids' on of div element for li tag

I want the Ids of all the li elements under div text.
<div id="editSortable">
<ul class="sortable-list ui-sortable">
<li id="id1">Test 1</li>
<li id="id2">Test 2</li>
<li id="id3">Test 3</li>
</ul>
</div>
I need output as id1, id2, id3 as a string.
You can use this. It will work for you.
var ids = [];
$("#editSortable").find("li").each(function () { ids.push(this.id); });
var result = ids.join(",");
Easily done by this way.
$("#editSortable ul li").each(function(){
console.log($(this).attr("id"));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editSortable">
<ul class="sortable-list ui-sortable">
<li id="id1">Test 1</li>
<li id="id2">Test 2</li>
<li id="id3">Test 3</li>
</ul>
</div>
use attr("id") to get the id of each li
You need to iterate each li to get each id using .each()
You can use .map() to get all id into an array
$('#editSortable').find('li').each(function() {
console.log(this.id) //more efficient way to get id of an element
//console.log($(this).attr("id"))//another way to get an id of element
})
var arr = $('#editSortable').find('li').map(function() {
return ($(this).attr("id"))
}).get();
console.log(arr)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editSortable">
<ul class="sortable-list ui-sortable">
<li id="id1">Test 1</li>
<li id="id2">Test 2</li>
<li id="id3">Test 3</li>
</ul>
</div>
while You need output as id1, id2, id3 as a string .. [way of ways] you can use .each() and save ids by += adding them to a variable join by comma except the last one
Demo
var Ids= '';
$('#editSortable .sortable-list li').each(function(){
var comma = $(this).index() + 1 == $('#editSortable .sortable-list li').length ? '' : ',';
Ids += this.id + comma;
});
console.log(Ids)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editSortable">
<ul class="sortable-list ui-sortable">
<li id="TEXT_1">Test 1</li>
<li id="TEXT_2">Test 2</li>
<li id="TEXT_3">Test 3</li>
</ul>
</div>

Click an array element, show the element with the same index of another array

I have a list of elements which is plotted via a ng-repeat and I am using a ng-click to get the index of the element of the array I am clicking on.
This is the html code:
<ul>
<li ng-repeat="period in periodPercentage" ng-click="getIndex('{{period}}')">
{{period}}
</li>
</ul>
And this is what is inside the controller:
$scope.periodPercentage = ['a', 'b', 'c', 'd'];
$scope.getIndex = function(period) {
console.log($scope.periodPercentage.indexOf(period));
};
In another part of the code, I am using again an ng-repeat to show the elements of another array with the same length.
<ul>
<li ng-repeat="ratio in ratioPercentage">
{{ratio}}
</li>
</ul>
Is there a way to show only the {{ratio}} with the same index of {{period}} via ng-show and hide the other ones?
Thanks in advance for your replies!
It may help you.
<div ng-app ng-controller="testrahul">
<ul>
<li ng-repeat="(i,period) in periodPercentage" ng-click="getindex(i)">
{{period}}
</li>
</ul>
function testrahul($scope) {
$scope.periodPercentage = ['a', 'b', 'c', 'd'];
$scope.getindex = function(i){
console.log(i);
}}
You could do that:
<li ng-repeat="period in periodPercentage" ng-click="getindex($index)">
{{period}}
</li>
and
<ul>
<li ng-repeat="ratio in ratioPercentage" ng-show="$index == findex">
{{ratio}}
</li>
</ul>
see updated fiddle
Something along the lines of:
<ul>
<li ng-repeat="period in periodPercentage" ng-click="setvariable($index)">
{{period}}
</li>
</ul>
<ul>
<li ng-repeat="ratio in ratioPercentage" ng-show="someVariable == $index">
{{ratio}}
</li>
</ul>
function setVariable(index){ $scope.someVariable = index;}
One solution is this:
$scope.periodPercentage = ['a', 'b', 'c', 'd'];
$scope.ratePercentage = ['arate', 'brate', 'crate', 'drate'];
$scope.rateShowPercentage = angular.copy($scope.ratePercentage);
$scope.update = function(index){
$scope.rateShowPercentage = [$scope.ratePercentage[index]];
}
In the HTML
<div ng-controller="GreetingController">
<ul >
<li ng-repeat="period in periodPercentage" ng-click="update($index)">
{{period}}
</li>
</ul>
<ul >
<li ng-repeat="rate in rateShowPercentage" >
{{rate}}
</li>
</ul>
</div>
working code here
Somehing like:
<ul>
<li ng-repeat="object in list" ng-click="openOther($index)">
{{object.data}}
</li>
</ul>
<ul>
<li ng-repeat="object in otherListToShow">
{{object.data}}
</li>
</ul>
and:
var otherList = [ some data ...]
var otherListToShow = []
openOther(index){
listToShow.push(otherList[index])
}
you need to give $index into ng-click
<ul>
<li ng-repeat="period in periodPercentage" ng-click="getIndex('{{$index}}')">
{{period}}
</li>

AngularJS nested ng-repeats with a single index?

Using Angular 1.0.7, how can I specify a single index for nested ng-repeats, so that each item on the inner arrays get's a consecutive index value? (i.e. 0, 1, 2, 3 and so on for all elements in all inner arrays)
To illustrate:
<ul>
<li ng:repeat="item in arr1">
<ul>
<li ng:repeat="child in item.children">{{consecutiveIndex++}}</li>
</ul>
</li>
</ul>
I tried to achieve it in the following manner:
var cindex= -1;
$scope.cindex= function () {
console.log('cindex', cindex);
return ++cindex;
};
HTML:
<ul>
<li ng:repeat="item in arr1">
<ul>
<li ng:repeat="child in item.children">{{index()}}</li>
</ul>
</li>
</ul>
I am getting quite exotic AngularJS errors using this (believe me, you don't wanna know).
I have also found out (following the console output), that even for an array with a mere 4 elements, ng-repeat hit my cindex() function over 80 times. Meaning instead of 0, 1, 2 and 3 - I got 84, 85, 86 and 87.
Any ideas?
You can't depend on your {{index()}} to be called a fixed amount of times. Whenever angular decides to dirty check a scope it will run all the bindings.
You can generate the value based on other indexes. Demo plunker
HTML
<body ng:controller="MainCtrl">
<ul>
<li ng:repeat="item in arr1">
<ul ng:init="parentIndex = $index">
<li ng:repeat="child in item.children">{{getConsecutiveIndex(parentIndex, $index)}}</li>
</ul>
</li>
</ul>
</body>
JS
app.controller('MainCtrl', function($scope) {
$scope.arr1 = [{children:[0,1,2,3]}, {children:[4,5]}, {children:[6,7,8]}];
$scope.getConsecutiveIndex = function(parentIndex, $index) {
var total = 0;
for(var i = 0; i < parentIndex; i += 1) {
total += $scope.arr1[i].children.length;
}
return total + $index;
}
});
The ngRepeat directive provides a special $index property which should suit your needs. It is zero-based and is exposed on the local scope of each template instance.
Try this:
<ul>
<li ng:repeat="item in arr1">
<ul>
<li ng:repeat="child in item.children">{{$index + 1}}</li>
</ul>
</li>
</ul>

Tabs and content into Array

I have two tabs like in this example:
<div id="tabs">
<ul>
<li>me</li>
<li>you</li>
</ul>
<div id="tabs-1">
<ul id="sortable1" class="connectedSortable ui-helper-reset">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
</div>
<div id="tabs-2">
<ul id="sortable2" class="connectedSortable ui-helper-reset">
<li class="ui-state-highlight">Item 5</li>
<li class="ui-state-highlight">Item 6</li>
<li class="ui-state-highlight">Item 7</li>
<li class="ui-state-highlight">Item 8</li>
<li class="ui-state-highlight">Item 9</li>
</ul>
</div>
</div>
I want to turn all of it into array's : me=>1,2,3,4,5 you=>5,6,7,8,9 any ideas? Thought maybe sortable1< li.index and give every li id but how to connect it with tab? Little help would be nice.
var obj = {};
$('#tabs > ul li a').each(function(i,ele) {
obj[$(ele).text()] = $.map($('li', $(ele).attr('href')), function(k, i) {
return $(k).text();
});
});
FIDDLE
var meid = $("#tabs a:contains(me)").attr("href");
var youid = $("#tabs a:contains(you)").attr("href");
var me = $("li", $(meid)).map(function() { return $(this).text() });
var you = $("li", $(youid)).map(function() { return $(this).text() });
The guys provided much more succinct answers. I didn't use $.map but here's what I wrote (might be useful for someone):
var tabs = $("#tabs");
var firstUL = tabs.first("ul");
var akeys = firstUL.find("a");
var valueDivs = tabs.children("div");
var dictionary = {};
$.each(akeys, function(index, value) {
var key = $(value).text();
dictionary[key] = $(valueDivs[index]).find("li");
});
//now dictionary contains all the <li> elements organized by the names in the first ul
//the beauty of JavaScript's dynamic features:
alert($(dictionary.me[0]).text()); //this will show Item 1
alert($(dictionary["you"][4]).text()); //this will show Item 9

AngularJS - how to use ng-repeat in different containers

I am trying to use ng-repeat to display the array of numbers. How to achieve this if I want it to be in different containers, for example in different ul? Also, each ul can only contain at most 2 li.
$scope.numbers = [1,2,3,4,5]
<div ng-controller="myController">
<ul>
<li>1</li>
<li>2</li>
</ul>
<ul>
<li>3</li>
<li>4</li>
</ul>
<ul>
<li>5</li>
</ul>
</div>
You should split that numbers array into chunks, then use a nested ng-repeat.
JavaScript:
var i, l = $scope.numbers.length;
$scope.chunks = [];
for ( i = 0; i < l; i += 2) {
$scope.chunks.push( $scope.numbers.slice(i, i + 2) );
}
HTML:
<div ng-controller="myController">
<ul ng-repeat="chunk in chunks">
<li ng-repeat="number in chunk">{{ number }}</li>
</ul>
</div>
See it here in action.

Categories

Resources