Reputation: 4363
How could I create a search form that will search for the entered term inside a JSON file?
So if the search term is equal to a title inside the location object, it should return that object info. If there is no match, give the user feedback that there are no items found
I created a search input:
<form action="" method="get">
<input id="search" type="text" placeholder="Search term">
<input type="submit" class="button">
</form>
My JSON looks like this:
{
"title": "Locations",
"locations": [
{
"title": "New York",
"url": "api/newyork.js"
},{
"title": "Dubai",
"url": "api/dubai.js"
},{
"title": "Netherlands",
"url": "api/netherlands.js"
},{
"title": "Lanzarote",
"url": "api/lanzarote.js"
},{
"title": "Italy",
"url": "api/italy.js"
}
]
}
Update:
I came up with the following, using jQuery:
$("#search").change(function() {
var arrival = $(this).val();
$.getJSON( "api/videoData.js")
.done(function(data) {
// update your ui here
console.dir(data.pages);
var dataArr = data.pages;
// Iterate over each element in the array
for (var i = 0; i < dataArr.length; i++){
// look for the entry with a matching `code` value
if (dataArr[i].title == arrival){
// we found it
console.log(dataArr[i].title);
} else {
console.log('Houston, we have a problem');
}
}
}).fail(function(data) {
// handle error here
console.log('no results found');
});
});
This is working, only it should be entered exactly as stored in the JSON.
So when you search for "Italy" and you use lowercase type, it will not find the object. Also it will not give any entries when you search for example: ne
. I would like to get Netherlands and New York as search results.
Upvotes: 5
Views: 36161
Reputation: 350137
Here is a snippet that demonstrates how the lookup could be done. It only loads the JSON once. I have included the test data for when the JSON request fails, which it will in this demo. At every change of the input value a short list of matches is shown in a div
below the input
. The submit button is not included, as the search is immediate.
Try it.
// testData is defined for demo only. Can be removed
var testData = [
{
"title": "New York",
"url": "api/newyork.js"
},{
"title": "Dubai",
"url": "api/dubai.js"
},{
"title": "Netherlands",
"url": "api/netherlands.js"
},{
"title": "Lanzarote",
"url": "api/lanzarote.js"
},{
"title": "Italy",
"url": "api/italy.js"
}
];
// Variable to hold the locations
var dataArr = {};
// Load the locations once, on page-load.
$(function() {
$.getJSON( "api/videoData.js").done(function(data) {
window.dataArr = data.pages;
}).fail(function(data) {
console.log('no results found');
window.dataArr = testData; // remove this line in non-demo mode
});
});
// Respond to any input change, and show first few matches
$("#search").on('keypress keyup change input', function() {
var arrival = $(this).val().toLowerCase();
$('#matches').text(!arrival.length ? '' :
dataArr.filter(function(place) {
// look for the entry with a matching `code` value
return (place.title.toLowerCase().indexOf(arrival) !== -1);
}).map(function(place) {
// get titles of matches
return place.title;
}).join('\n')); // create one text with a line per matched title
});
// submit button is not needed really
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="search" type="text" placeholder="Search term">
<div id="matches" style="height:70px; overflow-y:hidden; white-space:pre"></div>
Upvotes: 2
Reputation: 1636
As you said in your update with this code:
So when you search for "Italy" and you use lowercase type, it will not find the object. Also it will not give any entries when you search for example: ne. I would like to get Netherlands and New York as search results.
$("#search").change(function() { var arrival = $(this).val();
$.getJSON( "api/videoData.js", { arrivalDate: arrival })
.done(function(data) {
// update your ui here
console.dir(data.pages);
var dataArr = data.pages;
// Iterate over each element in the array
for (var i = 0; i < dataArr.length; i++){
// look for the entry with a matching `code` value
if (dataArr[i].title == arrival){
// we found it
console.log(dataArr[i].title);
} else {
console.log('Houston, we have a problem');
}
}
}).fail(function(data) {
// handle error here
console.log('no results found');
});
});
Replace this line:
if (dataArr[i].title == arrival){
for
if (dataArr[i].title.toLowerCase().contains(arrival.toLowerCase())){
And now it will match all the string that contains the string that you are searching...
Upvotes: 0
Reputation: 92854
If you intend your json file as static and not very huge one then you better load it at once on page load event(preventing sending the same requests dozens of times). Try this approach:
var xhr = new XMLHttpRequest(),
locations = {};
xhr.overrideMimeType("application/json");
xhr.open('GET', 'locations.json', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == "200") {
var content = JSON.parse(this.response),
locations_arr, i, count, title;
locations_arr = content['locations'];
for (i = 0, count = locations_arr.length; i < count; i++) {
title = locations_arr[i]['title'].toLowerCase();
locations[title] = locations_arr[i];
}
console.log(locations);
}
};
xhr.send(null);
Add some identifier to your form element (id="myForm"
) and 'name' attribute to your input field (name="search"
);
document.getElementById('myForm').onsubmit = function() {
var search_value = this.search.value.trim().toLowercase();
if (search_value && location[search_value]) {
console.log(location[search_value]);
} else {
alert("Object with specified title not found!");
}
// You must return false to prevent the default form behavior
return false;
}
Upvotes: 1
Reputation: 16762
The solution has a few steps, let us know which step you can't do:
But taking a stab at the simplest answer, the way I'd do it:
Load your JSON file with the page, like any Javascript file. Load lodash.js.
Call your JSON file towns.js and make it look like this:
var cities =
{
"title": "Locations",
"locations":
[
{
"title": "New York",
"url": "api/newyork.js"
},
{
"title": "Dubai",
"url": "api/dubai.js"
}
]
}
And then your HTML is something like this:
<input type="" class="button" onclick='go()'>
<script src='towns.js' />
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js' />
<script>
function go()
{
var name = document.getElementById('search').value;
var result = _.find(cities.locations, {'title': name});
if (!result)
window.alert('Nothing found');
else
window.alert('Go to ' + result.url);
}
<script>
Upvotes: 1