Building an e-Commerce website with Node – Part 38 – Instant search feature in Node.js

We are going to build an instant search feature for our application. In order to achieve that we are going to need three things.

  • A search API
  • We need to add additional HTML elements
  • A custom JavaScript file

Search API

Go to api folder and open the api.js file. In the file type the following code.

router.post('/search', function(req, res, next) {
  console.log(req.body.search_term);
  Product.search({
    query_string: { query: req.body.search_term }
  }, function(err, results) {
    if (err) return next(err);
    res.json(results);
  });
});

The URL is “search”.
The search (from Product.search) is a mongoosastic feature and req.body.search_term is where the user will type in the search query.
The response of the search will be in .json format which we will be using in the custom JavaScript file we are going to create.

Now open postman to test our api.

API test with Postman

The method has to be POST.
The address has to be http://localhost:3000/api/search
Key has to be serch_term and the value has to be computer.

Add additional HTML elements

Go to views/main folder and open the product-main.ejs file. If you don’t have the following code (as I remember I have included from the very beginning when we created the file) then type it now.

<p class="text-center">Search many of Ecommerce's products</p>
    <div class= "row">
      <div class="col-md-6 col-md-offset-3">
        <div class="input-group col-md-12">
          <input type="text" id="search" class="form-control input-lg" name="search_term" placeholder="Search for a Product ...">
          <span class="input-group-btn">
          <button type="submit" class="btn btn-primary btn-lg"><i class="glyphicon glyphicon-search"></i></button>
          </span>
        </div>
      </div>
    </div>

If you followed the previous posts then you should have the above code into the product-main.ejs file.

In order to see the search bar on the home page you have to be logged in.

A custom JavaScript file

In this custom JavaScript file we are going to write Ajax and Jquery code. Ajax is client-side script that can communicate with the server (the database) without a complete page refresh. The Jquery will manipulate the HTML elements to make our page more interactive.

Go to public/js folder (if you don’t have the js folder then create it) and create a new file named custom.js.
We also need to modify the file javascriptOnly.ejs which is under views/partials folder. Add in the javascriptOnly.ejs file the following line of code.

<script src="/js/custom.js"></script>

Let’s go back to the custom.js file. The HTML elements that are going to be manipulate have an id. We are going to use the id of the HTML elements to tell JavaScript which elements we are talking about in the code, since each id is unique.

In the custom.js type the following code.

$(function() {

  $('#search').keyup(function() {

    var search_term = $(this).val();

    $.ajax({
      method: 'POST',
      url: '/api/search',
      data: {
        search_term
      },
      dataType: 'json',
      success: function(json) {
        var data = json.hits.hits.map(function(hit) {
          return hit;
        });


        $('#searchResults').empty();
        for (var i = 0; i < data.length; i++) {
          var html = "";
          html += '<div class="col-md-4">';
          html += '<a href="/product/' + data[i]._source._id + '">';
          html += '<div class="thumbnail">';
          html += '<img src="' +  data[i]._source.image + '">';
          html += '<div class="caption">';
          html += '<h3>' + data[i]._source.name  + '</h3>';
          html += '<p>' +  data[i]._source.category.name  + '</h3>'
          html += '<p>$' +  data[i]._source.price  + '</p>';
          html += '</div></div></a></div>';

          $('#searchResults').append(html);
        }

      },

      error: function(error) {
        console.log(err);
      }
    });
  });

The keyup is a Jquery function which always listen to what you type in and imediatelly run the function that follows it to give you instant results as you type the search query, for example.

Let’s take a look at the following code that manipulates the HTML elements.

$('#searchResults').empty();
         for (var i = 0; i < data.length; i++) {
          var html = "";
          html += '<div class="col-md-4">';
          html += '<a href="/product/' + data[i]._source._id + '">';
          html += '<div class="thumbnail">';
          html += '<img src="' +  data[i]._source.image + '">';
          html += '<div class="caption">';
          html += '<h3>' + data[i]._source.name  + '</h3>';
          html += '<p>' +  data[i]._source.category.name  + '</h3>'
          html += '<p>$' +  data[i]._source.price  + '</p>';
          html += '</div></div></a></div>';

          $('#searchResults').append(html);
        }

The .empty() will empty the div element which has the id searchResults. You can see it in the product-main.ejs file.

Next, you add the elements to the HTML document. The elements that are added are the results of the search query.

Now, if you search for something the data should be displayed instantly without refreshing the page.

Leave a Reply