Two arrays in two columns of a table - javascript

I currently have two separate table bodies like this:
<tr ng-repeat="cup in cups" >
<td>{{::cup.type}}</td>
<td>{{::cup.name}}</td>
<td>{{::cup.id}}</td>
</tr>
<tr ng-repeat="holder in holders" >
<td>{{::holder.type}}</td>
<td>{{::holder.name}}</td>
<td>{{::holder.id}}</td>
</tr>
How can I combine them into one table, so that the columns are pulled from either the holders or cups array? Something like this (I know you cannot simply ng-repeat both arrays):
<tr ng-repeat="cup in cups" ng-repeat="holder in holders" >
<td>{{::cup.type}}</td>
<td>{{::holder.type}}</td>
<td>{{::cup.name}}</td>
<td>{{::holder.name}}</td>
<td>{{::cup.id}}</td>
<td>{{::holder.id}}</td>
</tr>

Looks like your arrays would always be equal in regard to index, so you can use the index of the ng-repeat directive:
<tr ng-repeat="cup in cups">
<td>{{::cup.type}}</td>
<td>{{::holders[$index].type}}</td>
<td>{{::cup.name}}</td>
<td>{{::holders[$index].name}}</td>
<td>{{::cup.id}}</td>
<td>{{::holders[$index].id}}</td>
</tr>

Related

Get the sum of a calculated expressions depends on template variable in Angular?

