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

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/

Related

Two arrays in two columns of a table

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>

How to make 2 Angular Lists appear next to each other in a html table

I am having a problem where when I run this code which reads data from 2 files both containing 10 numbers. These are both stored seperately in the mainlist but the only problem is when I try to output them into a table, instead of putting each one under its title it just puts both under the "List1" title in a 20 long list. So how do I make mainlist[0] appear under list 1 and mainlist[1] under list 2. Sorry that my code is very messy and very basic as I have only just started learning JS and Angular.
<div id="Tables">
<table>
<tr>
<th>List1</th>
<th>List2</th>
</tr>
<tr>
<tr ng-repeat="i in mainlist[0]">
<td>{{i}}</td>
</tr>
<tr ng-repeat="i in mainlist[1]">
<td>{{i}}</td>
</tr>
</tr>
</table>
</div>
JSfiddle
I hope you're liking Javascript and AngularJS so far! To answer your question the way that tables are created via HTML is row based and not column based meaning <tr> encapsulates cells,<td>, so to create tables you are filling in rows by cells. To accomplish what you want solely through HTML and no additional Javascript you could think of your data being two cells within a single row instead of several rows per column.
I wrote up a quick example of how you could accomplish this through nesting tables. So why nest tables and not just put <td><tr></tr></td>? Row elements cannot be placed within cell elements, but tables can! If you try to place <tr> within <td> it will be rendered ignoring <td>.
I hope this answers your question.
https://jsfiddle.net/krd4p0yt/
var myApp = angular.module('myApp', []);
myApp.controller('TestCtrl', ['$scope',
function($scope) {
$scope.mainList = [
[1, 2, 3],
[4, 5, 6]
];
}
]);
table {
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="TestCtrl">
<table>
<th>List 1</th>
<th>List 2</th>
<tr>
<td>
<table>
<tr ng-repeat="i in mainList[0]">
<td>{{i}}</td>
</tr>
</table>
</td>
<td>
<table>
<tr ng-repeat="i in mainList[1]">
<td>{{i}}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
Here is a solution for your case based on the fact that the two lists have equal length:
<table ng-init="items = mainList[0]">
<tr>
<th>
List 1
</th>
<th>
List 2
</th>
</tr>
<tr ng-repeat="item in items">
<td>
{{item}}
</td>
<td>
{{mainList[1][$index]}}
</td>
</tr>
</table>

Angular JS object as ng-model attribute name

I'm creating a dynamic angular js application wherein I want to use a textbox as a searchtext for the filter of a table. Here's a preview on what I am doing:
As of now, my code looks like this
<table>
<thead>
<tr class="filterrow">
<td data-ng-repeat="col in items.Properties">
<input id="{{col.DatabaseColumnName}}" type="text"
data-ng-model="search_{{col.DatabaseColumnName}}"/>
<!-- Above Here I want to dynamically assign the ng-model based on Databasecolumnname property-->
</td>
</tr>
<tr>
<th data-ng-repeat="col in items.Properties">{{col.ColumnTitle}}</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="content in items2.Contents | filter: search_{{col.DatabaseColumnName}}: search_{{col.DatabaseColumnName}}">
<td data-ng-repeat="col in items.Properties">
{{content[col.Databasecolumnname ]}}
</td>
</tr>
</tbody>
</table>
I already tried the approach of using $compile but I wasn't able to implement it. Any ideas in an approach? Thanks!
EDIT: Plnkr - plnkr.co/edit/5LaRYE?p=preview
You can do this by setting a base object for your ng-Models. So in your controller you will have:-
$scope.search = {};
and in your view do:-
<input ng-attr-id="{{col.DatabaseColumnName}}" type="text"
data-ng-model="search[col.DatabaseColumnName]"/>
With this your dynamic ng-model will be assigned to the search base object, ex:- if col.DatabaseColumnName is col1 then ngModel would be $scope.search.col1

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

How to format table dynamically within ng-repeat in AngularJS

I have a list of items of different types and I would like to display them in a table.
The items of one type will have two columns and items of another type just one. Any suggestions how to change conditionally the colspan on the <> tag on fly?
<div ng-init="items = [
{name:'item1', old:1, new:2},
{name:'item2', old:2, new:2},
{name:'item3', msg: 'message'},
{name:'item4', old:0, new:2}
]">
<table border=1>
<tr ng-repeat="item in items" >
<th>{{item.name}}</th>
<td>{{item.old}}</td>
<td colspan='2'>{{item.msg}}</td>
<td>{{item.new}}</td>
</tr>
</table>
Here is the example to play in jsfiddle: http://jsfiddle.net/38LXt/1/
Thanks!
You can use conditional directives, such as ng-show, to do something like this:
<table border=1>
<tr ng-repeat="item in items" >
<th>{{item.name}}</th>
<td>{{item.old}}</td>
<td colspan="2" ng-show="item.type == 'typeA'">{{item.msg}}</td>
<td ng-show="item.type == 'typeB'">{{item.msgB1}}</td>
<td ng-show="item.type == 'typeB'">{{item.msgB2}}</td>
<td>{{item.new}}</td>
</tr>
</table>
More info about ng-show:
ngShow directive

Categories

Resources