Adding a method to an object in AngularJS? - angularjs

I've got an AngularJS webapplication where I use ng-repeat on an array of persons. The json array defines a firstname, lastname and age of the persons.
In my table I'm trying to apply a CSS class to all the young persons using the ng-class directive.
<table class="table table-striped table-hover">
<tr><th>Firstname</th><th>Lastname</th><th>Age</th></tr>
<tr ng-repeat="person in people | filter:search" ng-class="{success: person.isYoung()}">
<td>{{person.firstname}}</td>
<td>{{person.lastname}}</td>
<td>{{person.age}}</td>
</tr>
</table>
Notice I'm trying to call person.isYoung(), which is the method I'm having trouble with. Things work if I use
ng-class="{success: person.age < 30}"
but, I want to move that logic into the Controller instead.
Inside my Controller I've added this;
$scope.isYoung = function (person) {
return person.age < 30;
}
but it seems like that isn't called.
What should my method definition in app.js look like for me to get this working?
ng-class="{success: person.isYoung()}"

The signature of the function is
isYoung(person)
So that's what you need to use in your template:
ng-class="{success: isYoung(person)}"
If you want to be able to use person.isYoung(), then you need to add this function to all the persons in the array :
angular.forEach(persons, function(person) {
person.isYoung = function() {
return person.age < 30;
}
});

Related

Conditional css class assign in angular 2

I have a grid with checkbox, I am putting checked values in an array (currentFocusedRow), now I want to assign activeRow class to the checked row:
// app.ts
class contact {
public contactlist = [{icontact_id: "contact1"}, {icontact_id: "contact2"}, {icontact_id: "contact3"}, {...}];
public currentFocusedRow = ["contact2", "contact3"];
}
// app.html
<tr *ngFor="let contact of contactlist"
[class.activeRow]="contact.icontact_id == currentFocusedRow">
...
</tr>
now since currentFocusedRow is an array i can't simply check like that (contact.icontact_id == currentFocusedRow) there should be something to check if the value is present in that array or not like indexOf.
I think this should work for you:
Typescript
isActive(id) {
return this.currentFocusedRow.indexOf(id) !== -1
}
HTML
<tr *ngFor="let contact of contactlist"
[class.activeRow]="isActive(contact.icontact_id)">
</tr>
You can use index of the object that is current object, by using:
<tr *ngFor="let contact of contactlist; let i = index">
Which will enable you to get those indexes.
Apart from that, you can just use NgClass directive.
Checking with indexOf in directive itself worked, this is pretty amazing that we can use this JS methods directly in DOM:
<tr *ngFor="let contact of contactlist;"
[class.activeRow]="currentFocusedRow.indexOf(contact.icontact_id) != '-1'">
</tr>

Angular JS - Display only the field with the highest value from JSON data

