Draw a matrix array based in AngularJS - angularjs

I need to draw a table in AngularJS based on the following array
$scope.list = [
{ "Row":1, "Column": 1, "Value": "11" },
{ "Row":1, "Column": 2, "Value": "12" },
{ "Row":1, "Column": 3, "Value": "13" },
{ "Row":2, "Column": 1, "Value": "21" },
{ "Row":2, "Column": 2, "Value": "22" },
{ "Row":2, "Column": 3, "Value": "23" },
];
So I need to get a table with 2 rows and 3 columns
I understand that I have to use two nested ngRepeat but I couldn't make it work
Please could you help me ??
Regards

I developed the solution I found a filter 'Unique' here
For each unique row number I get the list of columns
<table border="2">
<tr ng-repeat="row in list | unique:'Row'">
<td>Row: {{row.Row}}</td>
<td ng-repeat="col in list | filter:{'Row':row.Row}">{{col.Value}}</td>
</tr>
</table>

You should first transform your array to such one:
$scope.table = [
["11", "12", "13"],
["21", "22", "23"],
];
That way, it will be easier to iterate over the values in your view:
<table>
<tr ng-repeat="row in table">
<td ng-repeat="column in row">
{{column}}
</td>
</tr>
</table>

Related

Using ng-repeat on nested array of objects

Below is my JSON object and I am trying to show the same in html table.
$scope.results = {
"data": [
{
"name": "Sam",
"details": [
{
"official": [
{
"address1": "Link road",
"pincode": 76755554
},
{
"address1": "K main road",
"pincode": 9766565
}
]
},
{
"name": "John",
"details": [
{
"official": [
{
"address1": "Old college road",
"pincode": 11111
},
{
"address1": "near east side",
"pincode": 6555446
}
]
}
]
}
]
}
]
}
I have used ng-repeat to achieve the below output. But I am not getting the expected result
This is the code which I have tried and got stuck JSFIDDLE
Any idea on how to achieve my expected result will be really helpful.
You may have to tweak this slightly if your data structure can get more complicated when there are more levels, but this should reformat your data and flatten everything into an array of people without all the different levels.
$scope.peopleFlat = [];
function flattenPeople(people) {
people.forEach((person) => {
$scope.peopleFlat.push({
name: person.name,
addresses: person.details[0].official
});
if (person.details.length > 1) {
flattenPeople([person.details[1]]);
}
});
}
flattenPeople($scope.people);
Then you can use a combination of ng-repeat-start and ng-repeat-end to make it work using rowspan instead of a nested <table> element.
<table class="table table-bordered table-condensed">
<tr>
<th>Name</th>
<th>Address</th>
<th>Pincode</th>
</tr>
<tr ng-repeat-start="person in peopleFlat">
<td rowspan="{{person.addresses.length || 1}}">{{person.name}}</td>
<td>{{person.addresses.length ? person.addresses[0].address1 : ''}}</td>
<td>{{person.addresses.length ? person.addresses[0].pincode : ''}}</td>
</tr>
<tr ng-repeat-end ng-repeat="address in person.addresses.slice(1)">
<td>{{address.address1}}</td>
<td>{{address.pincode}}</td>
</tr>
</table>

Angular 2 How to Concatenate an index into an object and its array using Ng For

