Unable to iterate - javascript

I have got issue when I work out on the ng-repeat directive, since I am a beginner , unable to resolve it on my own.
var myModule = angular.module("myFirst",[]);
myModule.controller("cont", function($scope){
var employees = [
{name: "Manju", age :"23", rank:"2"},
{name: "SivaSankari", age :"23", rank:"1"},
{name: "Gayathri", age :"23", rank:"1"},
];
$scope.employees = employees;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myFirst">
<head>
<title> My workout|ngRepeat
</head>
<body>
<div ng-controller="cont">
<table>
<thead>
<th>Name</th>
<th>Age</th>
<th>Postions</th>
</thead>
<tbody>
<tr ng-repeat="x in employees">
<td>{{employees.name}}</td>
<td>{{employees.age}}</td>
<td>{{employees.position}}</td>
</tr>
</tbody>
</table>
</div>
</body>
<html>
Also I have doubt on key that is x. Is ok to give any key value ?
Can any one please help me to resolve and understand ?
Thanks.

First
You have to use x instead of employees because employees is your array and x the current item
Second
You were trying to access the property position that is not existing inside your object. You should call rank
var myModule = angular.module("myFirst", []);
myModule.controller("cont", function($scope) {
var employees = [{
name: "Manju",
age: "23",
rank: "2"
}, {
name: "SivaSankari",
age: "23",
rank: "1"
}, {
name: "Gayathri",
age: "23",
rank: "1"
}, ];
$scope.employees = employees;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myFirst">
<body>
<div ng-controller="cont">
<table>
<thead>
<th>Name</th>
<th>Age</th>
<th>Postions</th>
</thead>
<tbody>
<tr ng-repeat="x in employees">
<td>{{x.name}}</td>
<td>{{x.age}}</td>
<td>{{x.rank}}</td>
</tr>
</tbody>
</table>
</div>
</body>
<html>

It should be
<td>{{x.name}}</td>
<td>{{x.age}}</td>
<td>{{x.position}}</td>

You should access the properties of x not the employee array
<td>{{x.name}}</td>
<td>{{x.age}}</td>
<td>{{x.position}}</td>

You're defining x as the employee you're iterating over. So the repeat part should be:
<tr ng-repeat="x in employees">
<td>{{x.name}}</td>
<td>{{x.age}}</td>
<td>{{x.position}}</td>
</tr>

When you used ng-repeat="x in employees" it means you're saying on each iterate assign the item to x, that's why you can't use any other variable other than x.
<td>{{x.name}}</td>
<td>{{x.age}}</td>
<td>{{x.position}}</td>

I didn't understand your ngRepeat in the title tag, but your table declaration makes little sense.
<tr ng-repeat="x in employees">
means that for every element (henceforth to be referred to as x) in the array employees, repeat this element viz. table row. (Make sure that's what you really want to do)
Therefore, inside your td, you gotta write -
<td>{{x.name}}</td>
Also I have doubt on key that is x. Is ok to give any key value ?
If you mean to say whether you can call x anything else then yes, you can.
E.g.
<tr ng-repeat="singleEmployee in employees">
<td>{{singleEmployee.name}}</td>

You have issue in ng-repeat, it should be x.name not employess.name
<tr ng-repeat="x in employees">
<td>{{x.name}}</td>
<td>{{x.age}}</td>
<td>{{x.position}}</td>
</tr>

Related

Applying rowspan in table with ng-repeat angularjs

I have array like this
$scope.orderno=[
{"orderno":1254,"weight":25875,"group":5},
{"orderno":56787,"weight":25875,"group":5},
{"orderno":567,"weight":25875,"group":3},
{"orderno":123254,"weight":25875,"group":3}
];
now i want to show in html like below
I tried but i can't.I attached my tried code below.
<div ng-app>
<table ng-controller="MainCtrl">
<thead>
<div>
<tr>
<td>orderno</td>
<td>weight</td>
<td rowspan={{orderwt}}>group</td>
</tr>
</div>
</thead>
<tbody ng-repeat="item in orderno">
<tr>
<td></td>
<td></td>
<td rowspan="{{orderno.length}}">{{item.group}}</td>
</tr>
<tr>
<td>{{item.orderno}}</td>
<td>{{item.weight}}</td>
</tr>
</tbody>
</table>
</div>
i tried but i can't find correct answer
The first thing you should do is transform your data into a format that's easier to iterate over. For example, you could use array.reduce() to help you create a new object that's keyed by group number. Then you can iterate over this object to create your table.
See example snippet with comments below:
// This is your original data array
let arr = [{
"orderno": 1254,
"weight": 25875,
"group": 5
},
{
"orderno": 56787,
"weight": 25875,
"group": 5
},
{
"orderno": 567,
"weight": 25875,
"group": 3
},
{
"orderno": 123254,
"weight": 25875,
"group": 3
}
], // Use reduce and Object.create to make a new object keyed by group number
result = arr.reduce(function(r, a) {
r[a.group] = r[a.group] || [];
r[a.group].push(a);
return r;
}, Object.create(null));
let app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.groups = result;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table border="1">
<thead>
<td>Group</td>
<td>Order No</td>
<td>Weight</td>
</thead>
<tbody ng-repeat="(key, value) in groups"> <!-- Outer loop -->
<tr ng-repeat="group in value"> <!-- Inner loop -->
<td ng-if="$index == 0" rowspan="{{ value.length }}">{{ group.group }}</td>
<!-- the above is so we only add the rowspan once -->
<td>{{ group.orderno }}</td>
<td>{{ group.weight }}</td>
</tr>
</tbody>
</table>
</div>

JSON Object in Object refer in HHML

i have a JSON-datafile of typ: trip. In trip is a object: driver (with name, id etc..).
{
"id": "1",
"gpsStart": "N50.418716° , E006.750000°",
"gpsEnd": "N50.318516° , E006.750000°",
"tripBuinsness": true,
"startOdometer": 25698,
"endOdometer": 25700,
"wayPoints": [
"N50.418716° , E006.750000°",
],
"driver": [{
"name": "Theo"
}]
}
How can I refer the driver name in html?
<tbody>
<tr *ngFor="let trip of trips">
<td>{{trip.projectName}}</td>
<td>{{trip.driver}}</td>
</tr>
</tbody>
You do not need ngFor over trip since its an Object, change it over trip.driver which is an array of Objects,
<tbody>
<tr *ngFor="let driver of trip.driver">
<td>{{driver.name}}</td>
</tr>
</tbody>
If you want the only the first driver you can access him through the 0th index:
<tbody>
<tr *ngFor="let trip of trips">
<td>{{trip.projectName}}</td>
<td>{{trip.driver[0].name}}</td>
</tr>
</tbody>
But if you want all of the drivers add another ngFor loop to your template:
<tbody>
<tr *ngFor="let trip of trips">
<td>{{trip.projectName}}</td>
<td>
<span *ngFor="let d of trip.driver">{{d.name}} </span>
</td>
</tr>
</tbody>
'driver' is an array. I think you can access the name by doing trip.driver[0].name or iterating over trip.driver.

How to change the key name for each element in array using ng-repeat

I have an array of object, which I am showing in table through ng-repeat.
<table>
<thead>
<tr>
<th ng-repeat="col in columnHeaders">{{col}}</th> //['Name', 'Bank Name','Code', 'Type','Status'];
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data track by $index">
<td ng-repeat="col in columnRows">{{row[col]}}</td> //['name', 'bankName','code', 'type','isActive'];
</tr>
</tbody>
</table>
I am using ng-repeat in <th></th> and <td></td> too. But my columnHeaders name and row property(columnRows) names are different. I want to change my property name to same as column header name while using ng-repeat on <td></td> tag.
I am thought of using alias 'as' but not sure how to use it for each element.
Can anyone help me?
Instead of using two columnRows and header rows(array of string) , make a single array of keyHash(column data key and header string )
check running fiddle for this
and code be like :-
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<table>
<thead>
<tr>
<th ng-repeat="col in columnRows">{{col.displayStr}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data track by $index">
<td ng-repeat="col in columnRows">{{row[col.key]}}</td>
</tr>
</tbody>
</table>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.columnRows = [
{key:'name',displayStr:'Name'},
{key:'bankName',displayStr:'Bank Name'},
{key:'code',displayStr:'Code'},
{key:'type',displayStr:'Type'},
{key:'isActive',displayStr:'Status'}
]
$scope.data = [
{
name:'James',
bankName:'RBL',
code:'1234',
type:'Saving',
isActive:true
},
{
name:'Riyan',
bankName:'DSB',
code:'1234',
type:'Current',
isActive:true
}
];
});
</script>
</body>
</html>

Html/Angular toggle table rows to show hidden a table

I am completely new to angular, I need to create a table. The data array is as-follows:-
data = [{rollno: 1,name: 'abc',subject: 'maths'},
{rollno: 4,name: 'xyz',subject: 'history'},
{rollno: 2,name: 'pqr',subject: 'history'}
];
I want to create a table with some summary rows based on this data and then when I click the expand button the sub-rows should appear beneath that summary-row indicating the actual data.
For example:-
Expand/Collapse | No of Students | Subject
click here 1 Maths
click here 2 History
When I toggle the expand/collapse button on the second row for example I want actual rows to appear like this beneath it:-
Expand/Collapse | No of Students | Subject
click here 1 Maths
click here 2 History
RollNo | StudentName
4 xyz
2 pqr
How Can I achieve this?
1) Grouping the data by subject
First you need to group the data by subject and then count the items in each group.
You can use the angular.filter module's groupBy filter to do this.
1a) Add a dependency on that module as follows:
var app = angular.module("yourModuleName", ["angular.filter"]);
1b) You can then use the groupBy filter in an ng-repeat directive on a <tbody> tag like this:
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
1c) You're now dealing with the data in the format below. This is an object of key/value pairs where "maths" and "history" are both keys, and the arrays are the values
{
"maths": [
{
"rollno": 1,
"name": "abc",
"subject": "maths",
}
],
"history": [
{
"rollno": 4,
"name": "xyz",
"subject": "history",
},
{
"rollno": 2,
"name": "pqr",
"subject": "history",
}
]
}
2) Displaying the grouped data and counting the items in each group
Use key and value to display the grouped data in a table as follows:
<table>
<thead>
<tr>
<th>Subject</th>
<th>Number of Students</th>
<th>Expand/Collapse</th>
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<td>{{ key }}</td>
<td>{{ value.length }}</td>
<td>
<button>
Expand/Collapse
</button>
</td>
</tr>
<tr>
<td colspan="3">
<table>
<thead>
<tr>
<th>Roll Number</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in value">
<td>{{ student.rollno }}</td>
<td>{{ student.name }}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Note the extra <tr> and nested table with another ng-repeat for displaying the student data. Currently all nested student data will display, the next step is to conditionally show/hide the nested tables based on which expand/collapse button was clicked.
3) Showing/Hiding the nested student data
3a) Add an ng-click directive on the button so that it passes in the key to an onExpandClicked function on your controller:
<button ng-click="onExpandClicked(key)">
Expand/Collapse
</button>
3b) Create the onExpandClicked function in your controller:
$scope.onExpandClicked = function(name){
$scope.expanded = ($scope.expanded !== name) ? name : "";
}
This sets a value on the $scope that can be used in the view to decide whether to show/hide a section of student data. The key is passed into the function as the name parameter and $scope.expanded will either be set to name or reset to "" depending on whether the passed in name is the same as the current $scope.expanded value or not.
3c) Finally, use the $scope.expanded variable in an ng-if directive on the second <tr> tag of <tbody> to show or hide the nested student data:
<table>
<thead>
<tr>
<!-- Omitted for brevity -->
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<!-- Omitted for brevity -->
</tr>
<tr ng-if="expanded === key">
<!--
Omitted for brevity
-->
</tr>
</tbody>
</table>
Demo
CodePen: How to show/hide grouped data created by the angular.filter module's groupBy filter
Design a table with html and iterate through your data object with ng-repeat loop to display the data.
ngRepeat
W3Schools has some basic examples on how to display tables with AngularJS
Angular Tables
First you should replace the actual table by a div structure, because it is not possible to mix two kinds of table like you are planning (when I get you right).
You could toggle every row with a ng-click with the corresponding expanded content like this (pseudo code, I hope the idea gets clear):
<div class="row-header">
<span>RollNo</span>
<span>StudentName</span>
</div>
<div class="row-content" ng-if="!row_4_expanded" ng-click="row_4_expanded = !row_4_expanded">
<span>4</span>
<span>xyz</span>
</div>
<div ng-if="row_4_expanded">
<div class="row-expanded-header">
<span>No of Students</span>
<span>Subject</span>
</div>
<div class="row-expanded-content">
<span>1</span>
<span>Math</span>
</div>
<div class="row-expanded-content">
<span>2</span>
<span>History</span>
</div>
</div>
<div class="row-content" ng-if="!row_2_expanded" ng-if="row_2_expanded" ng-click="row_2_expanded = !row_2_expanded">
<span>2</span>
<span>pqr</span>
</div>
<div ng-if="row_2_expanded">
<div class="row-expanded-header">
<span>No of Students</span>
<span>Subject</span>
</div>
<div class="row-expanded-content">
<span>1</span>
<span>Math</span>
</div>
<div class="row-expanded-content">
<span>2</span>
<span>History</span>
</div>
</div>
When you now click on a row, it toggle presens with the corresponding expanded one.
Here is a working example which resolves your problem.
var indexCtrl = ['$scope', function($scope){
$scope.num = 0;
$scope.test = [{rollno: 1,name: 'abc',subject: 'maths'},
{rollno: 4,name: 'xyz',subject: 'history'},
{rollno: 2,name: 'pqr',subject: 'history'}
];
$scope.changeShow = function(index){
$scope.num = index;
};
}];
<!DOCTYPE html>
<html ng-app>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-controller='indexCtrl'>
<table>
<tr>
<td>Expand/Collapse</td>
<td>No of Students</td>
<td>Subject</td>
</tr>
<tr ng-repeat='i in test' ng-class="num == $index ? red : none">{{}}
<td ng-click='changeShow($index)'>click here</td>
<td>{{$index +1}}</td>
<td >{{i.subject}}</td>
</tr>
</table>
<table>
<tr>
<td>RollNo</td>
<td>StudentName</td>
</tr>
<tr ng-repeat='i in test'>
<td ng-show='num == $index'>{{i.rollno}}</td>
<td ng-show='num == $index'>{{i.name}}</td>
</tr>
</table>
<style>
table tr td{
border: 1px solid black
}
</style>
</body>
</html>
Hope it helps you.

