Using filter on angular ng-repeat - angularjs

I am trying to filter to just one store, given the store Id, which is picked in a dropdown.
HTML:
<tbody data-ng-repeat="store in orderVm.Stores | filter :{store.id=orderVm.Stores.selectedStore.id}">
I don't get how to set up the filter so that it only shows the one store with the specified id.
controller:
vm.Stores = json;// from file
vm.Stores.selectedStore = {
id: vm.Stores[0].Id,
name: vm.Stores[0].MarketplaceName
};
vm.Stores:
[
{
"Id": 1,
"MarketplaceId": 1,
"MarketplaceName": "Etsy"
]
},
{
"Id": 2,
"MarketplaceId": 2,
"MarketplaceName": "Shopify"
}
]
The error I get is unexpected%2C%20expecting%20%5B%3A%5D&p2=32&p3=orderVm.Stores%20%7CNaNilter%20%3A%7Bstore.id%3DorderVm.Stores.selectedStore.id%7D&p4=.id%3DorderVm.Stores.selectedStore.id%7D

Simple to filter your data by value:
<tbody data-ng-repeat="store in orderVm.Stores | filter:Vm.Stores.selectedStore.id">
It will get objects with properties have value is Vm.Stores.selectedStore.id. Because name not is a number (id), you can use this filter for it.
To specific filter by value of id:
<tbody data-ng-repeat="store in orderVm.Stores | filter:{Id:Vm.Stores.selectedStore.id}:true">
Syntax: filter:{propertyName:value}:true
true is for exact match.

Related

ng-option select bound to separate array