I have a JSON retrieve from database
[{"id":1,"firstname":"Alan Cayetano","numbers":2},{"id":2,"firstname":"Bong Marcos","numbers":0},{"id":3,"firstname":"I Dont Care","numbers":3},{"id":4,"firstname":"toto tata","numbers":0},{"id":5,"firstname":"titi terter","numbers":0},{"id":6,"firstname":"Ian Go","numbers":0}]
this is the result when displayed in table result
firstname lastname numbers
Alan Cayetano 10
Bong Marcos 4
Ian Go 3
What Ever 0
I only want the data with the highest number value
In this case
firstname lastname numbers
Alan Cayetano 10
This data is dynamically fetch from database
My angular.js
<script src="//code.angularjs.org/1.4.8/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('//');
$interpolateProvider.endSymbol('//');
});
app.controller('customersCtrl',['$scope','$http',function($scope, $http) {
//$http.get("http://localhost:8093/voters/voters_angular")
$http.get("{{ path('vp_president') }}")
.success(function (response) {
$scope.names= JSON.parse(response);
});
}]);
//console.log(names);
</script>
Table
<div ng-app="myApp" ng-controller="customersCtrl">
<table class="table">
//names//
<thead>
<tr>
<th>Firsname</th>
<th>Lastname</th>
<th>NUm</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in names">
<td>//x.firstname//</td>
<td>//x.lastname//</td>
<td>//x.numbers//</td>
</tr>
</tbody>
</table>
</div>
How to achieve this? I am still learning Angular Js
I wonder if Angular's $last filter will work on this
This should work as describe
Link
<tr ng-repeat="x in names| orderBy:'-numbers' | limitTo:1">
<td>//x.id//</td>
<td>//x.firstname//</td>
<td>//x.numbers//</td>
</tr>
It's better to find your max in the controller, not in the view.
function findMax(names) {
var result = null;
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (result == null || name.numbers > result.numbers) {
result = name;
}
}
return result;
}
$scope.name = findMax($scope.names);
And in html
<tr>
<td>{{name.firstname}}</td>
<td>{{name.lastname}}</td>
<td>{{name.numbers}}</td>
</tr>
In AngularJS it's better to pre-sort your data before showing in the view, the ng-repeat creates a watcher for each object it repeat's, in AngularJS the number of watchers is associated with performance if you have many watchers your performance it's worst.
If you don't need the other values to appear, there is no need to create watchers for that values, so it's better to pre-sort the array.
you can do this :
<tr ng-repeat="x in names | orderBy:numbers:reverse | limitTo:1">
You can use:
angular.forEach($scope.names, function (value, key) { //code });
With angular foreach you can read row by row in your $scope.names, and use your logic for get the msx value.
When:
key -> is the position (use an alert(key) to see the info)
value -> is a the row of the json. For get data use value.id, value.firstname, etc.

Use AngularJS Variable, where another AngularJS Variable matches its ID

I have an ng-repeat statement where I want to show an image. The image however, should be chosen from where the ng-repeat's ID matches the image object's ID.
I am unsure of how to do this properly, here is psuedo code of what I am trying to do.
<tr ng-repeat="user in rosterData | orderBy:'name'">
<img ng-src="{{champion.imagename WHERE user.id = champion.id}} />
</tr>
Remember that champion.id is an object of champions, so I want to make sure I get the right champion.name to match with the right champion.id when it matches the current ng-repeat user.id
It would be better if you could check those logic inside the controller:
<tr ng-repeat="user in rosterData | orderBy:'name'">
<img ng-src="{{getImage(user.id)}} />
</tr>
In your controller:
$scope.getImage = function(userId) {
var image = "defaultimage";
$scope.champions.forEach(function(champion) {
if(champion.id===userId) {
image = champion.image;
}
});
return image;
}
You will have to put a method in "ng-src" statement, pass the id as a parameter - > iterate array, find match and so on.
Method should be added in controller to $scope property, than just call it :)

angular filter name as variable

I'm designing universal table that reads data and columns from ajax.
In columns description is also filter name which angular should use for a specific column.
But in HTML templates I can't use variables for filter names:/
Is there a solution for that? Or should I code javascript loop with data source?
Here is code example:
<tr ng-repeat="item in data">
<td ng-repeat="col in cols">
{{item[col.source]}}
<span ng-if="col.ngFilter">
{{col.ngFilter}} // ex. "state" filter
{{item[col.source]|col.ngFilter}} //is not working - is looking for "col.ngFilter" not "state" filter.
</span>
</td>
</tr>
You cannot do it in your HTML. First, you need to apply the filter in your controller.
function MyCtrl($scope, $filter) {
$scope.applyFilter = function(model, filter) {
return $filter(filter)(model);
};
}
Then, in your HTML:
Instead of
{{item[col.source]|col.ngFilter}}
use
{{applyFilter(item[col.source], col.ngFilter)}}
For anyone looking to do something like
{{applyFliter(item[col.source], col.ngFilter)}}
where ngFilter might contains some colon separated parameters such as
currency:"USD$":0
I ended up writing this little helper
function applyFilter (model, filter){
if(filter){
var pieces = filter.split(':');
var filterName = pieces[0];
var params = [model];
if(pieces.length>1){
params = params.concat(pieces.slice(1));
}
return $filter(filterName).apply(this,params);
}else{
return model;
}
}

AngularJS filter with multiple parameters

I want to be able to filter my table with many parameters passed in as an array. Therefore I can build up an array of filter params and pass them in. I don't want to explicitly state what columns to filter against as there could be many columns (some which will be shown and some not).
The HTML looks something like this;
<tr ng-repeat="item in infoData | filter:['param1','param2']">
<td>{{item.data1}}</td>
<td>{{item.data2}}</td>
<td>{{item.data3}}</td>
<td>{{item.data4}}</td>
</tr>
Is there away to filter a table against multiple parameters?
Thanks
This is the quick and dirty way to accomplish what you need.
First create a custom filter in the controller something like this:
$scope.customFilter = function(param1, param2) {
return function(item) {
//return custom stuff here
}
}
then in the html you do this
<tr ng-repeat="item in infoData | filter:customFilter(param1, param2)">
<td>{{item.data1}}</td>
<td>{{item.data2}}</td>
<td>{{item.data3}}</td>
<td>{{item.data4}}</td>
</tr>
this is an example with a custom filter
app.filter('customFilter', function (param1, param2) {
return function (item) {
//return custom stuff here
};
});
and now in the html you do this:
<tr ng-repeat="item in infoData | customFilter(param1, param2)">
<td>{{item.data1}}</td>
<td>{{item.data2}}</td>
<td>{{item.data3}}</td>
<td>{{item.data4}}</td>
</tr>

Resources