Reputation: 4232
I currently have a method to search some product data which looks similar to this
function search(title) {
var result = [];
for (i = 0; i < data.length; i++) {
if (data[i].title.indexOf(title) > -1) {
result.push(data[i]);
}
}
return result;
}
Which works when trying to search my data for a product whose title contains the title being searched for. The title is passed in via an input.
However, I would to be able to perform a search for multiple properties and not just the title.
So, for example, say If I have 4 inputs like title, id, location, price and you can search for as many or as few of these as you like. So you can search for one at a time, two at time etc...
How should I approach this without having to write a completely new function? Would it be something similar like
function search(params) {
var result = [];
for (i = 0; i < data.length; i++) {
if (look for all params being searched for here) {
result.push(data[i]);
}
}
return result;
}
Edit: Just to show how I would pass the data
View
<input ng-model="params.one">
<input ng-model="params.two">
<input ng-model="params.three">
<input ng-model="params.four">
Controller
$scope.search = function() {
var params = $scope.params;
// call search service which uses the above function...
}
Upvotes: 0
Views: 1264
Reputation: 40790
So let's assume your example looks like this:
var data = [{"title": "foo", "description": "blabla", "yada": "yada"}, {..}];
and now you want to call
search({"title": "f", "yada": "da"});
To find elements with titles that include "f" and all elements with yadas that contain "da". Let's divide and conquer. First we create a method that tells us whether an item matches your search or not:
function matchItem(item, searchParams) {
for(var propertyToLookFor in searchParams) {
var valueToLookFor = searchParams[propertyToLookFor];
if (item[propertyToLookFor].indexOf(valueToLookFor) >= 0) {
return true;
}
}
return false;
}
What you need to know is of course the for-in loop which iterates over the properties of an object. And objects can be accessed just like arrays, using properties as indexes. So myObject.foo
is the same as myObject['foo']
which is the same as var someVar = 'foo'; myObject[someVar];
Now the simplest thing to apply the matcher we created is to use built in filter-method of arrays:
var filteredResult = data.filter(function(item) {
return matchItem(item, {"title": "f", "yada": "da"});
});
however you can also slightly adapt your method which searched only for title:
function search(searchParams) {
var result = [];
for (i = 0; i < data.length; i++) {
if (matchItem(data[i], searchParams)) {
result.push(data[i]);
}
}
return result;
}
Since you obviously use angularJS: Angular has a built-in filter filter which already does pretty much everything I just described. Use it like this:
var filteredData = $filter('filter')(data, {"title": "f", "yada": "da"})
Actually the API reference of filter includes an example that looks pretty much exactly like what you are trying to do, including the HTML.
Upvotes: 1