I have the user object defined as below.
$scope.user = [{id: 1, friends:
[
{name: 'John', age: 21, sex: 'M'},
{name: 'Brad', age: 32, sex: 'M'}
]
}]
I have the following code:
<input type="text" ng-model="searchText">
<div ng-repeat="friend in user.friends | filter:searchText">
{{friend.name}} {{friend.age}}
</div>
Here whenever I search, I get results for name, age as well as sex. But I want to search only for name and age and I don't want sex to be searchable. Can anyone help me with how I can achieve this?
You can pass an object as the second parameter to achieve this if you can have two search fields
<div ng-repeat="friend in user.friends | filter:{name:searchNameText, age:searchAgeText}">
Otherwise you'll need to write a custom filter to use the same field for both, or pass a custom filter function as the third parameter which is described in the docs.
http://docs.angularjs.org/api/ng.filter:filter
I'm not sure if this is what you are after. If you want to have one input field to matched multiple properties you need a filter function to be passed to filter.
$scope.user = {id: 1, friends: [{name: 'John', age: 21, sex: 'M'}, {name: 'Brad', age: 32, sex: 'M'}, {name: 'May', age: 64, sex: 'F'}]};
$scope.searchFilter = function (obj) {
var re = new RegExp($scope.searchText, 'i');
return !$scope.searchText || re.test(obj.name) || re.test(obj.age.toString());
};
Here's a fiddle example
http://jsfiddle.net/fredrik/26fZb/1/
This is not the cleanest way to accomplish what you want, but it is the simplest way to accomplish an OR filter using the standard ng-repeat filter.
Controller:
$scope.user = [{id: 1, friends:
[
{name: 'John', age: 21, sex: 'M'},
{name: 'Brad', age: 32, sex: 'M'}
]
}]
$scope.buildSearchData = buildSearchData;
function buildSearchData(friend){
return friend.name + ' ' + friend.age;
}
HTML
<input type="text" ng-model="searchText">
<div ng-repeat="friend in user.friends | filter:{searchData:searchText}"
ng-init="friend.searchData = buildSearchData(friend)">
{{friend.name}} {{friend.age}}
</div>
"friend in user.friends | json | filter:{something:somethingtext}"
http://docs-angularjs-org-dev.appspot.com/api/ng.filter:json
Another possible approach is to create an aggregate field that contains the values of all of the fields you want to filter on concatenated and only filter on that.
Related
I am reduce an array of object into a single object that should look like this :
`
result = {
23 : [{obj of kyle}, {obj of jade}],
29 : [{obj of ruby}]
32 : [{obj of mat}]
}
`
I have used reduce to do this, each person variable will refer to an object of the array to reduce, and they all collapse into a single object refered to with the variable group, the initial value of that object is an empty object {}, so with an if statement i checked first if it's empty, then create a key named age with a new empty array as value and push the person object into that empty array, and if the key age exists, then skip the new array creation and push that corresponding person object into the corresponding array.
what's wrong with this code?
`
const people = [
{name: "kyle", age: 23},
{name: "jade", age: 23},
{name: "ruby", age: 29},
{name: "mat", age: 32}
]
let result = people.reduce(function(person, group){
const age = person.age;
if(group[age]==null){
group[age] = []
}
group[age].push(person);
return group
},{})
console.log(result);
`
not what i expected
Looking again at your code it seems that you can fix your own code by replacing person and group in your callback function inside reduce like so
const people = [
{name: "kyle", age: 23},
{name: "jade", age: 23},
{name: "ruby", age: 29},
{name: "mat", age: 32}
]
let result = people.reduce(function(group, person){
const age = person.age;
if(group[age]==null){
group[age] = []
}
group[age].push(person);
return group
},{})
console.log(result);
You can do something like this as well
const people = [
{name: "kyle", age: 23},
{name: "jade", age: 23},
{name: "ruby", age: 29},
{name: "mat", age: 32}
];
const result = people.reduce((acc, curr) => {
if (!acc[curr.age]) {
return {...acc, [curr.age]: [curr]}
}
return {...acc, [curr.age]: [...acc[curr.age], curr]};
}, {});
console.log(result);
What we did here is initiating it with a new object like you did, then for each element in the array denoted as curr for current we check if our new object (denoted as acc for accumulator) has a key with this age already of curr.age. If not we make an array for this age and put the current element inside.
Else, if this age key already exist just add to that age array the current element.
Hello everyone I am beginner at react. I want to search i my state which array of object I write the following function for the search. It works perfectly fine in Console.log();
But not working in real dom thanks in advance
categorySearch(event){
const filteredElements =
this.state.data.filter(categoryObject => categoryObject.name.includes(event.target.value));
this.setState({filteredElements: filteredElements});
console.log(filteredElements);
}
here is code for list
this.state.data.map((item,index) => {
return (
<div key={index} id="area">
<h3>{item.name}</h3>
<div id="overflowTest"><List lists={item.lists} handle={this.handleItemClicked} /> </div>
</div>
)
}
Let's say this is your JSON
[
{name: "John", id: 120, age: 22, gender: "male"},
{name: "Beth", id: 443, age: 24, gender: "female"},
{name: "Jane", id: 510, age: 19, gender: "female"}
]
And now if you want to render this you have to write as shown below
render() {
return(
<ul>
{this.state.users.map(function(user, i){
return <li key={i}>{user.name}</li>
)}
</ul>
)
}
This is a simple example of rendering the JSON. Since I've no idea about your state data I have taken a sample array to show you how the rendering works.
I hope this helps you. Thanks.
I'm using angular and ng-repeat to iterate over data. I want to show only items where purchased-used <=5, but it is showing 5, 4, 55, 3, 33, 2, etc., as the result set where it should only show 5,4,3,2.
$scope.users = [{
first_name: 'Richard',
last_name: 'Grayson',
purchased: 50,
used: 10,
},
{
first_name: 'Donna',
last_name: 'Troy',
purchased: 6,
used: 3,
}]
And then on the page:
<tr ng-repeat="user in users | filter:user.purchased-user.used<=5:true">
Dick should not show in the list, but Donna should. They both show up though.
I know I could write a function for the filter, but this seems like such a simple comparison that I shouldn't have to. It seems like it should work, but there's something I'm missing.
Thanks!
You just have to make a custom filter:
$scope.customFilter = function(user){
return user.purchased-user.used <= 5;
};
And call it from your repeater:
<tr ng-repeat="user in users | filter: customFilter">
I have an application where I want to filter a long list of products based on value from "select" containing product types. The filter works, but only after I select something. It initially sets the "Show All" option, but filters out everything. If I select something else, it works, and if I re-select "Show All" it works. But why doesn't the filter work initially?
The model (looks something like this):
$scope.products = {[
{name: 'productA',Type: 1},
{name: 'productB',Type: 1},
{name: 'productC',Type: 2},
{name: 'productD',Type: 2},
]};
$scope.productTypes = {[
{Name: 'typeAlpha',Type: 1},
{Name: 'typeBravo',Type: 2},
]};
The HTML:
<select id="productFilter" data-ng-model="productFilter">
<option value="" selected="selected">Show all</option>
<option data-ng-repeat="type in productTypes" value="{{type.Type}}">{{type.Name}}</option>
</select>
<p data-ng-repeat="product in products | filter:{Type:productFilter} ">{{product.Name}}</p>
I recommend using ng-options instead of ng-repeat over the options:
<select id="productFilter" ng-model="productFilter"
data-ng-options="type.type as type.name for type in productTypes">
<option value selected="selected">Show all</option>
</select>
<p data-ng-repeat="product in products | filter:(!!productFilter || undefined) && {type: productFilter}">
{{product.name}}
</p>
For "show all", the filter must return undefined (ng-repeat filter "show all" items if no filter selected)
Also removed the {..} around the array and better use lower case for properties:
$scope.products = [
{name: 'productA', type: 1},
{name: 'productB', type: 1},
{name: 'productC', type: 2},
{name: 'productD', type: 2}
];
$scope.productTypes = [
{name: 'typeAlpha', type: 1},
{name: 'typeBravo', type: 2}
];
Here is a jsbin (based on Hiskinds)
http://jsbin.com/yepaqikodo/1/edit?html,js,output
This is a working example based on code above: http://jsbin.com/buzafisuko/edit?html,js,output
The Slava.N's comment is correct and you should not wrap productTypes and product in {}
Also, JavaScript is a case-sensitive language, product.Name is always undefined, you should use product.name in your HTML instead.
Use product.Type instead ofType inside 2nd ng-repeat filter
you set $scope.productFilter = ''.
so its return by default value blank at filter.
I would like to filter an employee object array using $filter('filter') to filter the results based on an employee's first name field ONLY that can be selected from the drop down/select. Notes that I do NOT want to use the "| filter:" in the ng-repeat".
The difficulty is that the name field is a property of another field called 'details', so I can't details.name like the code below because it will error.
$scope.filteredEmployees = $filter('filter')(employees, {details.name: selectedName });
See below for structure of the employee array object.
How can I tell it to filter the records based on details.name field using $filter('filter')?
Thank you in advance for your help!
Here is the code:
Var selectedName = “An”;
$scope.filteredEmployees = $filter('filter')(employees, {**details.name:** selectedName });
Var employees = [
{
Date: 01/01/2012
details: {
name: ‘An’,
age: 25
}
},
{
Date: 01/01/2012
details: {
name: ‘'Bill',
age: 20
}
}];
//Here is
<select ng-model="selectedName" ng-options="e for e in employees" data-ng-show="employees.length > 0" ng-change="filterEmployees">
<option value="">All Employees</option>
</select><br>
function filterEmployees() {
$scope.filteredEmployees = $filter('filter')(employees, "Joe");
};
The expression can be a map of property-to-filters: where each property in the object maps to a corresponding property within the result set.
$filter('filter')(employees, {name:"Joe"});
Live Demo
Using A Custom Function
If your data is more complex, and you need more advanced filtering, then you can simply pass in a custom predicate function to evaluate whether or not an item should be filtered.
The input of the function takes each item of the array as an argument, and is expected to return false if the item should be excluded from the result set.
var people = [{date:new Date(), details:{
name: 'Josh',
age: 32
}}, {date:new Date(), details:{
name: 'Jonny',
age: 34
}}, {date:new Date(), details:{
name: 'Blake',
age: 28
}}, {date:new Date(), details:{
name: 'David',
age: 35
}}];
$scope.filteredPeople = $filter('filter')(people, function(person){
return /^Jo.*/g.test(person.details.name);
});
Live Demo