user2085143
user2085143

Reputation: 4232

Javascript Search Multiple Params

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

Answers (1)

yankee
yankee

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

AngularJS

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

Related Questions