Welcome folks today in this blog post we will be building a book finder app in browser using google books api in vanilla javascript. All the full source code of the application is shown below.
Get Started
In order to get started you need to make an index.html
file and copy paste the following code
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!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"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="style.css"> <script src="main.js"></script> <title>Book Finder</title> </head> <body id="main"> <div class="booktit"><b>Book Finder</b></div> <div class="frm"> <input type="search" class="form-control" id="query" placeholder="Search for Books" autocomplete="off" autofocus> <input type="button" class="btn btn-success srcBtn" value="Search" name="btn" onclick="queryBooks()"> </div> <div class = "results" id="res"> <!-- <div class="card col-md-6" style="width: 32rem;" id="results"></div> --> <div id="query-display"></div> <div class="loader" id="load"></div> </div> </body> </html> |
As you can see guys we are importing the bootstrap cdn
for styling the app. Also we are importing the custom style file called style.css and also we are including the external javascript file which is main.js
. Now you need to copy paste the code inside the style.css
file as shown below
style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
body { background-color: #eeeeee; } .frm { width: 50%; position: relative; top: 25vh; /* left: 0vw; */ /* transform: translate(45%, 300%); */ margin: auto; display: flex; } @media screen and (max-width: 561px) { .frm { width: 70%; } } @media screen and (max-width: 492px) { .frm { width: 90%; } } .form-control { width: 80%; float: left; } .srcBtn { /* display: inline-block; */ /* vertical-align: middle; */ float: left; } .booktit { width: 50%; font-size: 48px; color: #696969; position: absolute; top: 10vh; left: 35vw; /* transform: translate(67%, 70%); */ /* margin: auto; */ } @media screen and (max-width: 561px) { .booktit { width: 100%; font-size: 42px; left: 25vw; } } @media screen and (max-width: 492px) { .booktit { width: 80%; left: 20vw; font-size: 36px; /* margin-bottom: 5px; */ } } .card-img-top { min-width: 28%; max-width: 32%; height: 15vw; display: inline-block; vertical-align: middle; object-fit: cover; /* padding: 10px; */ transform: translateY(-15%); box-shadow: 5px 5px 5px -3px #888888; } @media screen and (max-width: 492px) { .card-img-top { height: 25vh; min-width: 50%; transform: translateY(-15px); object-fit: none; margin-bottom: 10px; } } .results { background-color:#ddd; position: relative; padding: 2em; top: 30vh; width: 100%; /* height: 100vh; */ min-height: 62vh; float: left; } .card-body { /* float: left; */ display: inline-block; transform: translateY(-30px); } .card-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card { float: left; margin: 2.5%; width: 100%; box-shadow: 5px 5px 5px -3px #888888; } @media screen and (max-width: 492px) { .card { margin: 5%; margin-left: 1%; } } #query-display { font-size: 30px; font-weight: 500; text-transform: capitalize; margin-bottom: 20px; } @media screen and (max-width: 492px) { #query-display { font-size: 24px; } } /* Page loader */ .loader { border: 12px solid #f3f3f3; border-radius: 50%; border-top: 16px solid #218838; border-bottom: 16px solid #218838; width: 100px; height: 100px; -webkit-animation: spin 2s linear infinite; animation: spin 2s linear infinite; position: absolute; left: 43.5vw; display: block; z-index: 9999; } @media screen and (max-width: 492px) { .loader { border: 8px solid #f3f3f3; border-radius: 50%; border-top: 12px solid #218838; border-bottom: 12px solid #218838; width: 80px; height: 80px; -webkit-animation: spin 2s linear infinite; animation: spin 2s linear infinite; position: absolute; left: 40vw; display: block; z-index: 9999; } } @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } |
Now if you open the index.html
file inside the browser the user interface will look something as shown below
As you can see we have the simple search input field where we can search for books and then we have the button to search the books. Now we need to write the javascript code required for this application. Just make a main.js
file and copy paste the below code. Now first of all you need to add this javascript code
inside the index.html
file so that whenever the user presses any key on the keyboard we detect it and then call the api to search for books
1 2 3 4 5 6 7 8 9 |
<script> var loader = document.getElementById("load"); loader.setAttribute('style', 'display: none;'); document.getElementById("query").onkeypress = function(event){ if (event.keyCode == 13 || event.which == 13){ queryBooks(); } }; </script> |
Now we need to write this queryBooks()
function which will be there inside the main.js
file so the code looks like as shown below
main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
var verify_existance = false; function queryBooks() { const QUERY = (document.getElementById("query").value).toLowerCase(); var results = document.getElementById("res"); loader.setAttribute('style', 'display: block;'); var query_display = document.getElementById("query-display"); if (verify_existance == true) { results.remove(results); results = document.createElement('div'); results.setAttribute('id', 'res'); results.setAttribute('class', 'results'); loader = document.createElement('div'); loader.setAttribute('class', 'loader'); loader.setAttribute('id', 'load'); query_display = document.createElement('div'); query_display.setAttribute('id', 'query-display'); results.appendChild(loader); results.appendChild(query_display); document.getElementById('main').appendChild(results); } query_display.innerHTML = "Related results for \"" + QUERY + "\""; const URL = "https://www.googleapis.com/books/v1/volumes?q=" + QUERY var request = new XMLHttpRequest(); // Open a new connection, using the GET request on the URL endpoint request.open('GET', URL, true); request.onload = function () { // Begin accessing JSON data here for (var i = 0; i < 10; i++) { var data = JSON.parse(this.response); // console.log(data) var authors = (data["items"][i]["volumeInfo"]["authors"]) || 'No Author Disclosed' var title = (data["items"][i]["volumeInfo"]["title"]) || 'No title Disclosed' var publisher = (data["items"][i]["volumeInfo"]["publisher"]) || 'No publisher Disclosed' try { var thumbnail = data["items"][i]["volumeInfo"]["imageLinks"]["thumbnail"] } catch (err) { var thumbnail = 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Georgia_404.svg/1125px-Georgia_404.svg.png' } var info = (data["items"][i]["volumeInfo"]["infoLink"]) || 'No info Disclosed' card = document.createElement('div'); card.setAttribute('class', 'card col-md-6'); card.setAttribute('style', 'max-width: 32rem;'); card.setAttribute('id', 'results'); const logo = document.createElement('img'); logo.src = thumbnail; logo.className = "card-img-top" card.appendChild(logo); const card_body = document.createElement('div'); card_body.setAttribute('class', 'card-body'); const card_title = document.createElement('h5'); card_title.setAttribute('class', 'card-title'); card_title.innerHTML = title; card_body.appendChild(card_title); const card_text = document.createElement('p'); card_text.setAttribute('class', 'card-text'); card_text.innerHTML = "By: " + authors + "<br>Published By: " + publisher; card_body.appendChild(card_text); const button = document.createElement('a'); button.setAttribute('class', 'btn btn-primary btn-md'); button.setAttribute('href', info); button.innerHTML = "See this Book" card_body.appendChild(button); card.appendChild(card_body); results.appendChild(card); } } verify_existance = true; // Send request request.send() document.getElementById('query').value = '' setTimeout("loader.setAttribute('style', 'display: none;')", 1500); } |
So now if you open the index.html
file you can search your favourite book as shown below