I have a JSON array and a search form with multiple filters. In this search form I have 4 select drop down fields for filtering. How can I search the JSON array based on what the user selects and then display the results after they hit the submit button?
For instance If the user selects "Burger" in the "Food Select Drop Down" field and "Coke" in the "Drink Select Drop Down" field. I want to be able to display all the restaurants that offer both of those items. Is this possible?
var restaurants = [
{"restaurant" : { "name" : "McDonald's", "food" : "burger", "drink" : "coke", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "KFC", "food" : "chicken", "drink" : "pepsi", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "Pizza Hut", "food" : "pizza", "drink" : "sprite", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "Dominos", "food" : "pizza", "drink" : "root beer", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "Popeyes", "food" : "chicken", "drink" : "mist", "content" : "Lorem ipsum dolor sit amet" }}
];
I have a JSON array and a search form with multiple filters. In this search form I have 4 select drop down fields for filtering. How can I search the JSON array based on what the user selects and then display the results after they hit the submit button?
For instance If the user selects "Burger" in the "Food Select Drop Down" field and "Coke" in the "Drink Select Drop Down" field. I want to be able to display all the restaurants that offer both of those items. Is this possible?
var restaurants = [
{"restaurant" : { "name" : "McDonald's", "food" : "burger", "drink" : "coke", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "KFC", "food" : "chicken", "drink" : "pepsi", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "Pizza Hut", "food" : "pizza", "drink" : "sprite", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "Dominos", "food" : "pizza", "drink" : "root beer", "content" : "Lorem ipsum dolor sit amet" }},
{"restaurant" : { "name" : "Popeyes", "food" : "chicken", "drink" : "mist", "content" : "Lorem ipsum dolor sit amet" }}
];
Share
Improve this question
edited Dec 31, 2013 at 1:25
user2402492
asked Dec 31, 2013 at 1:14
user2402492user2402492
671 gold badge2 silver badges10 bronze badges
4
- You can iterate through your JSON array and do conditional filtering where appropriate. Do you need an example for this? If so, please give us an example of your JSON array. You can add this in your post directly. – Jeff Renaud Commented Dec 31, 2013 at 1:17
- thank you for the quick reply. i edited my post and added an example of my json array. – user2402492 Commented Dec 31, 2013 at 1:26
-
Since you aren't using
angular.js
I won't put this as an answer but I'd remend using it for this particular case. Here is a live demo: jsfiddle/lacoolj/UACue and the documentation can be found here: docs.angularjs/tutorial/step_03 – Deryck Commented Dec 31, 2013 at 2:10 - Closer inline to your question, this would fit as a very basic starter: jsfiddle/lacoolj/2TvLH – Deryck Commented Dec 31, 2013 at 2:13
3 Answers
Reset to default 2One way to filter the array is the following
function filter( restaurants, food, drink) {
var result = [];
for( var i= 0, len = restaurants.length; i < len; i++) {
var el = restaurants.restaurant[i];
if( el.food === food && el.drink === drink ) {
result.push( el );
}
}
return result;
}
A more functional way
You can use the filter method defined in the Array prototype
function customFilter(food, drink) {
return function(el) {
var r = el.restaurant;
return r.food === food && r.drink === drink;
}
}
restaurants.filter( customFilter('Burger', 'Coke') );
Sophisticated, general use filter
function customFilter(values) {
return function(el) {
var r = el.restaurant;
var keys = Object.keys( values );
var answer = true;
for( var i = 0, len = keys.length; i < len; i++) {
if( r[keys[i]] !== values[keys[i]] ) {
answer = false;
break;
}
}
return answer;
}
}
restaurants.filter( customFilter({'food':'Burger', 'drink': 'Coke'}) );
JavaScript has a native Array.prototype.filter
which accepts a function. You simply want to generate this function when a user chooses the inputs, for example
function filter(a, food, drink) {
food = food ? food.toLowerCase() : 0;
drink = drink ? drink.toLowerCase() : 0;
return a.filter(function (e) {
if (food && e.restaurant.food.toLowerCase().indexOf(food) === -1)
return false;
if (drink && e.restaurant.drink.toLowerCase().indexOf(drink) === -1)
return false;
return true;
});
}
filter(restaurants, 'burger', 'coke');
// [{"restaurant":{"name":"McDonald's","food":"burger","drink":"coke","content":"Lorem ipsum dolor sit amet"}}]
I've gave my vote to Igor's answer, but, because I wanted to put a full example in jsfiddle, here you go: http://jsfiddle/jeffrenaud/JDYMt/
I've added the possibility to have an 'Any' options, so that there's no filter on a particular element.
Here's a summary:
HTML:
<label for="food">Food:</label>
<select id="food">
<option value="">Any</option>
<option value="burger">Burger</option>
<option value="chicken">Chicken</option>
<option value="pizza">Pizza</option>
</select>
<label for="drink">Drink:</label>
<select id="drink">
<option value="">Any</option>
<option value="coke">Coke</option>
<option value="pepsi">Pepsi</option>
<option value="sprite">Sprite</option>
<option value="root beer">Root beer</option>
<option value="mist">Mist</option>
</select>
<ul id="result"></ul>
JavaScript:
var restaurants = [
{
"restaurant": {
"name": "McDonald's",
"food": "burger",
"drink": "coke",
"content": "Lorem ipsum dolor sit amet"
}
},
{
"restaurant": {
"name": "KFC",
"food": "chicken",
"drink": "pepsi",
"content": "Lorem ipsum dolor sit amet"
}
},
{
"restaurant": {
"name": "Pizza Hut",
"food": "pizza",
"drink": "sprite",
"content": "Lorem ipsum dolor sit amet"
}
},
{
"restaurant": {
"name": "Dominos",
"food": "pizza",
"drink": "root beer",
"content": "Lorem ipsum dolor sit amet"
}
},
{
"restaurant": {
"name": "Popeyes",
"food": "chicken",
"drink": "mist",
"content": "Lorem ipsum dolor sit amet"
}
}
];
var $food = $('#food'),
$drink = $('#drink'),
$result = $('#result');
$food.change(function () {
onChange();
});
$drink.change(function () {
onChange();
});
function onChange() {
var findedRestaurants = findRestaurants();
showRestaurants(findedRestaurants);
}
function findRestaurants() {
return filter($food.find('option:selected').val(), $drink.find('option:selected').val());
}
function filter(food, drink) {
var result = [];
for (var i = 0; i < restaurants.length; i++) {
var restaurant = restaurants[i].restaurant;
if ((!food || restaurant.food === food) && (!drink || restaurant.drink === drink)) {
result.push(restaurant);
}
}
return result;
}
function showRestaurants(restaurants) {
$result.empty();
for (var i = 0; i < restaurants.length; i++) {
$result.append($('<li>' + restaurants[i].name + '</li>'));
}
}
onChange();