Caspert
Caspert

Reputation: 4363

How to search in JSON file?

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

Answers (4)

trincot
trincot

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

Miguel
Miguel

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

RomanPerekhrest
RomanPerekhrest

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

Richard
Richard

Reputation: 16762

The solution has a few steps, let us know which step you can't do:

  1. Call a JS function when the user clicks the button
  2. Read the file from disk on the server into a JS variable in the browser
  3. Use lodash.js to get the url from the JS variable for the search term
  4. Display results to the user

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

Related Questions