AngularJS filter with multiple parameters - angularjs

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>

Related

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 :)

Adding a method to an object in 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;
}
});

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;
}
}

Angular.js - search filter for object with ng-repeat

I'm apologizing for messy description of my problem. I hope you understand it.
I have this HTML code:
<form>
<input ng-model="attr.query" type="text" placeholder="{{attr.attr_name}}" ng-repeat="attr in attrs">
</form>
<table>
<tr ng-repeat="element in elements">
<td ng-repeat="(key, value) in element">{{value}}</td>
</tr>
</table>
JS controller:
$scope.attrs = [{'descr':'descr1'},{'descr':'descr2'}];
$scope.elements = [{'property1" : 'value1', 'property2' : 'value2'},{'property1" : 'value3', 'property2' : 'value4'}];
I need to filter each by query from input. But i need to filter only with the same attr as in input field.
I have some troubles to apply filter to array of objects.
Thanks
If I understand you correctly (I don't have enough rep to ask in a comment, sorry), you want to filter the data on one or more of several attributes.
The simplest way to do this is probably by defining a custom filter function accessible to your scope. AngularJS's filter filter will happily accept that as an evaluator.
$scope.customFilter = function(item) {
var passed = true;
if(/* the item doesn't pass muster */) {
passed = false;
}
return passed;
}
If it helps, I put together a fiddle to demonstrate. (NB. The query fields are case-sensitive.)

How to ng-repeat into html table with multiple levels of json?

I have an object of social media stats. I'm trying to ng-repeat them into a table. Here's my plunker.
HTML:
<table>
<tr ng-repeat="(metric, metricData) in data">
<td>{{metric}}</td>
<td>{{metricData}}</td>
</tr>
</table>
Controller object:
$scope.data = { buzz:0,
Delicious:121,
Facebook:
{
like_count: "6266",
share_count: "20746"
},
GooglePlusOne:429,
LinkedIn:820,
Twitter:4074
};
I run into a problem when I get to the Facebook results. Within the <td> that entire object gets displayed (as it should be with how I have my code setup). But what I'd rather have happen is to repeat through that object and display the key and value in the cell.
I tried doing something looking to see if metricData is an object and doing some sort of ng-repeat on that. But I wasn't having luck with that. Any idea on how I can display the inner object (keys & value) within the cells?
You can define a scope function returning the type of metricData :
$scope.typeOf = function(input) {
return typeof input;
}
And then you can display it according to its type :
<tr ng-repeat="(metric, metricData) in data">
<td>{{metric}}</td>
<td ng-switch on="typeOf(metricData)">
<div ng-switch-when="object">
<div ng-repeat="(key, value) in metricData">
<span>{{key}}</span>
<span>{{value}}</span>
</div>
</div>
<span ng-switch-default>{{metricData}}</span>
</td>
</tr>
You can see it in this Plunker
Sounds like you'll need a specific directive that wires up children to be recursive, take a look at this example: Recursion in Angular directives
What you'd check on is if what you need to repeat is an object and not a value, then add the new element compile it, and start the process over again.
I'm assuming you want each of those values to have their own line but you don't explain exactly how you want it to work. I think the matter would best be handled by passing a clean version of what you want to the ng-repeat directive. I'm assuming you want two rows for facebook in your sample. You could create a filter to flatten the metrics so there are properties "Facebook_like_count" and "Facebook_share_count" (PLUNKER):
app.filter('flatten', function() {
function flattenTo(source, dest, predicate) {
predicate = predicate || '';
angular.forEach(source, function(value, key) {
if (typeof(value) == 'object') {
flattenTo(value, dest, predicate + key + '_');
} else {
dest[predicate + key] = value;
}
});
}
return function(input) {
var obj = {};
flattenTo(input, obj, '');
return obj;
}
});
Then your repeat can use the filter:
<tr ng-repeat="(metric, metricData) in data|flatten">

Resources