I have a product model that has a property I want to bind to a separate array of options. Basically by product model has a property called 'category', like this:
productModel = {
Id : 1,
Description: 'Widget',
Category: 0,
...
As you can see, the property is an int (from the db) but I also get a separate array of what the categories are:
Categories : [
{ "Number" : 0, Name : "N/A" },
{ "Number" : 1, Name : "Option 1" },
{ "Number" : 2, Name : "Option 2" }
]
I want to be able to have a select list with the corresponding value shown, so if the product model comes back with 0 set then the default value in the select list will be "N/A".
I have achieved this by doing:
<select ng-model="Categories[productModel.Category]" ng-options="v.name for v in Categories" ...
but the problem with this is that when I change the option the value isn't binding back to the model. Because the data is posted back the server when the user changes the value I don't really want to change the productModel to have the same Name and Number structure as the categories (I can do this if it is the best way). I really just want the user to be able to select an option and for the product model to contain the corresponding number.
Can I (should I) do this using the 'track by'?
You need to update your ng-model value to bind to productModel.Category, you also need to update your ng-options expression to the following ng-options="v.Name as v.Number for v in categories".
You can find more information regarding the ng-options and ng-model directives here.
Please see working example here
HTML:
<div ng-controller="TestController">
<select ng-model="productModel.Category" ng-options="v.Name as v.Number for v in categories"></select>
<h3>productModel.Catecogy => {{productModel.Category}}</h3>
</div>
JS:
var myApp = angular.module('myApp', []);
myApp.controller('TestController', ['$scope', function($scope) {
$scope.productModel = {
Id: 1,
Description: 'Widget',
Category: 0
};
$scope.categories = [{
"Number": 0,
Name: "N/A"
}, {
"Number": 1,
Name: "Option 1"
}, {
"Number": 2,
Name: "Option 2"
}];
}]);
Not relevant to the question but its good practice to try and keep the case of your properties and variable names the same.

convert column value to a map value in ng-repeat

Nervous to ask this question.. HATE getting downvoted.. but it is what it is, I've searched and can't find the solution.
What I ended up doing is adding a loop that goes through my searchResults and reassigns the value for the column after the service returns inside the success block (PSEUDO CODE HERE, I can't copy and paste my actual code, there is an airgap):
var myNumberMap = {
1: "Number ONE!!",
2: "Number TWO!!",
3: "Number THREE!!!"
}
$scope.getSearchResults = function() {
$q.all({
resultSet : searchService.getSearchResults()
}).then(function(resultData) {
searchResults = resultData.resultSet;
for(var i = 0; i < searchResults.length; i++) {
searchResults[i].number = myNumberMap[searchResults[i].number];
}
}
}
I was really hoping there was some slick way I could just assign the data result value inside the grid config to be the value in the map?
Something like:
$scope.myCoolGridConfig = NgGridConfig.getConfig(
NgGridConfig.getDefaultConfig(), {
data: 'searchModel.searchResults.list',
columnDefs: [
field: 'number',
displayName: 'Number',
value: myNumberMap[searchModel.searchResults.list.number]
]
}
)
There are a few methods that you could take here:
Create a custom filter that you apply to your ng-repeat to transform the values based on your map.
Store your value map in your angular controller and bind the mapped value to the DOM.
// Controller
$scope.myMap = {
1 : "String One",
2 : "String Two",
3 : "String Three"
}
// something.html
<div ng-repeat='num in numList'>
{{myMap[num]}}
</div>
If I interpenetrated the question correctly your looking for something along these lines.
myMap = {
1 : "String One",
2 : "String Two",
3 : "String Three"
};
If the col number is 1 display String One instead of one in the table
Use myMap and look for the prop of col in it to pull the string value
<table>
<tr ng-repeat="col in tempCols">
<td>{{col}}</td>
<td>{{myMap[col]}}</td>
</tr>
</table>
If you need to do it towards an object that has no defining index such as the object below.
$scope.objectData = [{
name: "test1",
},
{
name: "test1",
},
{
name: "test1",
},
{
name: "test1",
},
{
name: "test1",
},
]
You can track it by $index + 1
<table>
<tr>
<td> Column Converted</td>
<td> Object name value</td>
<tr ng-repeat="col in objectData">
<td>{{myMap[$index + 1]}}</td>
<td>{{col.name}}</td>
</tr>
</table>
Heres a plunker for a better visual

Angular filter by array that contains search criteria

Does the built in Angular "filter" support filtering an array in the sense that "filter where array contains "
Such as follows:
$scope.currentFilter = "Allentown";
$scope.users = [{
name: "user1",
locations: [
{ name: "New York", ... },
{ name: "Allentown", ... },
{ name: "Anderson", ... },
]
}, ... ];
<div ng-repeat="user in users | filter : { locations: { name: currentFilter } }"></div>
In other words I'm looking to filter to only users with a "locations" array that CONTAINS a location that matches the string by name.
If not, how can I accomplish this with a custom filter?
Your code snippet works as is since Angular 1.2.13. In case you're using an older version (tested on 1.0.1) and don't need to reuse your filtering routine across controllers (in which case you should declare a proper filter), you can pass the built-in filter a predicate function :
<div ng-repeat="user in users | filter : hasLocation">{{user.name}}</div>
And write something like this :
$scope.currentFilter = "Allentown";
$scope.hasLocation = function(value, index, array) {
return value.locations.some(function(location) {
return location.name == $scope.currentFilter;
});
}
Fiddle here.

filtering the list using angularjs

See my Fiddle
I have list of books label with "comic" and "fiction" in my list.
on top I have all label and if you click on each label then books labled with that text should only be displayed.
If I get the JSON key at parent level in JSON then it works perfect.
but in this case I have label key as cid and I need to sort basic on that key.
this is my js code
function Test($scope) {
$scope.persons = [{
"s": "book1",
"cl": [{
"cn": "fiction",
"cid": 1
}]
}, {
"s": "book 2",
"cl": [{
"cn": "comic",
"cid": 2
}]
}];
}
any idea?
You can use ng-click in each tab and call a function with a value .based on that value you can filter the array to new array.
like this
<span ng-click="setTab(1)">fiction</span> |
<span ng-click="setTab(2)">comic</span> |
<span ng-click="setTab(3)">No filter</span>
and in controller
$scope.setTab = function(a) {
$scope.s=a;
//filter your array based on the value
/*if(a===1){ filter fictions} and so on */
}
see my fiddle for starting

Angularjs OrderBy on ng-repeat doesn't work

I'm trying to use AngularJS for my first project (a tournaments manager) and the orderBy filter on ng-repeat doesn't work :( I have read all the documentation about that, but nothing to do :/
So, I have vars defined on $scope like that :
$scope.order_item = "count_win";
$scope.order_reverse = false;
$scope.teams = {
100 : {
id: 100,
name: "XXX",
count_win: 1,
count_loose: 2,
goal_average: 1,
},
200 : {
id: 200,
name: "XXX",
count_win: 1,
count_loose: 2,
goal_average: 1,
},
[...]
};
Now, on my view i'm trying to reorder (first with only one order item) but never work...
<tr ng-repeat="team in teams | orderBy:order_item:order_reverse">
<td>{{team.name}}</td>
<td>{{team.count_loose}}</td>
<td>{{team.goal_average}}</td>
</tr>
The second time, I want to reorder from 2 pieces of information: count_win and goal_average if first are equal.. I try to replace $scope.order_item like that, but if with one the code doesn't work, he'll never work with 2...
$scope.order_item = ['count_win','goal_average'];
Thank you all for reading and sorry for the post size.
$scope.teams isn't an array (it's an object of objects), and the orderBy filter only works with arrays. If you make $scope.teams an array, it will work:
$scope.teams = [
{
id: 100,
name: "team1",
count_win: 3,
count_loose: 2,
goal_average: 2,
},
{
id: 200,
name: "team2",
count_win: 3,
count_loose: 2,
goal_average: 1,
},
{
id: 300,
name: "team3",
count_win: 1,
count_loose: 2,
goal_average: 1,
}
];
Or, you can add a special filter that works on objects, like this (borrowed from here):
app.filter('orderObjectBy', function() {
return function(items, field, reverse) {
var filtered = [];
angular.forEach(items, function(item) {
filtered.push(item);
});
filtered.sort(function (a, b) {
return (a[field] > b[field] ? 1 : -1);
});
if(reverse) filtered.reverse();
return filtered;
};
});
And use it like this:
<tr ng-repeat="team in teams | orderObjectBy:order_item:order_reverse">
Note that this custom filter will not work with an array of sort orders as in the second part of your question.
You don't have to create a scope parameter for your orderBy, you can directly do this in your markup if you are dealing with arrays.
<tr ng-repeat="team in teams | orderBy:count_win:false">
With two parameters, you should just do
<tr ng-repeat="team in teams | orderBy:['count_win','goal_average']">
After for a more complex order, you could create a function in your scope like so :
$scope.customOrder = function (team) {
//custom
}
And just call it like
<tr ng-repeat="team in teams | orderBy:customOrder">
Like #Jerrad said, ng-repeat only works with arrays, so you need to convert your teams object into an array to get it work properly.
ng-repeat works only on arrays, not on JSON objects.
This was already discussed here: Angular - Can't make ng-repeat orderBy work
You either have to change the JSON object to an Array, or to convert it on the fly.
The controller could then look like this:
var app = angular.module('app', []);
app.controller('Ctrl', function ($scope) {
$scope.teams = [
{
id: 100,
name: "A Team",
count_win: 1,
count_loose: 2,
goal_average: 1
},
{
id: 200,
name: "C Team",
count_win: 2,
count_loose: 3,
goal_average: 4
},
{
id: 300,
name: "B Team",
count_win: 4,
count_loose: 1,
goal_average: 8
}
];
$scope.predicate = 'name';
});
I created a fiddle here with a demo containing your data:
http://jsfiddle.net/c3VVL/

Resources