ng-repeat or ng-options How can I automatically select the last row in a table ? - angularjs

How I can I automatically select the last row in a table
ng-repeat="unit in selectedOrder.products" using something like select by track by $index == desc or alternatively ng-options
<div class="search" ng-show="selectedOrder">
<table class="table table-bordered">
<tr><th>Item</th><th>Name</th><th>ValueToday</th></tr>
<tr ng-repeat="unit in selectedOrder.products">
<td><img ng- src="http:images/thumbnails/{{unit.shortname}}_tn.jpg" width=40 height=40
alt="{{ unit.shortname | limitTo: 18}} Photo"></td>
<td>{{unit.name | limitTo:18 }}</td>
<td>{{unit.valuetoday| currency:"£"}} </td>
</tr>
</table>

<div class="search" ng-show="selectedOrder">
<table class="table table-bordered">
<tr><th>Item</th><th>Name</th><th>ValueToday</th></tr>
<tr ng-repeat="unit in selectedOrder.products" ng-if="$last">
<td><img ng- src="http:images/thumbnails/{{unit.shortname}}_tn.jpg" width=40 height=40
alt="{{ unit.shortname | limitTo: 18}} Photo"></td>
<td>{{unit.name | limitTo:18 }}</td>
<td>{{unit.valuetoday| currency:"£"}} </td>
</tr>
</table>
will give you only the last row selected

In ng-repeat you can use the $last special variable to apply something only if it's the last element. see: https://docs.angularjs.org/api/ng/directive/ngRepeat
you can use it as a condition for anything you want to do in the tag. like
<img class="{{$last ? 'selected'}}" ng-class="{'selected': $last}" ng-if="$last" ....>
or however you like (these are just examples)
Always keep in mind though that using angular means that you have to edit your model to apply changes to your view, so if you want to have an element selected you have to do something to your model so that the element contains a value that makes it selected and then your view should reflect this.
For example in your controller you can check which element is the last in your ng-repeat array and add a selected variable, then in your view do something to make it look like your element is selected (for example: ng-class="{'selected': element.selected}") otherwise, by working on the view only you can make it look like the element is selected using $last but it won't be really selected in your model
In fact In ng-options (so we are talking about a select) you have to change your model in order to reflect your choice. So for example if your select has an attribute like this: ng-model="selected" then in your controller you set the $scope.selected variable to the last element of the array containing the values for your ng-options

You could use something like ng-if="$index == $last"

Related

angular: sum of ng-repeat filtered list

I can calculate sum of property in ng-repeat list like this:
<table ng-init="total=0">
<tr ng-repeat="item in items">
<td ng-init="$parent.total = $parent.total + item.Amount">
{{item.Amount}}
</td>
</tr>
</table>
However this does not work, when items are filtered: ng-repeat="item in items | filter: search"
The reason is, that <table> element is initialized only once, while <tr> each time the list is filtered. Because of that, the sum is not set to 0 when filtering is applied.
Is there some event/directive, which is called when filtering is applied? I use this "calculate totals" functionality very often and wish to avoid writing calculateTotals() function several times in my controllers and directives.

$index always 0 when using ng-bind-html

I have a directive that contains this markup
<tr ng-if="isComplete()" ng-repeat="row in paged.page() track by $index" ng-click="rowClick(row, $event)" ng-class="assignRowClass(row)">
<td ng-repeat="header in headers" ng-bind-html="trustAsHtml(header.formatter(row[header.property], row, $index))"></td>
</tr>
The problem is that $index is always 0 when passed to the header.formatter function.
try this
<tr ng-if="isComplete()" ng-repeat="(index,val) in paged.page() track by index" ng-click="rowClick(val, $event)" ng-class="assignRowClass(val)">
<td ng-repeat="header in headers" ng-bind-html="trustAsHtml(header.formatter(val[header.property], val, index))"></td>
As saw in my comment this works
$parent.$index
This is because of the new scope created by ng-if and the limit of inheritance between scope in angular (because of javascript limits).
You can either go for $parent.$index of move the ng-if to the upper DOM Element if possible (<thead> / <tbody).

how to display the number of filtered rows outside table definition?