I have a simple array of numbers :
data:Array<number> = [1,2,3,4,5];
And I also have an editable input which is a multiplication factor.
on the right side , I show the user the result :
The html is pretty simple :
<table>
<tbody>
<tr *ngFor="let a of data">
<td>{{a}}</td>
<td><input type='text' #i [ngModel]="a" /></td>
<td>{{i.value*a}}</td>
</tr>
<tr>
<td></td>
<td></td>
<td>-------<br/>sum ?</td>
</tr>
<tbody>
</table>
Please notice that the multiplication result is calculated via a template variable (#i ----> i.value*a)
Question:
But how can I calc the sum of that calculated column ?
I wonder if I can do it only via in the template.
Sure I can find solutions via TS.
But I wonder if I can do this only via template calculations
nb
I've used [ngModel] and not banana since I need to show (in the input) the left side value at initialization , and if I'd do banana , when I'll change the input value , it would also change the left side value - which I don't want.
StackBlitz
Fiddled my brain over this for half a day. Finally found a solution to the above. All value manipulations directly from html are often discouraged as these don't qualify as good code practices. Nevertheless, I implemented the solution as follows.
Add the following in your component.ts.
data : Array<number> = [1,2,3,4,5];
sum : Array<number> = [0];
Add the following code in your component.html
<table>
<tbody>
<ng-container *ngIf="{sample : sum} as variable">
<tr *ngFor="let a of data;let index of index">
<td>{{a}}</td>
<td><input type='text' #i [ngModel]="a"/></td>
<td>{{i.value*a}}</td>
<td style="display:none;">{{variable.sample[index] = variable.sample[index-1]+i.value*a}}</td>
</tr>
<tr>
<td></td>
<td></td>
<td>Sum={{variable.sample[5]}}</td>
</tr>
</ng-container>
</tbody>
</table>
Basically, I have used a Array<number> named sum which will hold the sum during each iteration of ngFor. I am calculatiing the same using expression inside the last td as {{variable.sample[index] = variable.sample[index-1]+i.value*a}}. For each iteration of the loop, the sample variable gets updated with the new sum. On any change of the input value the sample variable value also changes and this reflects as the Total.
Hope this helps. A nice and challenging question it is, I must say!.
---EDIT1---
The case was failing in case of non-consecutive numbers. Basically, let a of data;let index of index has two loop conditions. In the longhand notation, the condition evaluates to <tr ngFor let-index="$implicit" ngFor let-a="$implicit" [ngForOf]="data"> , which converts both index and a to implicit variables for the loop over data, thus meaning index === a. I have rectified the same as below. The following code works fine for all cases:
<table>
<tbody>
<ng-container *ngIf="{sample : sum} as variable">
<tr *ngFor="let a of data;let in=index">
<td>{{a}}</td>
<td><input type='text' #i [ngModel]="a"/></td>
<td>{{i.value*a}}</td>
<td style="display:none;">{{variable.sample[in+1] =variable.sample[in]+ i.value*a}}</td>
</tr>
<tr>
<td></td>
<td></td>
<td>SUM={{variable.sample[data.length]}}</td>
</tr>
</ng-container>
</tbody>
</table>
You need use [(ngModel)]. The problem when we use a ngModel with an array is that we can not iterate over the same array
/***** This NOT valid ****/
<tr *ngFor="let a of data;let i=index">
<td><input type='text' [(ngModel)]="a" /></td>
</tr>
See Angular two way data binding in string array doesn't works correctly
So we need use an auxiliar variable
//in ts
data:Array<number> = [1,2,3,4,5];
count:number[]=new Array(this.data.length); //<--this is the auxiliar variable
//for the sum, I use a getter
get sum()
{
let sum=0;
this.data.forEach((p,index)=>{
sum+=p*index
})
return sum;
}
In .html
<table>
<tbody>
<tr *ngFor="let item of count;let i=index">
<td>{{i}}</td>
<td><input type='text' [(ngModel)]="data[i]" /></td>
<td>{{i*data[i]}}</td>
</tr>
<tr>
<td></td>
<td></td>
<td>-------<br/>{{sum}}</td>
</tr>
<tbody>
</table>

How to display data inside table by ng-repeat using Angular.js

I need one help i need to display data inside table using Angular.js.I am explaining my code below.
$scope.listOfData=[
{
{'date':'2016-01-25 18:14:00','name':'raj','email':'raj#gmail.com','order_status':1,'order_id':1111},
{'date':'2016-02-04 11:26:05','name':'raj','email':'raj#gmail.com','order_status':0,'order_id':2222}
},
{
{'date':'2016-01-23 13:15:59','name':'rahul','email':'rahul#gmail.com','order_status':1,'order_id':3333},
{'date':'2016-01-25 18:14:00','name':'rahul','email':'rahul#gmail.com','order_status':0,'order_id':4444}
}
]
my html table is given below.
<div class="table-responsive dashboard-demo-table">
<table class="table table-bordered table-striped table-hover" id="dataTable" >
<tbody>
<tr>
<td rowspan="2">Date</td>
<td rowspan="2">Name</td>
<td rowspan="2">Email</td>
<td colspan="7">Order</td>
</tr>
<tr>
<td>Order Id</td>
<td>Order status</td>
</tr>
<tr>
<td>date</td>
<td>name</td>
<td>email</td>
<td>orderid</td>
<td>orderstatus</td>
</tr>
</tbody>
</table>
</div>
expected output result.
date name email order
order_id order_status
2016-01-25 raj raj#gmail.com 1111 1
to 2016-02-04 2222 0
The above table is for serial no-1 again for sl no-2 the data will display accordingly.
Here i need suppose 0th index of $scope.listOfData has two set of data some field value like name,email are same so these two sate of data will join and it will display in 1st index of the table.Here date column will contain lower date to higher date like(from date to todate),name and email filed will contain the value one but here different is for order column order_id and order_status is different for each set of data of 0th index from $scope.listOfData so these will again move in a another loop.Please help me.
The following may help you
<div ng-repeat="data in listOfData">
<!--<Do whatever you need here with data.name, data.date etc...>-->
<!--You can keep your table here.-->
</div>
<tr ng-repeat="data in listOfData">
<td>{{data.date}}</td><td>{{data.name}}</td>....
</tr>
PS for header you can use a <thead> tag
Edit :
{
{'date':'2016-01-25 18:14:00','name':'raj','email':'raj#gmail.com','order_status':1,'order_id':1111},
{'date':'2016-02-04 11:26:05','name':'raj','email':'raj#gmail.com','order_status':0,'order_id':2222}
}
You can't with your json format like this, flatten it in a one level array with even index containing "from" and odd containing "to" datas then do the following
<tr ng-repeat="data in listOfData">
<td ng-if="$index %2==0">{{data.date}}</td>
<td ng-if="$index %2==1">To {{data.date}}</td>
...
</tr>
EDIT : can't really make a plunker, here is what by flatten I mean transform this
$scope.listOfData=[
[
{'date':'2016-01-25 18:14:00','name':'raj','email':'raj#gmail.com','order_status':1,'order_id':1111},
{'date':'2016-02-04 11:26:05','name':'raj','email':'raj#gmail.com','order_status':0,'order_id':2222}
},
{
{'date':'2016-01-23 13:15:59','name':'rahul','email':'rahul#gmail.com','order_status':1,'order_id':3333},
{'date':'2016-01-25 18:14:00','name':'rahul','email':'rahul#gmail.com','order_status':0,'order_id':4444}
]
]
Into this :
$scope.listOfData=[
{'date':'2016-01-25 18:14:00','name':'raj','email':'raj#gmail.com','order_status':1,'order_id':1111},
{'date':'2016-02-04 11:26:05','name':'raj','email':'raj#gmail.com','order_status':0,'order_id':2222},
{'date':'2016-01-23 13:15:59','name':'rahul','email':'rahul#gmail.com','order_status':1,'order_id':3333},
{'date':'2016-01-25 18:14:00','name':'rahul','email':'rahul#gmail.com','order_status':0,'order_id':4444}
}
]
So your "from" lines will have even index (0,2,4...) and your "to" lines will have the odds ones (1,3,5,...).
Using $index you can now built properly your lines : $index is given by ng-repeat. ng-if is a directive that won't build the dom element if the condition is not true.
So this
<td ng-if="$index %2==0">{{data.date}}</td>
<td ng-if="$index %2==1">To {{data.date}}</td>
Will always build only one <td> element.

