AngularJS - how to use ng-repeat in different containers - javascript

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.

Related

How to .querySelectAll() from .getElementsByTagNAme() html element?

Let suppose I have HTML like:
<html>
<body>
<ul>
<li>list</li>
<li>2</li>
<li>3</li>
</ul>
<div>div</div>
<p>something else</p>
</body>
</html>
and I want to get all UL elements:
var ul = document.getElementsByTagName("ul");
Now I would like to get all list elements:
var allListElements = ul.querySelectorAll("ul > li");
var ul = document.getElementsByTagName("ul");
var allListElements = ul.querySelectorAll("ul > li");
<ul>
<li>list</li>
<li>2</li>
<li>3</li>
</ul>
<div>div</div>
<p>something else</p>
However this is not working... but getElementById is working fine with querySelectAll(). So how to make to work HTMLcollection or NodeList with querySelectorAll()?
Just call querySelectorAll with the ul > li query string alone, on the document:
var allListElements = document.querySelectorAll("ul > li");
console.log(allListElements);
<ul>
<li>list</li>
<li>2</li>
<li>3</li>
</ul>
<div>div</div>
<p>something else</p>
If you already have an HTMLCollection that you need to effectively call querySelectorAll on, it'd be more complicated, you'd have to call querySelectorAll on each element in the HTMLCollection:
var uls = document.getElementsByTagName("ul");
var allListElements = [...uls].reduce((a, ul) => {
a.push(...ul.querySelectorAll('li'));
return a;
}, []);
console.log(allListElements);
<ul>
<li>list</li>
<li>2</li>
<li>3</li>
</ul>
<div>div</div>
<p>something else</p>
Two things to keep in mind:
getElementsByTagName returns a HTMLCollection object.
You must call Element query methods from an specific DOM node.
Your last JS line needs two changes:
First, you need to select the specific DOM node from the ul collection. Ex: ul[0]
Since you are querying the DOM from to the <ul> node you must exclude this element from the query. Ex: ul[0].querySelectorAll("li")
Please find the final edits below:
var ul = document.getElementsByTagName("ul");
var allListElements = ul[0].querySelectorAll("li");
console.log(allListElements)
<html>
<body>
<ul>
<li>list</li>
<li>2</li>
<li>3</li>
</ul>
<div>div</div>
<p>something else</p>
</body>
</html>
The ul > li elements are not contained inside the ul - they're on the document. Use that query string:
var allListElements = [...document.querySelectorAll("ul > li")];
console.log(allListElements);
<ul>
<li>list</li>
<li>2</li>
<li>3</li>
</ul>
<div>div</div>
<p>something else</p>

How to dynamically select last 5 list elements of an unordered list?

Using javascript, how do I select the last 5 list elements in an unordered list made with HTML?
You can use a css selector
element.querySelectorAll(":nth-last-child(-n+5)")
var list = document.querySelector('ul');
var children = list.children;
var len = children.length;
for(var i = len; i >= len-5; i--){
children[i-1].style.color = "red";
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<ul>

Append array to a class in javascript

I have an array in javascript called menuElm that has <ul> elements in it:
<ul id="1"></ul>
<ul id="2"></ul>
<ul id="3"></ul>
I have a page in HTML that has the following:
<ul id="menu">
<li class="menu-item"></li>
<li class="menu-item"></li>
<li class="menu-item"></li>
</ul>
I want to add the elements of menuElm to the HTML page so it would look like this:
<ul id="menu">
<li class="menu-item">
<ul id="1"></ul>
</li>
<li class="menu-item">
<ul id="2"></ul>
</li>
<li class="menu-item">
<ul id="3"></ul>
</li>
</ul>
I have tried the following, but the <ul> elements just wont show up in the page nor in the code:
function CreateMenu() {
var menuElm;
var k = 0;
menuElm = createElm("ul");
menuElm.id = ++k;
for (var i = 0; i < menuElm.length; ++i) {
document.getElementsByClassName("menu-item")[i].appendChild(menuElm[i]);
}
}
I am new with JavaScript, what am I doing wrong?
menuElm.length
The ul element doesn't have a length, so you are looping from 0 to 0, which is 0 iterations.
menuElm = createElm("ul");
This function isn't defined. You need document.createElement('ul');
menuElm = createElm("ul");
menuElm.id = ++k;
You appear to be creating one list item, and then changing its ID and appending it multiple times.
You need a new list item each time you go around the loop.
appendChild(menuElm[i]);
You've been treating menuElm as an element previously. It isn't an array, [i] makes no sense here.
$("#menu").find('li').each(function(i){
$(this).append(menuElm[i]);
});
/* if you want to use jquery here is the code to append */

How to copy selector id into li selector class?

JS
$(document).ready(function(){
groups = $('[id^=id_2_class_]');
$.each(groups, function(key, group) {
inputs = $(group).attr('id');
alert(inputs);
$()
});
})
HTML
<div id="id_2_class_385">id_2_class_385</div>
<div id="id_2_class_386">id_2_class_386</div>
<div id="id_2_class_387">id_2_class_387</div>
<div id="id_2_class_388">id_2_class_388</div>
<ul class="flex-control-nav flex-control-paging">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
Above is my current code, how can I transfer the selector id into another element's class using jquery?
The result should look like the below
<div id="id_2_class_385">id_2_class_385</div>
<div id="id_2_class_386">id_2_class_386</div>
<div id="id_2_class_387">id_2_class_387</div>
<div id="id_2_class_388">id_2_class_388</div>
<ul class="flex-control-nav flex-control-paging">
<li class="id_2_class_385">1</li>
<li class="id_2_class_386">2</li>
<li class="id_2_class_387">3</li>
<li class="id_2_class_388">4</li>
<li class="id_2_class_389">5</li>
</ul>
You already have the IDs, just need to add them to the list items like so
$(document).ready(function () {
groups = $('[id^=id_2_class_]');
groups.each(function (index) {
inputs = $(this).attr('id');
$('.flex-control-nav').find('li').eq(index).addClass(inputs);
});
});
http://jsfiddle.net/jvqq23kv/
Basically just go through each li and add the class
Here you go:
This goes through each one and creates an <li> so it doesn't matter how many you have. It creates dynamically.
$(function(){
$('[id^=id_2_class_]').each(function(){
$('ul.flex-control-nav.flex-control-paging').append("<li id='"+this.id+"'></li>");
});
});
http://jsfiddle.net/pLvopvqL/

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>

Categories

Resources