Angular ng-repeat inside ng-repeat loop count - javascript

I have the following code:
<div ng-repeat="list in [[1,2,3,4], [1,2,3,4]] track by $index">
<div id="{{counter}}" ng-repeat="listChild in list track by $index">
{{listChild}}
</div>
</div>
I want to make counter be the number of the element but relative to the whole parent array. How can I make it work so the divs count continuously and not as two individual arrays. to be something like this:
<div>
<div id="1">
{{listChild}}
</div>
<div id="2">
{{listChild}}
</div>
<div id="3">
{{listChild}}
</div>
<div id="4">
{{listChild}}
</div>
</div>
<div>
<div id="5">
{{listChild}}
</div>
<div id="6">
{{listChild}}
</div>
<div id="7">
{{listChild}}
</div>
<div id="8">
{{listChild}}
</div>
</div>

The code below accounts for varied array lengths within the parent array. $scope.precedingCount tracks the rolling total up to the start of a given inner array
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.counter = 0;
$scope.data = [[1,2,3,4], ['a','b','c','d', 'e', 'f'], ['any', 'other', 'data', 'needed']];
$scope.precedingCount = {
0: 0
};
for(var i=1; i<$scope.data.length; i++) {
$scope.precedingCount[i] = $scope.precedingCount[i-1] + $scope.data[i-1].length
}
$scope.combinedIndex = function(oIndx, iIndx) {
return $scope.precedingCount[oIndx] + iIndx
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-repeat="list in data track by $index" ng-init="outerIndex = $index">
<div id="{{combinedIndex(outerIndex, $index)}}" ng-repeat="listChild in list track by $index">
{{listChild}} - {{counter}} - {{outerIndex}} - {{$index}} - {{combinedIndex(outerIndex, $index)}}
</div>
</div>
<br />
<br />
<div>
The count of the previous indices: {{precedingCount}}
</div>
</div>

You could use an external variable that will keep the number of listChild
<div ng-repeat="list in [[1,2,3,4], [1,2,3,4]] track by $index">
<div id="{{counter}}" ng-repeat="listChild in list track by $index" ng-init="counter += 1">
{{listChild}}
</div>
</div

Related

how to ADD class in every to div using loop

This is my structure I want to add odd even class in every two divs so how can I achieve this structure using JavaScript loop i tried everything but i got nothing I am learning JavaScript loop so anyone please help me with this
var i = 0;
$('.CollectionInner__Products .Grid__Cell .ProductItem').each(function(i) {
var index = 0;
if (index % 3 == 0) {
$(this).addClass("odd");
}
});
<div class="custompsps">
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
</div>
<div class="custompsps">
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
</div>
I want this structure:
i want this stucture
<div class="custompsps">
<div class="ProductItem even">
</div>
<div class="ProductItem even">
</div>
<div class="ProductItem odd">
</div>
<div class="ProductItem odd">
</div>
</div>
<div class="custompsps">
<div class="ProductItem even">
</div>
<div class="ProductItem even">
</div>
<div class="ProductItem odd">
</div>
<div class="ProductItem odd">
</div>
</div>
$('.CollectionInner__Products .Grid__Cell .ProductItem').each(function(index, element) {
$(element).addClass(index & 2 ? "even" : "odd");
});
& is a bitwise "and". index & 2 would be 0 for index 0 and 1, and 2 for index 2 and 3, alternating like this. 0 is falsy and non-0 is truthy. (Your use of "even" and "odd" seem backwards, but I've followed your use.)
jQuery's .each accepts a callback that can take both an index and an element argument.

Best way to loop the angular flex layout with two rows?

I would like to know how to do the ngFor with two rows in angular flex layout.
<div *ngFor="let item of items">
<div class="container" fxLayout fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap.xs="0">
<div class="item item-1" fxFlex="50%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
<div class="item item-2" fxFlex="50%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
<div class="container" fxLayout fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap.xs="0">
<div class="item item-3" fxFlex="100%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
</div>
Here its looping but each time its printing 3 values for every index. I would like to print index 0 value of first column, index 1 on second column and index 2 value on second row.
I've created for you an example on stackblitz, based on your requirements.
The correct way would be :
<div class="container" fxLayout="row wrap" fxLayoutAlign="center" fxLayoutGap.xs="0">
<!-- you can use ngClass to manage 'item-1' or 'item-2' style -->
<div class="item" fxFlex="50%" *ngFor="let item of items">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
The wrap/nowrap property on the fxLayout directive does everything, because childs are set with fxFlex="50%".
I put out fxLayout.xs to render it correctly on stackblitz.
Here is #angular/flex-layout documentation
Hope it helps ;-)
The "wrap" parameter in the "fxLayout" is used to wrap the child content with the help of "fxFlex"

two $index in various ng-repeat

Can I have two ng-repeat with two "track by index". For example:
<div ng-repeat="car in cars track by $index">
<div ng-repeat="wheel in car track by $index">
</div>
</div>
The first is $index, is it broke in second ng-repeat?
You can do it like this instead
<div ng-repeat="(carIndex,car) in cars">
<div ng-repeat="(wheelIndex,wheel) in car">
</div>
</div>

angular ng repeat disable all items except first item

I have a list of items. Each item is in div. i want to show only first item enable except others shows disabled.
AngularJs
angular.module('example', [])
.controller('myCtrl', function Ctrl($scope) {
$scope.items = [1,2,3];
});
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="example" ng-controller="myCtrl">
<div ng-repeat="item in items">{{item}}</div>
</div>
simply by using $first attribute:
<div ng-app="example" ng-controller="myCtrl">
<div ng-repeat="item in items" ng-disabled="!$first">{{item}}</div>
</div>
beware: ng-disabled works with form elements. see documentation for details.
you can do this using $first.
angular.module('example', [])
.controller('myCtrl', function Ctrl($scope) {
$scope.items = [1,2,3];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="example" ng-controller="myCtrl">
<div ng-repeat="item in items"><span ng-if="$first">{{item}}</span>
<span ng-if="!$first">do whatever you want with this item {{item}} </span>
</div>
</div>
Try this snippet.
angular.module('example', [])
.controller('myCtrl', function Ctrl($scope) {
$scope.items = [1,2,3];
});
.disable {
color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="example" ng-controller="myCtrl">
<b>First way</b>
<div ng-repeat="item in items track by $index">
<input ng-disabled="$index != '0'" type="text" value="do whatever you want with this item {{item}}"/>
</div>
<br/>
<b>Second way</b>
<div ng-repeat="item in items">
<input ng-disabled="!$first" type="text" value="do whatever you want with this item {{item}}"/>
</div>
<br/>
<b>Third way</b>
<div ng-repeat="item in items">
<span ng-class="{'disable': !$first}">do whatever you want with this item {{item}}</span>
</div>
</div>
<div ng-app="example" ng-controller="myCtrl">
<div ng-repeat="item in items" ng-class='{disable:!$first}' >{{item}}</div>
</div>
Using disable class we can only apply disable css if someone did change from console then it will break so i did as followed
<div ng-app="example" ng-controller="myCtrl">
<div ng-repeat="item in items" ng-class="{'disabled-me': !($index==0)}">
<span ng-click="($index!=0) ? false : xyx(item)">{{item}}</span></div>
</div>
And in css
.disabled-me,.disabled-me span{color: #777 !important;cursor: default;}

AngularJS data binding checkboxes to object if checked

I have a JSON object which I am repeating with ng-repeat, the keys are strings, and the values are an array. I am listing each of the values as a checkbox. I would like to create a second object which contains a list of only the checkboxes that are checked. I want to preserve the structure of the object with keys and values.
I'm unsure how to bind this to a model properly so that the structure is preserved.
http://jsfiddle.net/NDFc2/3/
This is my HTML
<h3 >Dynamic data binding in AngularJS</h3>
<div ng-app ng-controller="Controller" class="container">
<h4>Inputs</h4>
<ul ng-repeat="(parent, values) in inputs">
<span>{{parent}} : </span>
<li ng-repeat="value in values"><label>{{value}}
<input type="checkbox" ng-model="output[parent]" ng-checked="output[parent]" value="value" >
</input></label>
</li>
</ul>
<h4>Outputs</h4>
<ul ng-repeat="(key,value) in inputs">
<li>
{{key}} : {{output[key]}}
</li>
</ul>
</div>
and my JS
function Controller($scope) {
$scope.output = {};
$scope.inputs = {'category': ['one','two','three'], 'color':['blue','green']};
}
Is there some simple way to do this? I have the feeling that I'm missing something minor and this will all work nicely.
My examples have your angular logic in the recommended syntax (non-global). There were also several issues with your markup that I have corrected.
In this example, ng-model="x" is a placeholder that I don't use, but ng-model must be present or an error is thrown. I am using ng-change to handle the link between the checkboxes and $scope.outputs.
Live demo here (click).
Markup:
<div ng-app="myApp" ng-controller="myCtrl">
<h3 >Dynamic data binding AngularJS</h3>
<h4>Inputs</h4>
<ul>
<li ng-repeat="(typeKey, typeVal) in inputs">
<span>{{typeKey}} : </span>
<ul>
<li ng-repeat="value in typeVal">
<label>{{value}}
<input
type="checkbox"
ng-model="x"
ng-change="setOutput(typeKey, $index, value)"
>
</label>
</li>
</ul>
</li>
</ul>
<h4>Outputs</h4>
<ul ng-repeat="(key,value) in inputs">
<li>{{key}} : {{outputs[key]}}</li>
</ul>
</div>
JavaScript:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.outputs = {};
$scope.inputs = {
'category': ['one','two','three'],
'color':['blue','green']
};
$scope.setOutput = function(typeKey, $index, value) {
$scope.outputs[typeKey] = $scope.outputs[typeKey] || [];
$scope.outputs[typeKey][$index] = value;
};
});
Another Solution
Live demo here (click).
First, I used ng-init to dynamically add the first-level properties from inputs to outputs. Then you just needed to set your ng-model and ng-checked properties to the correct location in outputs.
Markup:
<div ng-app="myApp" ng-controller="myCtrl">
<h3 >Dynamic data binding AngularJS</h3>
<h4>Inputs</h4>
<ul>
<li
ng-repeat="(typeKey, typeVal) in inputs"
ng-init="outputs[typeKey] = outputs[typeKey] || {}">
<span>{{typeKey}} : </span>
<ul>
<li ng-repeat="value in typeVal">
<label>{{value}}
<input
type="checkbox"
ng-model="outputs[typeKey][value]"
ng-checked="outputs[typeKey][value]"
value="outputs[typeKey][value]"
>
</label>
</li>
</ul>
</li>
</ul>
<h4>Outputs</h4>
<ul ng-repeat="(key,value) in inputs">
<li>{{key}} : {{outputs[key]}}</li>
</ul>
</div>
JavaScript:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.outputs = {};
$scope.inputs = {
'category': ['one','two','three'],
'color':['blue','green']
};
});
You need to bind to the value for the parent, as checkboxes don't work like that. Here's an example:
<h3 >Dynamic data binding in AngularJS</h3>
<div ng-app ng-controller="Controller" class="container">
<h4>Inputs</h4>
<ul ng-repeat="(parent, values) in inputs">
<span>{{parent}} : </span>
<li ng-repeat="value in values"><label>{{value}}
<input type="checkbox" ng-model="output[parent][value]" ng+checked="output[parent][value]" value="value" >
</input></label>
</li>
</ul>
<h4>Outputs</h4>
<ul ng-repeat="(key,value) in inputs">
<li>
{{key}} : {{output[key]}}
</li>
</ul>
</div>
And in the controller create the keys beforehand
function Controller($scope) {
$scope.output = { 'category': {}, color: {} };
$scope.inputs = {'category': ['one','two','three'], 'color':['blue','green']};
}
jsfiddle: http://jsfiddle.net/5eeVc/
Have a look at this plunk, i have handled two different scenarios. Just sharing it as a knowledge article
Plunk
<h3>First Scenario <small>Handling JSON source </small></h3>
<div class="container-fluid">
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<h4>Available options</h4>
<div ng-repeat="item in itemList">
<mark>{{item.name}}</mark>
<input type="checkbox" ng-model="modelContainer[$index].checked" />
</div>
</div>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<h4 class="text-success">Selected options</h4>
<ul>
<li ng-repeat="item in modelContainer | filter: {checked:true}">
{{item.item.name}} X
</li>
</ul>
</div>
</div>
</div>
<br>
<p class="text-danger">itemList</p>
<code>{{itemList}}</code>
<br>
<br>
<p class="text-danger">modelContainer</p>
<code>{{modelContainer}}</code>
<hr>
<h3>Second Scenario <small>Handling map Source </small></h3>
<div class="container-fluid">
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<h4>Available options</h4>
<div ng-repeat="item in Maplist">
<mark>{{item}}</mark>
<input type="checkbox" ng-model="modelContainer1[$index].checked" />
</div>
</div>
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">
<h4 class="text-success">Selected options</h4>
<ul>
<li ng-repeat="item in modelContainer1 | filter: {checked:true}">
{{item.name}} X
</li>`enter code here`
</ul>
</div>
</div>
</div>

Categories