Splitting a string in JSON and using them in two separate tds with angular

So I'm calling a JSON string, and I want to split it in two at the ":" and use the two values to show in two separate td tags.
function testCtrl($scope) {
$scope.response = {"name":["The name field is required."],"param":["Hobby: Coding", "Country: USA"]};}
to visualize a little more at what I'm trying to do http://jsfiddle.net/8mnxLzc1/5/
You could try this:
<table>
<tr ng-repeat="resp in response.param">
<td ng-repeat="val in resp.split(':')">{{ val }}</td>
</tr>
</table>
Fiddle
This is a entirely angular solution, no need to call the function split in the ng-repeat.
https://jsfiddle.net/kLjzh565/
<table>
<tr ng-repeat="resp in response.param track by $index">
<td ng-repeat="i in [$index]">
{{response.param[i]}}
</td>
</tr>
</table>

Ng-repeat is not working as expected in html table?

Why doesn't this simple table structure work in angularjs? None of the rows gets populated with the data. If I replace span with tr, it works fine but my third column of Percent doesn't fit in well.
<table class="table table-hover">
<tbody>
<tr>
<th>Grade</th>
<th>Point</th>
<th>Percent</th>
</tr>
<tr>
<span ng-repeat="gdata in gradepoints">
<td ng-repeat="(grade, gp) in gdata"> {{grade | uppercase}} </td>
<td ng-repeat="(grade, gp) in gdata"> {{gp}} </td>
</span>
<span ng-repeat="pdata in percents">
<td ng-repeat="(grade, perc) in pdata"> {{perc}} </td>
</span>
</tr>
</tbody>
</table>
Try this:
<tr ng-repeat="gdata in gradepoints">
<td>{{gdata.grade | uppercase}}</td>
<td>{{gdata.gp}}</td>
<td>{{pdata[$index].perc</td>
</tr>
You want one row for each element in the gdata array, so the ng-repeat needs to be on the <tr> element. If the two arrays aren't in sync, you can create a function in your controller to return the pdata element you need:
$scope.findPdata(gdata, index) {
// ... do your magic here to find the pdata element you want
return result;
}
<td>{{findPdata(gdata, $index)}}</td>
guessing from the below:
<tr>
<th>Grade</th>
<th>Point</th>
<th>Percent</th>
</tr>
i guess your table has 3 columns so your each row has 3 columns?
in that case use the following
<tr ng-repeat="gdata in gradepoints">
<td>{{gdata.grade | uppercase}}</td>
<td>{{gdata.gp}}</td>
<td>{{gdata.percent}}</td>
</tr>
for above to work your gradepoints must be an ARRAY containing objects with 3 properties each i.e. grade,gp,percent

Angular JS ng-class-odd in nested ng-repeats

I'm trying to develop a very generic table outputter - no set number of rows or columns. As such, I've got nested ng-repeat attributes, as such:
<table>
<tr ng-repeat="row in rowList">
<td ng-repeat="col in colList">{{printCell(row,col)}}</td>
</tr>
</table>
It's working great! Until I try to use ng-class-even and ng-class-odd to change the background color of the rows accordingly.
If I put the ng-class-*** statements on the td tag, I get alternating column colors.
If I put the ng-class-*** statements on the tr tag, I don't get any class assignment - they all stay default.
I want alternating row colors. How do I go about doing this?
The value of ng-class-odd and ng-class-even can be a string: ng-class-odd="'myClass'" or an expression ng-class-odd="{myClass: boolExpression}"
Also:
Angular 1.2+: ng-class="{even: $even, odd: $odd}"
<table>
<tr ng-repeat="row in rowList" ng-class="{even: $even, odd: $odd}">
<td ng-repeat="col in colList">{{printCell(row,col)}}</td>
</tr>
</table>
<hr />
Angular < 1.2 ng-class="{even: !($index%2), odd: ($index%2)}"
<table>
<tr ng-repeat="row in rowList" ng-class="{even: !($index%2), odd: ($index%2)}">
<td ng-repeat="col in colList">{{printCell(row,col)}}</td>
</tr>
</table>
Examples: http://jsfiddle.net/TheSharpieOne/JYn7S/1/

Categories

Resources