-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
217 lines (170 loc) · 7.59 KB
/
Copy pathscript.js
File metadata and controls
217 lines (170 loc) · 7.59 KB
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/* All the JavaScript is here */
// Global variable to store the total of books finally displayed on the page
var booksShown;
var jsonCount;
/*
displayItem(item) -> Called from the JSON onload function in getDetails()
item: is an Object array extracted from JSON for 1 book to be displayed
*/
function displayItem(item){
//txtHTML -> String to add to the HTML after all elements are added
//first, the book cover, url and title
var txtHTML = "<div class='book'>"+
"<a href='" + item.url + "' target='_blank'>" +
"<img width='100%' src='" + item.cover.large + "' /></a>"+
"<div class='label'>"+
"<h4>" + item.title + "</h4>"+
"<strong>";
//if many authors -> display Authors: else if only 1 -> Author:
txtHTML += (item.authors.length>1) ? "Authors: " : "Author: ";
txtHTML += "</strong>"
//loops through the authors list to get each name with a comma between each that is not the last one
for (x=0;x<item.authors.length;x++){
txtHTML += item.authors[x].name;
if (x != item.authors.length -1) txtHTML += ", "
}
//displays only 1 publisher, the first one
txtHTML += "<br/><br/><strong>Publisher</strong>: " +
item.publishers[0].name + "<br/><br/>";
txtHTML += "<strong>"
//if many subjects -> display Subjects: else if only 1 -> Subject:
txtHTML += (item.subjects.length>1) ? "Subjects: " : "Subject: ";
txtHTML += "</strong>"
//loops through the subjects list with a maximum of 12 subjects
for (x=0;x<item.subjects.length;x++){
txtHTML += "<a href='" + item.subjects[x].url + "' target='_blank'>" +
item.subjects[x].name + "</a> ";
if (x > 12) break;
}
txtHTML += "</div>";
//insert the new HTML item <div> book at the beginning of the <div> books (container for flex boxes)
document.querySelector("#books").insertAdjacentHTML("afterBegin", txtHTML);
}
/*
getDetails(itemISBN, last) -> Called from a loop in getISBN()
itemISBN: is a String with a specific ISBN number for one item
last: is a boolean which indicates true when getISBN() has reached the last iteration of its loop
*/
function getDetails(itemISBN, itemsTotal){
//console.log("PRE---- bookShown:"+booksShown+", jsonCount:"+jsonCount);
//A fetch GET call to Open Library's API with the specific ISBN number added to the url
fetch("https://openlibrary.org/api/books?jscmd=data&format=json&bibkeys=ISBN:" + itemISBN ,{
method: "GET",
})
.then(response => response.json())
.then(function(json){
//When the JSON object is returnded from the API it is stored in item
jsonCount++;
let item = json[Object.keys(json)[0]];
let last = (itemsTotal == jsonCount) ? true : false;
//console.log("IN----last:"+last+", bookShown"+booksShown+", jsonCount:"+jsonCount);
//Tests if the returned object contains the desired values: title, cover, url, author, publisher and subject
if (Object.keys(json).length != 0 && item.title != null && item.cover != null && item.url != null && item.subjects != null && item.authors != null && item.publishers != null) {
//Global variable bookShown is incremented
booksShown++;
//if the object is valid it is displayed in HTML
//console.log("PRE-DISPLAY----last:"+last+", bookShown"+booksShown+", jsonCount:"+jsonCount);
displayItem(item);
}
if (last) {
console.log("INLAST----last:"+last+", bookShown"+booksShown);
if (booksShown === 0) {
alert("Couldn't find any book, try another search");
//console.log("IN-ALERT----last:"+last+", bookShown"+booksShown);
}else {
fadeTitle('fade-out','fade-in');
if (booksShown % 3 > 0){
//if true -> a number of hidden div (1 or 2) is added
//at the end of the flex container for a better look
for (x = 0; x < (3 - (booksShown % 3)); x++)
document.querySelector("#books").insertAdjacentHTML("beforeend", "<div class='book' style='opacity:0;'></div>");
}
}
//console.log("OUT----last:"+last+", bookShown"+booksShown+", jsonCount:"+jsonCount);
}
})
.catch(console.error);
}
/*
readISBN(xmlText) -> Called from the XML onload function in getISBN()
xmlText: is a String with a text in XML format returned from the API
*/
function readISBN(jsonObj){
//arrISBN: will contain the selected ISBN Strings that will be displayed
let arrISBN = [];
//Loops through all the titles in the XML Object
for (i = 0; i < jsonObj.data.results.length; i++) {
let isbn = jsonObj.data.results[i].id
let isbnSpt = isbn.split('-');
arrISBN[i] = isbnSpt[isbnSpt.length-1];
}
//If no book were stored alerts the user for a different search
if (arrISBN.length == 0) {
alert("Can't find any book, please try another keyword");
}else {
//console.log("ISBN:"+arrISBN);
//Loops through arrISBN from the end to the beginning
//Because items are pushed at the begining of the <div> books container
//So this way they will be displayed in the right order
for (i = arrISBN.length-1; i >=0 ; i--){
//console.log("i==0::"+arrISBN[i]);
//Calls getDetails() with boolean true when it's the last iteration
getDetails(arrISBN[i], arrISBN.length);
}
// Shows the 'Book List' title fade in animation
//fadeTitle('fade-out', 'fade-in');
}
}
/*
getISBN(keyword) -> Called from searchBooks()
keyword: is a String obtained from the user's input
*/
function getISBN(keyword){
//GET Request for a JSON Object from Penguin Random House's API with the keyword (query q) from the user
//A fetch GET call to Open Library's API with the specific ISBN number added to the url
fetch("https://api.penguinrandomhouse.com/resources/v2/title/domains/PRH.US/search?rows=100&docType=isbn&api_key=x2w6xdemsxy79fujj6z53hbh&q=" + keyword ,{
method: "GET",
})
.then(response => response.json())
.then(function(json){
//When the JSON object is returned from the API it is stored in item
//Callback function when the json is received
console.log(json);
readISBN(json);
})
.catch(console.error);
}
function fadeTitle(currentClass, newClass){
if (document.querySelector("#booktitle").classList.contains(currentClass)){
document.querySelector("#booktitle").classList.replace(currentClass, newClass);
} else document.querySelector("#booktitle").classList.add(newClass);
}
/*
searchBooks() -> Called from the EventListener when the user submits an input value
*/
function searchBooks(){
//Resets the page's state for a new Search and the booksShown global variable
//Deletes all previous books displayed in <div> books container, if any
//Fades out the 'Book List' title if it was displayed
booksShown = 0;
jsonCount = 0;
document.getElementById("books").innerHTML = "";
fadeTitle('fade-in', 'fade-out');
//keyword: stores the String of the user's input
let keyword = document.querySelector("#searchInput").value;
//If the input is not empty launch the json request
if (keyword != ""){
getISBN(keyword);
}else alert("Can't find any book, please enter a valid search");
}
/*
init() -> Called from the body onload
*/
function init(){
//Adds 2 listeners for the user's input, one fired when Search button is pressed
//the other with 'Enter' key pressed when in the input Search box
document.getElementById("searchBtn").addEventListener("click", searchBooks);
document.getElementById("searchInput").addEventListener("search", searchBooks);
//Hides the 'Book List' title before any search is made
document.querySelector("#booktitle").style.opacity = 0;
}