1const QUERY_INPUT_PLACEHOLDERS = [ 2 "Austen, Jane", "Shakespeare, William", "Homer", "Voltaire", "Swift, Jonathan", "Pope, Alexander" 3]; 4 5// Randomize text field placeholder 6document.getElementById('query__input_text').placeholder = QUERY_INPUT_PLACEHOLDERS[Math.floor(Math.random()*QUERY_INPUT_PLACEHOLDERS.length)]; 7 8var RESULTS_CONTAINER = document.getElementById('query__output'); 9var RESULTS_LIST = document.getElementById('query__results'); 10var NUMBER_RESULTS = document.getElementById('query__number-results_container'); 11var filter_images = false; 12var total_results_shown = 0; 13var number_displayed_results = 18; 14var category = ""; 15var query = ""; 16var query_tokens = []; 17var query_result = []; 18 19document.addEventListener('keypress', function(event){ 20 if(event.key == "Enter"){ queryCatalogue(); } 21}); 22 23function getFilterImages(){ 24 if(filter_images && query_result.length > 0){ 25 var resultWithImages = query_result.filter(function(bk){ 26 return (bk.images && (bk.images == "yes")); 27 }); 28 renderQuery(resultWithImages, query); 29 }else if(!filter_images && query_result.length > 0){ 30 renderQuery(query_result,query); 31 }else{ 32 renderQuery(query_result,query); 33 } 34} 35 36function pushBookToResults(book, id){ 37 book["id"] = id; // If found, add ID as param to book object 38 query_result.push(book); 39} 40 41// Return first instance found 42function checkBookAttributes(book, id) { 43 var keys = Object.keys(book); 44 keys.forEach(function(key){ 45 if(category == "pub_date"){ 46 for(var i = 0; i < query_tokens.length; i++){ 47 if(queryDatePublished(book, query_tokens[i])){ 48 pushBookToResults(book, id); 49 } 50 } 51 }else if (book[key]) { 52 var bk_value = book[key].toString().toLowerCase(); 53 for(var i = 0; i < query_tokens.length; i++){ 54 // For each value, check if token exists within it 55 if (bk_value.indexOf(query_tokens[i].toLowerCase()) > -1) { 56 pushBookToResults(book, id); 57 } 58 } 59 } 60 }); 61} 62 63// Turns inputs into tokens and normalizes them 64// TODO:: refactor to accept query and return array of tokens 65function tokenizeQuery(){ 66 if(query[0] == "\"" && query[query.length -1] == "\""){ 67 query_tokens.push(query.replace(new RegExp("\"",'g'),"")); //remove quotes 68 }else{ 69 query_tokens = query.split(' '); 70 query_tokens.push(query); 71 for(var i = 0; i < query_tokens.length; i++){ 72 query_tokens[i] = query_tokens[i].replace(/[.,\/#!$%\^&\*;:{}=\-_`~()\\]/g,""); // remove special characters 73 query_tokens[i] = query_tokens[i].replace(/\s{2,}/g," "); // ? 74 } 75 } 76 // If yes is searched, true is also relevant 77 if(query_tokens.indexOf("yes") > -1){ 78 query_tokens.push("true") 79 } 80} 81 82// TODO:: redo and optimize 83function queryCatalogue() { 84 RESULTS_LIST.innerHTML = ""; 85 category = document.getElementsByName('category')[0].value; 86 query = document.getElementsByName('query')[0].value; 87 query_tokens = []; 88 tokenizeQuery(); 89 filter_images = document.getElementById('query__check_filterImages').checked; 90 query_result = []; 91 92 if (category == "all") { 93 Object.keys(COMPLETE_DATA).forEach(function(id){ 94 checkBookAttributes(COMPLETE_DATA[id], id); 95 }); 96 } else { 97 // Specific Category Selected 98 // TODO:: place this into checkBookAttributes, this is repeated 99 if(category === "id"){ 100 query_tokens.forEach(token =>{ 101 if(COMPLETE_DATA[token]) pushBookToResults(COMPLETE_DATA[token], token) 102 }) 103 }else{ 104 Object.keys(COMPLETE_DATA).forEach( id => { 105 let book = COMPLETE_DATA[id]; 106 Object.keys(book).forEach( key =>{ 107 if (key.toString() == category) { 108 if(category == "pub_date"){ 109 for(var i = 0; i < query_tokens.length; i++){ 110 if(queryDatePublished(book, query_tokens[i])) pushBookToResults(book, id); 111 } 112 } 113 else{ 114 var bk_value = book[key].toString().toLowerCase(); 115 for(var i = 0; i < query_tokens.length; i++){ 116 if (bk_value.indexOf(query_tokens[i].toLowerCase()) > -1) { 117 pushBookToResults(book, id); 118 break; 119 } 120 } 121 } 122 } 123 }); 124 }); 125 } 126 } 127 128 // remove duplicate entries 129 // note: duplicate entries b/c book is added for every instance found per attribute 130 // TODO:: return book once instance found, parse book during printout 131 var flags = [], output = []; 132 for(var i = 0; i < query_result.length; i++) { 133 if( flags[query_result[i].id]) continue; 134 flags[query_result[i].id] = true; 135 output.push(query_result[i]); 136 } 137 query_result = output; 138 139 //sort by book id 140 query_result.sort(function(a,b){ 141 return a.id - b.id; 142 });
143 if(filter_images){ getFilterImages(); } 144 else{ renderQuery()}; 145} 146 147// Output results of query to DOM 148function renderQuery() { 149 RESULTS_CONTAINER.classList.add('query_hide-output'); 150 setTimeout(function() { 151 document.getElementById('query__show-more').classList.remove('query_hide-output'); 152 if (query_result.length == 0 || query == "") { 153 console.log('Query returned no results'); 154 NUMBER_RESULTS.innerHTML = "<p>The query returned no books.</p>"; 155 document.getElementById('query__results-shown').innerHTML =""; 156 document.getElementById('query__show-more').classList.add('query_hide-output'); 157 return; 158 } 159 NUMBER_RESULTS.innerHTML = "<p>Found <span id='query__number-results'>" + query_result.length + "</span> Books</p>"; 160 total_results_shown = 0; 161 number_displayed_results = 18; 162 if (number_displayed_results > query_result.length) { 163 number_displayed_results = query_result.length; 164 } 165 for (var i = 0; i < number_displayed_results; i++) { 166 total_results_shown++; 167 var bk = query_result[i]; 168 var bookInfo = ""; 169 170 // Highlights query in selected category 171 Object.keys(bk).forEach(function(attr){ 172 if (bk[attr] && attr != "folder") { 173 if (category == "all") { 174 if(attr == "link"){ 175 let external_link = `<a class="query_result__link-text" href="${bk[attr]}" target="_blank">${highlightQuery(bk[attr])}</a>` 176 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " +external_link + "</p>"; 177 }else{ 178 let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr]; 179 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(temp) + "</p>"; 180 } 181 } else if (category == attr) { 182 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category query__highlight-category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(bk[attr]) + "</p>"; 183 } else if(attr == "link"){ 184 let external_link = `<a class="query_result__link-text" href="${bk[attr]}" target="_blank">${bk[attr]}</a>` 185 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + external_link + "</p>"; 186 } else { 187 let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr]; 188 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + temp + "</p>"; 189 } 190 } 191 }); 192 193 var link = makeBookViewInLibraryAnchor(bk); 194 var output = "<li class='query__result_item'>" + bookInfo + "</li>"; 195 var wall_link = "<a href='" + link + "#bookID-" + bk.id + "'>" + output + "</a>"; 196 RESULTS_LIST.innerHTML += wall_link; 197 } 198 if (total_results_shown < query_result.length) { 199 document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length; 200 }else if(total_results_shown == query_result.length){ 201 document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length; 202 document.getElementById('query__show-more').classList.add('query_hide-output'); 203 } 204 }, 300); 205 setTimeout(function() { 206 RESULTS_CONTAINER.classList.remove('query_hide-output'); 207 }, 600); 208} 209 210function highlightQuery(string) { 211 var output = string; 212 for(var i = 0; i < query_tokens.length; i++){ 213 var regex = new RegExp(query_tokens[i], "gi"); 214 output = output.toString().replace(regex, '<span class="query__highlight">' + query_tokens[i] + '</span>'); 215 } 216 return output; 217} 218 219function showMoreResults() { 220 var count = total_results_shown + number_displayed_results; 221 if (count > query_result.length) { 222 count = query_result.length; 223 } 224 console.log("Total: " + total_results_shown + " ||Displayed: " + number_displayed_results + " ||Query Length: " + query_result.length + " ||count: " + count); 225 RESULTS_CONTAINER.classList.add('query_hide-output'); 226 setTimeout(function() { 227 for (var i = total_results_shown; i < count; i++) { 228 total_results_shown++; 229 var bk = query_result[i]; 230 var bookInfo = "";
231 Object.keys(bk).forEach(function(attr){ 232 if (attr != "folder" && bk[attr]) { 233 if (category == "all") { 234 let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr]; 235 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(temp) + "</p>"; 236 } else if (category == attr) { 237 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category query__highlight-category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + highlightQuery(bk[attr]) + "</p>"; 238 } else if(attr == "link"){ 239 let external_link = `<a class="query_result__link-text" href="${bk[attr]}" target="_blank">${bk[attr]}</a>` 240 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + external_link + "</p>"; 241 } else { 242 let temp = (bk[attr] === true || bk[attr] == "yes") ? "Yes" : bk[attr]; 243 bookInfo += "<p class='query_result__" + attr + "'><span class='query_result__category'>" + FORMAT_ATTR_NAME[attr] + "</span>: " + temp + "</p>"; 244 } 245 } 246 }); 247 248 var link = makeBookViewInLibraryAnchor(bk); 249 var output = "<li class='query__result_item'>" + bookInfo + "</li>"; 250 var wall_link = "<a href='" + link + "#bookID-" + bk.id + "'>" + output + "</a>"; 251 RESULTS_LIST.innerHTML += wall_link; 252 } 253 if (total_results_shown < query_result.length) { 254 document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length; 255 }else if(total_results_shown == query_result.length){ 256 document.getElementById('query__results-shown').innerHTML = total_results_shown + " / " + query_result.length; 257 document.getElementById('query__show-more').classList.add('query_hide-output'); 258 } 259 }, 300); 260 setTimeout(function() { 261 RESULTS_CONTAINER.classList.remove('query_hide-output'); 262 }, 600); 263} 264 265// Parses date_published string into INT 266function findDateRange(date_string){ 267 if(date_string){ 268 if(date_string.indexOf('-') > -1){ 269 return { 270 type : "ranged", 271 dates : date_string.split('-') 272 }; 273 }else if(date_string.indexOf(',') > -1){ 274 return { 275 type :"multipleDates", 276 dates : date_string 277 }; 278 }else{ 279 var regex = /\d+/g; 280 return { 281 type : "normal", 282 dates : parseInt(date_string.substring(date_string.search(regex))) 283 }; 284 } 285 }else{ 286 return{ 287 type: "null", 288 dates: "no dates" 289 }; 290 } 291} 292 293function queryDatePublished(bk,dateQuery){ 294 var parsed_date = findDateRange(bk.pub_date); 295 switch(parsed_date.type){ 296 case "ranged": 297 if(dateQuery >= parsed_date.dates[0] && dateQuery <= parsed_date.dates[1]) return true; 298 break; 299 case "multipleDates": 300 if(parsed_date.dates.indexOf(dateQuery) > -1) return true; 301 break; 302 case "normal": 303 if(parsed_date.dates == dateQuery) return true; 304 break; 305 default: 306 return false; 307 } 308}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.