Simple JS Projects: Project 2: MovieInfo Search App

A simple responsive movie info search app built using vanilla.js, Bootswatch and jQuery. It uses session storage.The project that we will build will be using OMDB API and axios(Promise based HTTP client for the browser and node.js)

The project consists of two pages — HomePage and MoviePage . Bootswatch and custom CSS is used for styling.

Designing the HomePage

It’s a simple page with a navbar, an input field and a search button wrapped around jumbotron container and a class rowto display our movies results. You need to insert 3 scripts in this HTML file jquery, axiosand our custom main.js file.

Code for HomePage is given below

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
    <link
      href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM"
      crossorigin="anonymous"
    />
    <link rel="stylesheet" href="css/styles.css" />
    <title>MovieInfo App</title>
  </head>
  <body>
    <nav class="navbar navbar-default">
      <div class="container">
        <div class="navbar-header">
          <a href="index.html" class="navbar-brand">MovieInfo</a>
        </div>
      </div>
    </nav>
    <div class="container">
      <div class="jumbotron text-center">
        <h3 class="text-center">Search For Any Movie</h3>
        <form id="searchForm">
          <input
            type="text"
            class="form-control"
            id="searchText"
            placeholder="SearchMovie"
          />
          <button type="submit" class="btn btn-primary mt-4">Search</button>
        </form>
      </div>
    </div>
    <div class="container">
      <div id="movies" class="row"></div>
    </div>
    <script
      src="https://code.jquery.com/jquery-3.5.0.min.js"
      integrity="sha256-xNzN2a4ltkB44Mc/Jz3pT4iU1cmeR0FkXs4pru/JxaQ="
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="js/main.js"></script>
  </body>
</html>

Designing the MoviePage

It’s pretty similar to our HomePage with just an extra container with class well to display our movies details like title, actors, IMDb ratings, etc. We will add HTML dynamically using JS and you also need to call getMovie() enclosed in script tag which is defined in main.js

Code for MoviePage is given below

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <meta
      http-equiv="Content-Security-Policy"
      content="upgrade-insecure-requests"
    />
    <title>MovieInfo</title>
    <link
      href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM"
      crossorigin="anonymous"
    />
    <link rel="stylesheet" href="css/styles.css" />
  </head>
  <body>
    <nav class="navbar navbar-default">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="index.html">MovieInfo</a>
        </div>
      </div>
    </nav>

    <div class="container">
      <div id="movie" class="well"></div>
    </div>

    <script
      src="https://code.jquery.com/jquery-3.1.1.min.js"
      integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="js/main.js"></script>
    <script>
      getMovie();
    </script>
  </body>
</html>

Let’s play with OMDB API

The OMDb API is a RESTful web service to obtain movie information, all content and images on the site are contributed and maintained by different users.

Usage - Send all data requests to:

http://www.omdbapi.com/?apikey=[yourkey]&

Parameters - By ID/Title or By Search. You just need two:

s - Movie title to search for.

i - A valid IMDb ID (e.g. tt1285016)

What is Axios?

A axios is a promise based HTTP client for the browser and node.js

Features:

  • Make XMLHttpRequests from the browser
  • Make http requests from node.js
  • Supports the Promise API
  • Intercept request and response
  • Transform request and response data
  • Cancel requests
  • Automatic transforms for JSON data
  • Client side support for protecting against XSRF

To install axios run the below command

$npm install axios

Adding functionality with JS

We have to use $(document).ready(()=>{}) which executes when HTML-Document is loaded and DOM is ready and pass a callback to search for movies which executes when a user searches for a movie. We then need to call a getMovies() function which searches for the movie based on the search term.

$(document).ready(() => {
  $("#searchForm").on("submit", (e) => {
    let searchText = $("#searchText").val();
    getMovies(searchText);
    e.preventDefault();
  });
});

To display all the movies that match the search text you need to define a getMovies() where you make an API call to OMDb using axios.get() with searchText and apiKey as parameters. We have to use.each() jQuery for looping through the movies and tap onto movie Poster, Title and imdbID from data.Search response. We need to add this HTML to the homepage layout using .html()

function getMovies(searchText) {
  axios
    .get(
      "http://www.omdbapi.com/?s=" + encodeURI(searchText) + "&apikey=796a6593"
    )
    .then((response) => {
      console.log(response);
      let movies = response.data.Search;
      let output = "";
      $.each(movies, (index, movie) => {
        output += `
          <div class="col-md-3">
            <div class="well text-center">
              <img src="${movie.Poster}">
              <h5>${movie.Title}</h5>
              <a onclick="movieSelected('${movie.imdbID}')" class="btn btn-primary" href="#">Movie Details</a>
            </div>
          </div>
        `;
      });
      $("#movies").html(output);
    })
    .catch((err) => {
      console.log(err);
    });
}

Once you get all the movies related to the search text you can dig deeper into the details of single movie using id and render a page which contains all the details of a particular movie. You can also use SessionStorage for storing movieID.

function movieSelected(id) {
  sessionStorage.setItem("movieId", id);
  window.location = "movie.html";
  return true;
}

To display all the details of a particular movie you need to define a getMovie(). You can look for movieID if it exists in Session Storage and you have to make an API call just like you did above to get details of movies but with id and apiKey in the search query instead of searchText. You will get a response and you need to tap onto response.data to get the required properties like movie Poster Title Genre Released Rated imdbRating Director Writer Actors Plot imdbID . and dynamically add HTML using JS.

function getMovie() {
  let movieId = sessionStorage.getItem("movieId");
  axios
    .get("http://www.omdbapi.com/?i=" + movieId + "&apikey=796a6593")
    .then((response) => {
      console.log(response);
      let movie = response.data;
      let output = `
        <div class="row">
          <div class="col-md-4">
            <img src="${movie.Poster}" class="thumbnail">
          </div>
          <div class="col-md-8">
            <h2>${movie.Title}</h2>
            <ul class="list-group">
              <li class="list-group-item"><strong>Genre:</strong>${movie.Genre}</li>
              <li class="list-group-item"><strong>Released:</strong>${movie.Released}</li>
              <li class="list-group-item"><strong>Rated:</strong>${movie.Rated}</li>
              <li class="list-group-item"><strong>IMDB Rating:</strong>${movie.imdbRating}</li>
              <li class="list-group-item"><strong>Director:</strong>${movie.Director}</li>
              <li class="list-group-item"><strong>Writer:</strong>${movie.Writer}</li>
              <li class="list-group-item"><strong>Actors:</strong>${movie.Actors}</li>
            </ul>
          </div>
        </div>
        <div class="row">
          <div class="well">
            <h3>Plot</h3>
            ${movie.Plot}
            <hr>
            <a href="http://imdb.com/title/${movie.imdbID}" target="_blank" class="btn btn-primary">View IMDB</a>
            <a href="index.html" class="btn btn-default">Go Back To Search</a>
          </div>
        </div>
      `;
      $("#movie").html(output);
    })
    .catch((err) => {
      console.log(err);
    });
}

To make the app responsive you just need to add some CSS

#movies img,
#movie img {
  width: 100%;
}

@media (min-width: 960px) {
  #movies .col-md-3 .well {
    height: 390px;
  }

  #movies .col-md-3 img {
    height: 240px;
  }
}

.container .navbar-header {
  text-transform: uppercase;
}

HomePage before clicking Search

movieHomePage (2)

Hope you enjoyed this article! Happy Coding

blog