Is there a way to create a function in html view. Because I have data and I used ng-repeat to diplay them in my html view. I used ng-if to display the first 15 data in the first table and the second 15 data in the second table and so on... .
My concern now is I am creating a table three times and I think it's repetitive code. The 3 tables have the same code except I only changed the ng-if condition. I want a shorter code to make it reusable. Is there a way for it? Thanks.
My fiddle is here: https://jsfiddle.net/DharkRoses/kpw43k95/
sample of my code is:
<table border=1>
<tr ng-repeat="user in users" ng-if = "$index <= 14">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.stat}}</td>
</tr>
</table>
The quick and dirty way :
<table border=1 ng-repeat="col in [0,1,2]">
<tr ng-repeat="user in users" ng-if = "$index >= col*15 && $index < (col+1)*15">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.stat}}</td>
</tr>
</table>
https://jsfiddle.net/ocuznpov/
But it will not adapt to the length of the array if you get over 15*3 items
You can create a directive for that, see https://jsfiddle.net/kpw43k95/1/
here I have created a directive name uiFoo, which contains the template for the table,
Directive:
app.directive('uiFoo',
function() {
return {
restrict: 'EAC',
template:'<td>{{user.id}}</td><td>{{user.name}}</td><td>{{user.stat}}</td>',
link: function($scope, element, attrs, controller) {
}
};
}
);
Html:
<div ng-app="myApp" ng-controller="check">
<div class = "container">
<table border=1>
<tr ng-repeat="user in users" ui-foo ng-if = "$index <= 14">
</tr>
</table>
<table border=1 class>
<tr ng-repeat="user in users" ui-foo ng-if = "$index > 14 && $index <=29">
</tr>
</table>
<table border=1>
<tr ng-repeat="user in users" ui-foo ng-if = "$index > 29">
</tr>
</table>
</div>
</div>
link the template html in your directive, and you are done! its reusable.
Related
I'm working on a shift arrangement app. In it I'm trying to create two tables that show which possible shifts each user has selected.
Both tables display the same data, but arrange it differently. Each table cell has a number of check-boxes that display the possible shifts for each person (in table 1) or the possible people for a shift (in table 2). A checkbox from table 1 that displays shift A option for person X will have the same data-bind as its equivalent checkbox in table 2, which displays person X option for shift A.
The purpose of this is to update the equivalent data in both tables simultaneously when the user couples a person with a shift. The problem: when a checkbox in table 1 is checked/unchecked, all of the check-boxes in table 2 gets checked/unchecked, as shown below:
Here is my template:
<div class="table-container" dir="ltr">
<h3>People</h3>
<table>
<thead>
<th>Name</th>
<th>Options</th>
</thead>
<tbody>
<tr *ngFor="let user of userPreferences">
<td>{{user.name}}</td>
<td>
<div *ngFor="let selection of userYesses[user.name]">
<mat-checkbox class="option-checkbox" dir="ltr" [(ngModel)]="selection.isSelected" name="usc">{{selection.option}}</mat-checkbox>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="table-container" dir="ltr">
<h3>Shifts</h3>
<table>
<thead>
<th>Time</th>
<th>Options</th>
</thead>
<tbody>
<tr *ngFor="let shift of totalShifts">
<td dir="ltr">{{shift.time}}</td>
<td>
<div *ngFor="let selection of shiftYesses[shift.time]">
<mat-checkbox class="option-checkbox" [(ngModel)]="selection.isSelected" name="syc">{{selection.name}}</mat-checkbox>
</div>
</td>
</tr>
</tbody>
</table>
</div>
And here is relevant component code:
this.userPreferences.forEach(u => {
this.userYesses[u.name] = [];
u.preferences.shifts.forEach(week => {
week.forEach(day => {
if (!day.shifts) return;
day.shifts.forEach(shift => {
if (!this.shiftYesses[`${day.date} ${shift.time}`]) this.shiftYesses[`${day.date} ${shift.time}`] = [];
if (shift.isSelected) {
let selection = new Selection(`${day.date} ${shift.time}`, u.name);
this.userYesses[u.name].push(selection);
this.shiftYesses[`${day.date} ${shift.time}`].push(selection);
}
});
});
});
});
The code seems alright to me, am I missing anything? Maybe it's a bug in Angular?
Thanks in advance!
In case anyone else experiences this issue -
After a few days of struggling with this, I stumbled upon this issue from Angular's git - https://github.com/angular/angular/issues/9230
I've read the following in kara's answer:
In the case that you don't want to register a form control, you currently have a few options:
1 - Use ngModel outside the context of a form tag. This will never throw.
<input [(ngModel)]="person.food">
After reading this, I switched the <form> tag into a <div> and everything works as expected now.
Seems to be the same requirement like AngularJS "Vertical" ng-repeat but solution doesn't work for *ngFor
I have this object array that I am trying to bind to an HTML table. Its format is something like below:
[
{
"Animal":"Dog",
"Country":"France",
"Food":"Tofu",
"Car":"Nano",
"Language":"TypeScript"
}
]
Now this can simply be formatted in the default HTML horizontal table way like this:
<table>
<tr>
<th>Animal</th>
<th>Country</th>
<th>Food</th>
<th>Car</th>
<th>Language</th>
</tr>
<tr *ngFor="let data of datas">
<td>{{data.Animal}}</td>
<td>{{data.Country}}</td>
<td>{{data.Food}}</td>
<td>{{data.Car}}</td>
<td>{{data.Language}}</td>
</tr>
</table>
This would create table like below(Please ignore the data in the table;its just to give an idea.):
But how would I create a structure like this with dynamic data(kind of a vertical table):
In Component:
this.arrayOfKeys = Object.keys(this.datas[0]);
html:
<table>
<tr *ngFor="let key of arrayOfKeys">
<th>{{key}}</th>
<td *ngFor="let data of datas">
{{data[key]}}
</td>
</tr>
</table>
Use ng-container if You have data structure similar to groups[].items[].name
So, if You want to add row
<table>
<ng-container *ngFor="let group of groups">
<tr>
<td>{{group.name}}</td>
</tr>
<tr *ngFor="let item of group.items">
<td>{{item.name}}</td>
</tr>
</ng-container>
</table>
Source: https://stackoverflow.com/a/44086855/1840185
In my new project,called "Gold loan management system",I need to fetch the ornaments name from ornament table with the specified GLID.GLID is not unique,So we may have more than one row with same GLID and ornament name.ornament name with weight
Now i want to calculate the number of ornaments after perform ng-if.I used "{{ornamentdata.length}}" Which getting the totalno of ornaments in the ornament table.How can we find the total no of ornaments getting as the result of ng-if ?
index.html
<table class="table table-bordered table-hover">
<tr ng-repeat="ornament in ornamentdata" ng-if="ornament.GLID == cstmrdetails.GLID">
<td>{{$index }}</td>
<td>{{ornament.ORNAMENT}}</td>
<td>{{ornament.WEIGHT}}gm</td>
</tr>
</table >
You can use angular filter instead of ng-if ng-repeat expression allows filtered results to be assigned to a variable. This variable will be accessible from current scope so you can use it to count the number of elements in it.
<body ng-controller="MainCtrl">
<table class="table table-bordered table-hover">
<tr ng-repeat="ornament in (filteredItems = (ornamentdata | filter : {GLID: testid}))" >
<td>{{$index }}</td>
<td>{{ornament.ORNAMENT}}</td>
<td>{{ornament.WEIGHT}}gm</td>
</tr>
</table>
<p>Number of filtered items: {{filteredItems.length}}</p>
</body>
DEMO
first add class to ng-repeat raw and then create another raw and call a function. from that get length of the rows
<table class="table table-bordered table-hover">
<tr ng-repeat="ornament in ornamentdata" ng-if="ornament.GLID == cstmrdetails.GLID" class="row-count">
<td>{{$index }}</td>
<td>{{ornament.ORNAMENT}}</td>
<td>{{ornament.WEIGHT}}gm</td>
</tr>
<tr ng-init="getCount()">
<td> count{{count }}</td>
</tr>
</table >
$scope.getCount = function(){
$timeout(function(){
$scope.count = document.getElementsByClassName('row-count').length;
});
}
Make a filter called filterWithCondition
In Your Html
<table class="table table-bordered table-hover">
<tr ng-repeat="ornament in filteredData = (ornamentdata | filterWithCondition:'GLID':cstmrdetails.GLID)">
<td>{{$index }}</td>
<td>{{ornament.ORNAMENT}}</td>
<td>{{ornament.WEIGHT}}gm</td>
</tr>
Filtered Data Count is {{filteredData.length}}
</table >
The Filter is like below
app.filter('filterWithCondition', function() {
return function(items, itemKey, compareWith) {
var filtered = items.filter(function(item){
return item.itemKey == compareWith
})
return filtered;
}
});
plnkr demo Filter Demo
Is it possible to apply ng-click in AngularJS to a table column? I tried the following, which doesn't seem to do the trick.
<table>
<colgroup>
<col ng-repeat="item in items" ng-click="myFunction(item)"> </col>
</colgroup>
<thead>
<tr>
<th ng-repeat="item in items"> {{item.title}} </th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="item in items"> {{item.info}} </td>
</tr>
</tbody>
</table>
It is not possible do it in the way you have tried. You may register the ng-click on every td element. Another possibility may be registering the ng-click at the table element and use the original dom event to determin wich column was clicked. You can access the event in this way: ng-click="myFunction($event)" then in the controler:
$scope.myFunction = function(e){
console.log(e);
}
see this post How to find row and col number of a cell in table if you would like to go this way...
Before using knockout, I was injecting an id in my tr of my table like this:
<table>
<tr data-id="#item.id">
....
Then #item.id was replaced (server side)
Now I use knockout and I don't know how to inject my 'id' in my < tr > tag.
Any idea?
Thanks.
Use the 'attr' binding: http://knockoutjs.com/documentation/attr-binding.html
<table>
<tbody data-bind="foreach: items">
<tr data-bind="attr: { 'data-id': id }">
<td data-bind="text: id"></td>
</tr>
</tbody>
</table>
Here's a working example: http://jsfiddle.net/VKP4J/