Filter through array of objects - arrays

I have an array of objects (~650) in the format
[1: {firstName: "Hello",
lastName: "World",
shortName: "h.world",
...some other items
},
2: {firstName: "John",
lastName: "Doe",
shortName: "j.doe",
...some other items
}]
And I need to filter through the list based on a text input, which should search firstName+ " "+lastName. So searching He or Hello W will return Hello World, and searching Hellow wouldn't return it (case doesn't matter). What's the best way to filter the array? I've seen Angulars filter method but I've not yet worked out how to do it.
EDIT What I have
<div ng-controller="NotesCtrl">
<p>Search for a user to see there sessions and notes</p>
<input type="text" id="user" ng-model="search.firstName" />
{literal}
<ul>
<li ng-repeat="u in users | filter:search">{{u.activeDirectoryName}}</li>
</ul>
{/literal}
</div>
From what I've read that should work, but the list doesn't filter. Do I need to do anything in the controller to get this to work?
Answer: Turns out even though in PHP my data was an array, in Javascript it was an object, changed it around a bit so it came through as an array and it seems to be working now.

In your case, search should be a function in your controller that takes each item in the array and returns true or false depending if it passes the filter or not.

Related

Can you explain how the angular filter process works with this code?

I don't understand why the .name is happening in the model instead of the filter. I don't get what is happening behind the scenes when I create nameText.name and bind it to my data. How is my filter actually working?
<input type="text" data-ng-model="nameText.name" />
<input type="text" data-ng-model="nameText.city" />
<li data-ng-repeat="customer in customers | filter:nameText>
<script>
function FilteringController($scope) {
$scope.customers = [
{ name: 'Dave Jones', city: 'Phoenix' },
{ name: 'Jamie Riley', city: 'Phoenix' },
{ name: 'Heedy Wahlin', city: 'Chandler' },
{ name: 'Thomas Winter', city: 'Seattle' }
];
</script>
nameText is an object with the properties name and city in this case. These properties are filled by the input fields. You're filtering your list using an object. What Angular does in this case, is filter the objects in the list using the properties with the matching names. So, for example, if nameText.city is Phoenix, the items in the list are filtered so that only the items with Phoenix for the city property are left. This works the same for name and both can be combined.
Update to answer question in comments: For the exact implementation, I'd suggest looking through the Angular source code. The specific case for a filter using an object is here. What this roughly does is get all the properties of the object passed in as the filter (nameText in your case). It then goes through the list of objects to filter and select all the objects that have properties with values that match the properties that you are searching for. In the source code I referred, you can also see how the other types of search filters you may pass would be handled.

Angular filter by multiple properties and show if any value is equal to search

When using ng-repeat I want to filter object by two values (name and description). I want to filter this array in way if in any key exists value in search it will return it. When I'm trying this filter:{info:{name:search, description:search}} the result is when value from search equals in both.
Okay so based on what I have been able to understand. Although I am not sure if this is what you wanted, if not let me know and I will delete this answer.
Let's say you have object that has values in this format which you are feeding to ng-repeat.
$scope.inputobject = [
{name: 'xyz', description: 'hadhash'},
{name: 'uza', description: 'hadhahdh'},
{name: 'aaa', description: 'hadhahas'}
];
This is our HTML part now, add the controller and all, I hope that wont be a problem.
<input type="text" placeholder="search" ng-model="objectsearch">
<div ng-repeat="x in inputobject | filter:{name:objectsearch}">
<div>
{{x.name}} {{x.lastname}}
</div>
</div>
Now filter will only happen based on first input. Cheers!

How can i Apply filter by taking the arrays First value as Input On check?

Iam Learning AngularJs ...
Example : -
My Json Having an array with some values as types :-
Lets Say A Restaurant would be Mexican or Italian Etc
My example
{
name:'res 123',
description:'Italian Rest'
types:['Mexican','Indian']
}
<input type="checkbox" data-ng-model="Mexican"/> // Iam Using Textbox Oncheck Filter Need to Filter all the Objects with types:['Mexican']
Filter Code :-
<div class="col-xs-12" data-ng-repeat="obj in objs| filter : objs.types[1]: Mexican" > <!-- Filter applied Like this -->
Realted looping
</div>
How can i Apply filter by taking the types:['Mexican'] value as Input for Filter On check ?
A built-in filter in Angular accepts a hash that specifies by what properties to match against each element in an array.
So, if you have an array of restaurants:
var restaurants = [
{ name: "foo", types: ["Mexican", "Indian"] },
{ name: "bar", types: ["Mexican"] },
{ name: "baz", types: ["Italian"] }
];
then if you need to filter by name, the input to filter would be {name: 'b'} - which would give you "bar" and "baz".
Likewise, if you need to filter by types - even though it is an array - a similar approach would work: {types: "Mexican"}.
And so, you just need to construct that object - let's call it filterBy.
<input type="checkbox" ng-model="filterBy.types"
ng-true-value="'Mexican'"
ng-false-value="undefined"> Mexican
<div ng-repeat="r in restaurants | filter: filterBy>
{{r.name}}
</div>
Demo

Filter collection by child

I have the following fictional object which I'm trying to filter:
{
"0":{
"boy":{
"age":"32",
"name":"Daniel Grey"
}
},
"1":{
"boy":{
"age":"23",
"name":"John Doe"
}
}
}
And then, the ng-repeat directive looks like this:
<ul>
<li ng-repeat="person in people">{{person.boy.name}}<li>
</ul>
My question is, how do I filter people by "name"? I've tried:
<input type="text" ng-model="name">
<ul>
<li ng-repeat="person in people | filter:name">{{person.boy.name}}<li>
</ul>
... but nothing happens [ ng-model seems disconnected from the view! ].
Any response is much appreciated!
Thank you!
Updated answer as per OP's updates
Looking at your fiddle, your $scope.people is essentially an array with one big JSON object, with multiple nested boy objects. This is hard to work with. If you have control over the construction of the JSON object, I will suggest converting into an array of multiple JSON objects, which may look something like:
$scope.people = [
{
"name":"Daniel Grey",
"age":"32",
"gender": "male"
},
{
"name":"John Doe",
"age":"23",
"gender": "male"
}
];
Notice how I converted the boy key into the gender attribute.
If you really have absolutely no control over the data structure, you may have to come up with a custom filter to parse through the nested structure.
Take a look at this fiddle. A few things to pay attention to:
I have to specify people[0] in ng-repeat to retrieve the one big JSON object in your array.
The custom nameFilter searches the .boy.name attribute only.
Original Answer
If you want your filter by just name, you will have to specify the specific attributes in your ng-model directive. So in your case, it will be
<input type="text" ng-model="search.boy.name">
<ul>
<li ng-repeat="person in people | filter:search">{{person.boy.name}}<li>
</ul>
But first you will need to fix your JSON object.
UPDATE:
Live demo on fiddle. I did notice that the search-by-name-only filter doesn't work with angularjs 1.2.1, but works with angularjs 1.2.2.

In AngularJS, is it possible to filter inside of a specific element of an array using only a view?

I've got some data like this:
people = [
{
names: [
{first: "Joe", last: "Smith"},
{first: "Joseph", last: "Smith"},
...
]
},
...
]
In other words, an array of objects with an array of names. For example, a person could be called "Joe Smith" or "Joseph Smith". How can I use a filter to only search the first element of names? IE: If I typed in "Jo" or "Smith" it would find the first person. But, if I typed in "seph" it wouldn't.
I've been looking at the examples on this page, but there isn't really an example of filtering inside arrays. Here's what I've tried but it gives me an error:
<input ng-model="search.names[0].$">
TypeError: Cannot set property '$' of undefined
Working Code
Input HTML
<input ng-model="searchTerm">
Results
<tr ng-repeat="p in people | filter:searchFunc">...</tr>
Controller
$scope.searchFunc = function(person) {
var firstPersonsName = [person.names[0]]; // Wrapping in array since the 'filter' $filter expects an array
var matches = $filter('filter')(firstPersonsName, $scope.searchTerm); // Running firstPersonsName through filter searching for $scope.searchTerm
return matches.length > 0;
}
Plunker Demo
Answer to the question in your title
I played around with filter and it doesn't seem like you can go beyond one level deep when specifying a pattern object for it e.g. ng-model="search.names" works but ng-model="search.names.otherVal" doesn't.
Also, even if filter supported going beyond one level deep, you still wouldn't be able to do ng-model="search.names[0]". This is because filter expects the input to be an array, but the elements of your names array are all objects e.g. people[0].names[0] == {first: "Joe", last: "Smith"} so filtering will never work.
The only way to do what you are asking purely through the view and no extra code in your controller is to just create your own custom filter that handles your case.
Would this do the trick?
Say that your input is
<input ng-model="search.name" type="text">
Then, you can display results like this:
<div ng-repeat="person in people[0].names | filter: alias">...</div>
Controller:
$scope.alias = function (object) {
if (object.first.match(new RegExp($scope.search.name))) {
return true;
}
return false;
};

Resources