angular 1.2.15 running concurrent loops

I need to do this:
<tbody>
<tr class=“object.sibling[0]”>
<tr class=“object.sibling[1]”>
<tr class=“object.sibling[2]”>
<tr class=“object.sibling[2].child”>
<tr class=“object.sibling[2].child”>
<tr class=“object.sibling[3]”>
<tr class=“object.sibling[4]”>
however I am not sure how to keep track of two loops that are siblings. I can easily do this:
<tbody>
<tr class=“object.sibling[0]”>
<tr class=“object.sibling[1]”>
<tr class=“object.sibling[2]”>
<tr class=“object.sibling[3]”>
<tr class=“object.sibling[4]”>
<tr class=“object.sibling[2].child”>
<tr class=“object.sibling[2].child”>
but then the rows are out of order.
I found a solution that appears to work using ng-repeat-start and ng-repeat-end that visually does exctally what I want but the extra empty rows needed to end the hg-repeat start loops messes up the table when users copy paste.
<tbody>
<tr ng-repeat-start=“x in object.sibling”>
<td class=“x”>
<tr ng-repeat-start=“y in x.child”>
<td class=“Y”>
<tr ng-repeat-end=“”>
<tr ng-repeat-end=“”>
The problem is that the tr’s though they may represent children of siblings must all be on the same level as if that are all sibings. I cannot figure out how to do this with angular 1.2.15. How do I run two loops that keep track of each other that are not nested?
Hm, interesting scenario you've got. This should work:
<tr ng-repeat-start="sibling in siblings"></tr>
<tr ng-repeat-end ng-repeat="child in sibling.children"></tr>
The idea is to repeat two rows for each sibling, but the second row of each sibling is actually repeated for all of the sibling's children. So, in practice, the second row will only show up (and be repeated) if the sibling actually has children.
Here's a full example:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.siblings = [
{
children: [
{}, {}, {}
]
},
{},
{
children: [
{}, {}
]
}
];
});
<div ng-app="app">
<table ng-controller="MainCtrl">
<tr ng-repeat-start="sibling in siblings">
<td>Sibling {{$index}}</td>
</tr>
<tr ng-repeat-end ng-repeat="child in sibling.children">
<td>Sibling child {{$index}}</td>
</tr>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
Notice how there are no extra <tr> elements.

Categories

Resources