I dynamically created an array using rows and columns
[
{
"name": "table 1",
"rows": [
"row 1",
"row 2",
"row 3",
"row 4",
"row 5"
],
"columns": [
"column 1",
"column 2"
],
"col1": [
{
"1": "row1col1"
},
{
"2": "row2col1"
},
{
"3": "row3col1"
},
{
"4": "row4col1"
},
{
"5": "row5col1"
}
],
"col2": [
{
"1": "row1col2"
},
{
"2": "row2col2"
},
{
"3": "row3col2"
},
{
"4": "row4col2"
},
{
"5": "row5col2"
}
]
},
{
"name": "table 2",
"rows": [
"row 1",
"row 2",
],
"columns": [
"column 1",
"column 2",
"column 3"
],
"col1": [
{
"1": "row1col1"
},
{
"2": "row2col1"
],
"col2": [
{
"1": "row1col2"
},
{
"2": "row2col2"
],
"col3": [
{
"1": "row1col3"
},
{
"2": "row2col3"
]
}
]
Then using this dynamic array I created a table and stored it as finalArray
which was okay until I went to the body of my table to show data for col and row
<div *ngFor="let table of finalArray">
<span>{{table.name}}</span>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col"></th>
<th *ngFor="let column of table.columns" scope="col">{{column}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of table.rows ; let i = index">
<td>{{row}}</td> // this works fine
<td *ngFor="let column of table.columns; let x = index"> {{table.['col' + x].[i+1]}}</td>
// this is the problem
</tr>
</tbody>
</table>
</div>
Note that the array was created dynamically so rows and columns is not fixed and col1 and col2 was created based on columns.
I attempt to something like table.col[index].[loop all values]?
You are almost there. Iterate thru columns in the second loop for more precision. Remove '.'s when getting elements. Interchange + 1 from i to x when getting columns and use Object.keys to get the array of key names so you can get the corresponding column content. I put it in a method for for readability
HTML
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col"></th>
<th *ngFor="let column of table.columns" scope="col">{{column}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of table.rows ; let i = index">
<td>{{row}}</td>
<td *ngFor="let col of table.columns; let x = index">
{{getColumnContent(table['col'+(x+1)][i])}}
</td>
</tr>
</tbody>
</table>
Typescript
getColumnContent(col) {
return col[Object.keys(col)[0]] // always [0] as it contains a single element
}
Demo

to order object contain dates in html view by angularjs

I have to arrange status(P,A) according to date in ascending order but it showing me in same order as they are inserted. but i want to arrange accourding to date.
API Data:-
$scope.students{
"name": "sample",
"def": [
{
"setId": "arun",
"Date": [
{
"day": "2016-09-28",
"status": "A"
},
{
"day": "2016-09-27",
"status": "P"
},
{
"day": "2016-09-29",
"status": "A"
},
{
"day": "2016-09-26",
"status": "P"
}
]
},
{
"name": "deepak",
"Date": [
{
"day": "2016-09-28",
"status": "P"
},
{
"day": "2016-09-27",
"status": "A"
},
{
"day": "2016-09-29",
"status": "A"
},
{
"day": "2016-09-26",
"status": "P"
},
]
}
]
}
html page :-
<table>
<tbody>
<tr>
<td>S.No.</td>
<td>NAME</td>
<td>26-9-2016</td>
<td>27-9-2016</td>
<td>28-9-2016</td>
<td>29-9-2016</td>
</tr>
<tr data-ng-repeat="student in students" st-select-row="row">
<td data-ng-bind="$index+1"></td>
<td data-ng-bind="student.name"></td>
<td data-ng-repeat="data in student.Date" data-ng-bind="data.status"></td>
</tr>
</tbody>
</table>
want to show on screen in this way:
1. Name | 26-9-2016 | 27-9-2016 | 28-9-2016 | 29-9-2016|
2. Arun | P | P | A | A |
3. dDepak | P | A | P | A |
but i am getting in this way on screen :
1. Name | 26-9-2016 | 27-9-2016 | 28-9-2016 | 29-9-2016|
2. Arun | A | P | A | p |
3. Deepak | P | A | A | P |
angular.module('myApp', ['ng'])
.controller('Ctrl', ['$scope',
function($scope) {
$scope.students = {
"name": "sample",
"def": [{
"name": "arun",
"Date": [
{
"day": "2016-09-28",
"status": "A"
}, {
"day": "2016-09-27",
"status": "P"
},
{
"day": "2016-09-29",
"status": "A"
},
{
"day": "2016-09-26",
"status": "P"
}
]
}, {
"name": "deepak",
"Date": [{
"day": "2016-09-28",
"status": "P"
}, {
"day": "2016-09-27",
"status": "A"
}, {
"day": "2016-09-29",
"status": "A"
},
{
"day": "2016-09-26",
"status": "P"
},
]
}]
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="Ctrl">
<table>
<tbody>
<tr>
<td>S.No.</td>
<td>NAME</td>
<td>26-9-2016</td>
<td>27-9-2016</td>
<td>28-9-2016</td>
<td>29-9-2016</td>
</tr>
<tr data-ng-repeat="student in students.def" st-select-row="row">
<td data-ng-bind="$index+1"></td>
<td data-ng-bind="student.name"></td>
<td data-ng-repeat="data in student.Date | orderBy :'day'" data-ng-bind="data.status"></td>
</tr>
</tbody>
</table>
</body>
The Json data has some keys with wrong names so from your question made a bit assumption and did changes in your HTML part.
<tr data-ng-repeat="student in students.def" st-select-row="row">
<td data-ng-bind="$index+1"></td>
<td data-ng-bind="student.name"></td>
<td data-ng-repeat="data in student.Date | orderBy :'day'" data-ng-bind="data.status"></td>
</tr>
Just use orderBy and provide the key to perform ordering in your case 'day'

how to get particular customers order

/*factory method for getting particular customers order*/
factory.getCustomer = function(customerId) {
for(var i=0,len=customers.length ; i<len ; i++) {
if(customers[i].id === parseInt(customerId)){
return customer[i];
}
}
return {};
};
return factory();
/*Controller*/
myApp.controller('OrdersController',['$scope','$routeParams','customersFactory', function($scope,$routeParams,customersFactory) {
var customerId = $routeParams.customerId;
$scope.customer = null;
function init() {
$scope.customer = customersFactory.getCustomer(customerId);
}
init();
}]);
/*View*/
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>{{customer.name}}'s Orders</h2>
<table class="table table-hover">
<tr>
<th>Product</th>
<th>Total</th>
</tr>
<tr ng-repeat="order in customer.orders">
<td>{{ order.product }}</td>
<td>{{ order.total | currency }}</td>
</tr>
</table>
</div>
</div>
</div>
/*JSON FILE*/
{
"id": "1",
"joined": "2000-12-2",
"name": "Wali",
"city": "Dubai",
"orderTotal": "9.0765",
"orders": [
{
"id": "1",
"product": "protein",
"total": "11.987"
}
]
},
{
"id": "2",
"joined": "2004-12-2",
"name": "Ali",
"city": "London",
"orderTotal": "20.0765",
"orders": [
{
"id": "2",
"product": "bcca",
"total": "2.3456"
},
{
"id": "3",
"product": "baseball",
"total": "4.3456"
}
]
},
{
"id": "3",
"joined": "1980-11-2",
"name": "Zen",
"city": "Australia",
"orderTotal": "6.500",
"orders": [
{
"id": "3",
"product": "chocolate",
"total": "6.4567"
}
]
}
I have made a customers table from which we can perform the CRUD functionality, but when I click to check the particular customer order it is redirecting me to the right view via routing but particular customers orders are not displaying.
can any one suggest a solution for this?
According to your JSON data, the ID is a String, but you are parsing it into an integer, and using ===, which will match only if the value and the type of the compared variables match.
You need to change the if statement, one option is:
if (parseInt(customers[i].id) === parseInt(customerId))
Another option will be:
if (customers[i].id == customerId)
And yet another option is using angular's $filter service.
You need to inject it into your factory, and than in order to get the client, you can use:
var customer = $filter('filter')(customers, {id: customerId.toString()}, true);
return customer.length === 1 ? customer[0] : null;
The toString part is only because your JSON data have ID as as string, and the third argument is set to true to prevent 'like' filter (default $filter behavior will return id 10 for example also if the customerId is 1).

Get value in a row on click and pass it to popup

I need to get the value in a row of a table on click and display it in popup
HTML:
<md-data-table-container>
<table md-data-table class="md-primary" md-progress="deferred">
<thead md-order="query.order" md-trigger="onorderchange">
<tr>
<th name="Task To Be Done"></th>
<th name="Office"></th>
<th name="Due Date"></th>
</tr>
</thead>
<tbody ng-click="showAlert($event)">
<tr ng-repeat="dessert in desserts.data" ng-click="showAlert($index)" flex-sm="100" flex-md="100" flex-gt-md="auto">
<td>{{dessert.task}}</td>
<td></td>
<td>{{dessert.due_on}}</td>
</tr>
</tbody>
</table>
</md-data-table-container>
JS:
$scope.desserts = {
"count": 6,
"data": [{
"task": "Frozen yogurt",
"type": "Ice cream"
}, {
"task": "Ice cream sandwich",
"type": "Ice cream"
}, {
"task": "Eclair",
"type": "Pastry"
}, {
"task": "Cupcake",
"type": "Pastry"
}, {
"task": "Jelly bean",
"type": "Candy"
}, {
"task": "Lollipop",
"type": "Candy"
}, {
"task": "Honeycomb",
"type": "Other"
}]
};
$scope.showAlert = function (index) {
$scope.obj = $scope.desserts.data[2];
$scope.task = $scope.obj.task;
alert($scope.task);
console.log($scope.task);
};
issue in my code is that i could get the value on the array which i have specified ".data[2]". Actually when i click a row in my table i need that value to be displayed to popup "sweetAlert". is there any solution
Don't pass the $index, as this can be a bit dangerous if the underlying data changes, and in this case it just forces you to re-get the item from the array.
Pass the actual item you want to display back to the alert.
<tr ng-repeat="dessert in desserts.data" ng-click="showAlert(dessert)" flex-sm="100" flex-md="100" flex-gt-md="auto">
<td>{{dessert.task}}</td>
<td></td>
<td>{{dessert.due_on}}</td>
</tr>
Don't assign to scope unless you really need it elsewhere.
$scope.showAlert = function (dessert) {
alert('Task:' + dessert.task);
// if you're just using a variable in this function, declare it locally
var dessertType = dessert.type;
console.log(dessertType);
};
See an example of $index causing issues:
http://codeutopia.net/blog/2014/11/10/angularjs-best-practices-avoid-using-ng-repeats-index/comment-page-1/

Resources