ng-repeat value as ng-class for last <td> - angularjs

<tr ng-repeat="row in rows">
<td ng-class="{row[th]:$last}" ng-repeat="th in ths">{{row[th]}}</td>
</tr>
for the code above, i'm trying to use the row[th] value as the name of the class in ng-class for the last td element only.
I can use an actual class name just fine, but not the referenced value from row[th]. Any ideas how to accomplish this?
PS: the row[th] will return a status (e.g. Red, Green, etc.), which is also a css class name i'm using.
jsFiddle here
in the fiddle above, if i replace row[th] with Green in ng-class, that works!
the solution below by #tasseKATT works fine, however now i seem to have another issue. i'm not able to include another static-named class. Fiddle link here. Any help much appreciated.

After much troubleshooting, I came up with the following solution (extending #tasseKATT's original answer:
<td ng-class="{true: [row[th], 'staticCSSClassName']}[$last]" ng-repeat="th in ths">{{row[th]}}</td>
The code above adds two classes to the last <td> in ng-repeat:
value contained in row[th]
staticCSSClassName
So, basically, the value part in the Object can be an array of strings, which can include referenced values from ng-repeat as well as static class names.
working jsfiddle here
Hope someone finds this useful.

Related

How to find out if input is valid without form in AngularJS

I've faced following issue:
I have a <table>, where <tr>'s a generated via ng-repeat, and each <tr> contains several <input> elements. Smth like this:
<table>
<tr ng-repeat="plan in plans">
<td>
<input ng-pattern="/^\d+((\.|\,)\d+)?$/" ng-model="plan.field1" ng-blur="updateRow(plan)">
</td>
<td>
<input ng-pattern="/^\d+((\.|\,)\d+)?$/" ng-model="plan.field2" ng-blur="updateRow(plan)">
</td>
</tr>
</table>
When user finishes editing input I want to update full row. But I want to do it only if this input is valid. I mean I want to execute updateRow(plan) only if this condition ng-pattern="/^\d+((\.|\,)\d+)?$/" is satisfied. Or maybe somehow check it within updateRow(). But I can't find a way to do it without forms.
1)Is there a way to do it? Or may be there is better way to implement my idea?
2)And also is there way to bind ng-blur to each input in a row? Because I have about 20 inputs in a row and it looks bad when there is such amount of repeating.
Thanks to everybody in advance!
So I solved the first question by using forms and ng-form. I put every tr element in separate tbody and applied ng-form to each tbody element.
So i believe that I have to use forms if I need validation.

Coloring a row depending on a boolean column value

I use a ui-grid in an app showing some data.
The first column is a boolean value.
If this value is true I want to color the whole row green (by setting bg-success as cellclass)
How can I check for the boolean value?
How can I change the whole row's color?
My setup is pretty basic, so I dont include code you know anyways ;)
Assuming you'll use boolOdd as the boolean and bg-error as other class, this would be the answer:
<table>
<tr ng-repeat="column in columns" ng-class="{'bg-success': boolOdd, 'bg-error': !boolOdd}">
<td>{{column.name}}</td>
<td>{{column.text}}</td>
</tr>
</table>
Have you though about using ngClass.
Could add this on the <tr ng-class="{'bg-success' ? yourBool }">
Sounds like you want to try ng-class
Could you paste sample code?

Angularjs ng-class not updating when using object annotation style

I just noticed that something doesn't work in Angular (or it doesn't as I expected it to work) when using object in ng-class.
What do I expect?
When changing the name of a property in the object, the class should update accordingly.
What did I try?
I found that when I use object style annotation like
ng-class="{obj.prop: testExpression}" and the obj.prop changes (the expression keeping returning TRUE) the value inside ng-class changes but that in the class attribute doesn't.
the difference is between this [NOT WORKING]:
<tr ng-repeat="user in users" ng-class="{ {{user.genre}}: true}">
and this [WORKING]:
<tr ng-repeat="user in users" ng-class="user.genre">
See a plunkr here:
http://plnkr.co/edit/149ba2WQ5RK5XqLmWQWK?p=preview
The thing is I need to use object annotation in order to disable the class.
Is there something I am doing wrong or I just misunderstood Angular?
Or a third solution?
In short, { {{user.genre}}: true} is not a correct angularjs expression
For your solution, try ng-class="getClass(user.genre)"
and do whatever you want in getClass function
example
You are trying to evaluate an object here, hence for each key-value pair of object with a real (truthy) value the corresponding key is used as a class name. If you have single parameter you have to use like:
<tr ng-repeat="user in users" ng-class="user.genre: true">
In case of multiple parameter you have to use like:
<p ng-class="{strike: deleted, bold: important, red: error}">

Table from 2D array in AngularJS

I'm stuck on something that I was expecting with AngularJS to work out of the box without any issues, and yet strangely enough...
I'm using a JSON service that returns data as a 2D array:
$scope.data= [
["val-11", "val-12", "val-13"],
["val-21", "val-22", "val-23"]
];
From this I'm trying to generate a table like this:
<table>
<tr ng-repeat="row in data">
<td ng-repeat="col in row">{{col}}</td>
</tr>
</table>
I don't understand why AngularJS doesn't handle such a basic scenario. I can get correct $index for the parent loop, if I need it, I can iterate through the values, but only with one loop like this "col in data[0]", but I cannot get any result trying to use the nested loop as shown above.
Am I doing something wrong? It just seems to be too basic not to work right away. Please somebody help me with this bizarre issue.
In Angular 1.0.x the ng-repeat directive had numerous bugs caused by trying to "guess" whether non-object values (i.e. strings or numbers) had been added, removed or moved.
The problem is that non-objects have no identity of their own, so it is impossible to track them accurately. This was problematic in a number of cases and also caused the ngRepeat code to be bloated with loads of workarounds and edge cases.
In 1.2 we improved the syntax for ng-repeat to allow the developer to specify for themselves exactly how to identify items in a collection. This is done by the "track by" keyword. One consequence of this is that we disallow items which have the same identifier.
By default ng-repeat will try to track by the value of the item. If you have repeated items such as the same object or identical strings or numbers then ng-repeat will complain and you will see the error in the console.
var TableCtrl = function($scope) {
$scope.data= [
["", "", "val-13"]
];
}
Here the first two items in the sub-array are the same "empty" string. See this fiddle: http://jsfiddle.net/tEU8r/
If you really do want to have repeated items in the collection then you need to provide a method for ng-repeat to distinguish them. The simplest and obvious approach is to track the items by their position in the collection. This is done by using "track by $index". Here is the same example but fixed in this way:
<table ng-controller="TableCtrl">
<tr ng-repeat="row in data">
<td ng-repeat="col in row track by $index">
{{$parent.$index}}-{{$index}} {{col}}
</td>
</tr>
</table>
http://jsfiddle.net/h44Z8/
So this is not a bug in AngularJS. But you are correct that people should be aware of this change when upgrading to 1.2

What is the syntax for an orderBy with an ng-repeat in AngularJs

I reviewed the documentation
http://docs.angularjs.org/api/ng.filter:orderBy
but I am still a little confused so maybe the documentation could benefit from a really simple example as well as one that's more detailed.
What I have is:
<tr data-ng-repeat="row in grid.data">
In the row object there is a property row.num
If I want to order my ng-repeat then should what syntax should I use. Do I need to orderBy row.num or num. Do I need this in quotes?
You just need to state property of the loop variable.
<tr data-ng-repeat="row in grid.data | orderBy:'num'">

Resources