I have implemented a filter for my ngtable. Trying to display the number of filtered items like this:
How to display nr of filtered rows here? Outside the table definition?
{{filtered.length}} result(s) matching the filter
<table ng-table="tableParams" class="table">
<tr ng-repeat="account in filtered =($data | filter:search.accountName | filter:search.id)">
<td>{{filtered.length}}</td>
<td data-title="'id'">
{{account.account.accountId.id}}
</td>
<td data-title="'name'">
{{account.account.accountName}}
</td>
</tr>
</table>
plunkr: http://plnkr.co/edit/Sx4YAO?p=preview
Just add $parent before your filtered in your ng-repeat and you should be fine.
Ng-repeat has an isolated scope.
<tr ng-repeat="account in $parent.filtered =($data | filter:search.accountName | filter:search.id)">
If you create the array before you use it within the child scopes then they'll reference and use the one from the parent scope
JS
$scope.model = {filtered:[]}
HTML
How to display nr of filtered? {{model.filtered.length}} result(s) matching the filter
<tr ng-repeat="account in model.filtered =($data | filter:search.accountName | filter:search.id)">
http://plnkr.co/edit/mcuN34?p=preview
Use built in function:
total() {{ tableParams.total() }}

How to get rowspan into td element of table in AngularJS

In AngularJS 1.3, I'm creating a table from an array I've defined in my controller. Basically, I have the array:
sessionOverviewTrs = [{rowspan: 1},{rowspan: 2},..]
I've got code like this:
<tr ng-repeat="trs in list.sessionOverviewTrs">
<td ng-repeat="tds in trs track by $index">
{{ tds.rowspan}}
The problem is I really want to put the rowspan on the td ng-repeat="tds... but I can't figure out to do that. I feel like I want to put my repeater for the td one level up in a div or something, then have the td executed with the
Why not to simply add the rowspan attribute?
<table>
<tr ng-repeat="trs in sessionOverviewTrs">
<td ng-repeat="tds in trs track by $index" colspan="{{tds.colspan}}" rowspan="{{tds.rowspan}}">
{{tds.value}}
</td></tr></table>
Jsfiddle
<tr ng-repeat="trs in list.sessionOverviewTrs">
<td ng-repeat="tds in trs track by $index" rowspan="{{tds.rowspan}}">

How to sort table by value using ng-if?

I'm a novice at AngularJS and trying to get my table to only show the rows that have a 'color' value of true when the user selects the 'Color Only' item from the Sort By drop down menu.
Here's my sort menu code:
<label>Sort By:</label>
<select ng-model="orderProp">
<option value="title">Title</option>
<option value="filename">File Name</option>
<option value="class">Classification</option>
<option value="color">Color Only</option>
</select>
Here is my table code:
<table>
<thead>
<tr>
<th>Classification</th>
<th>Title</th>
<th>File</th>
<th>Color</th>
</tr>
</thead>
<tbody>
<tr ng-animate="'animate'" ng-repeat="item in filtered = (pptData | filter: query | orderBy: orderProp)">
<td>{{item.class | uppercase}}</td>
<td>{{item.title}}</td>
<td>{{item.filename}}</td>
<td>{{item.color}}</td>
</tr>
</tbody>
</table>
I tried adding ng-if="color"to the ng-repeat directive but that did not work. Live link here.
Use
ng-if="orderProp !== 'color' || item.color"
on your ng-repeat element.
As you should know, when you refer to a property in an Angular directive expression, the property is resolved against the current $scope. ng-repeat creates a child scope for every iteration. When you specify ng-repeat="item in collection", you can then reference that child scope via the property item.
The color property is on that item child scope, not on the outer scope. Thus, saying ng-if="color" will result in none of the rows being rendered, because $scope.color is undefined. ng-if="item.color" will resolve against the item scope, and the row will only be rendered if item.color is defined.
However, if you only want to filter out those rows when the user has selected the color filtering option, you need to make sure you check the orderProp. Thus,
ng-if="orderProp !== 'color' || item.color"
gets the behavior you are looking for.
I suspect you will want to continue to do more complex filtering on these rows as you develop the code. In that case, I would recommend instead writing a function in your controller:
$scope.shouldShowRow = function(row, index) {
var show = $scope . orderProp !== 'color" || row.color;
// more logic for determining show/hide here
return show;
}
And then in your template:
<tr ng-repeat="item in (pptData | filter: query | orderBy: orderProp)"
ng-if="shouldShowRow(item, $index)">
<!-- your row markup here -->
</tr>
$index is a handy value that ng-repeat creates. You may not need it, but it might be useful.
As a suggestion, you should look into the controllerAs syntax. It requires you to name all of your controllers' scopes, and will help you keep track of what scope you are using when:
<div ng-controller="MyController as my">
...
<tr ng-repeat="item in (my.pptData | filter: query | orderBy: my.orderProp)"
ng-if="my.shouldShowRow(item, $index)">
...
</tr>
</div>
ControllerAs:
http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/

Resources