implements the book finder using jquery + ajax#2
Conversation
| </p> | ||
| </footer> | ||
| </body> | ||
| <script src="jquery-3.5.1.js"></script> |
There was a problem hiding this comment.
To use jQuery, I downloaded the latest version from the jQuery website. I picked the unminified, full-featured version.
Here, it's being loaded before the Book Finder script, because we need jQuery to be loaded first since we're using it inside script.js.
| const booksDisplay = document.getElementById("books-display"); | ||
| const $msgWaiting = $(".message-waiting"); | ||
| const $searchForm = $("#search-form"); | ||
| const $booksDisplay = $("#books-display"); |
There was a problem hiding this comment.
Naming the variables starting with a $ (as in $msgWaiting) is not necessary, but a common convention. This convention is used because it quickly lets a developer know that the variables reference jQuery objects, not DOM nodes directly.
This is important, because to interact with these objects we have to use jQuery functions, not vanilla JS DOM functions.
There was a problem hiding this comment.
Also note that we're using jQuery's CSS-style selector syntax to look up elements in the DOM.
| searchForm.addEventListener("submit", () => { | ||
| msgWaiting.style.display = "none"; | ||
| const searchInput = document.getElementById("search-input").value; | ||
| $searchForm.on("submit", () => { |
There was a problem hiding this comment.
This is using jQuery's on function to bind an event handler for submit.
| msgWaiting.style.display = "none"; | ||
| const searchInput = document.getElementById("search-input").value; | ||
| $searchForm.on("submit", () => { | ||
| $msgWaiting.hide(); |
There was a problem hiding this comment.
jQuery's hide function more-or-less will do the same thing as setting the display property to none, only it's a bit more clever based on the initial display property of the element(s) being hidden.
| const searchInput = document.getElementById("search-input").value; | ||
| $searchForm.on("submit", () => { | ||
| $msgWaiting.hide(); | ||
| const searchInput = $("#search-input").val(); |
There was a problem hiding this comment.
Because we're working with jQuery obejcts, we need to use the jQuery val function to grab the value of the input.
| datatype: "json" | ||
| }).done((booksData) => { | ||
| displayBooks(booksData.items); | ||
| }); |
There was a problem hiding this comment.
This is the core part of this demo: the difference between the newer fetch API, and the more legacy (but still used) jQuery + Ajax approach.
When making an Ajax request, you don't need to specify the method if you're making GET requests, or the datatype because jQuery will (usually) infer it on its own. But it doesn't hurt to have a bit more clarity and resilience.
Note also that the ajax function returns a Promise, so we can use the Promise API to bind a callback for what to do once the Ajax request is successful.
| function displayBooks(books) { | ||
| // clear any previous results | ||
| booksDisplay.innerHTML = ""; | ||
| $booksDisplay.empty(); |
There was a problem hiding this comment.
This jQuery function clears out all the contents of a selected jQuery node.
| let smallThumbnail = getThumbnail(volumeInfo); | ||
|
|
||
| let bookDiv = document.createElement("div"); | ||
| let $bookDiv = $("<div>").addClass("book-styling"); |
There was a problem hiding this comment.
The jQuery syntax for creating new DOM nodes is ... horrible. It works well enough for a quick addition, like this <div>, but for more than that, it gets unwieldly.
| </div> | ||
| <a href = "${previewLink}" class ="book-link" target="_blank"> Google Books Preview </a> | ||
| `; | ||
| `); |
There was a problem hiding this comment.
Because jQuery's syntax for creating new nodes is gross, I just set all the HTML contents of the newly-created <div> all at once. This can have security implications, so it's not good for all situations.
If you find yourself needing to create DOM nodes, and using React (or similar) would be overkill, a template library like Handlebars could be very useful.
This PR (pull request) compares the
refactoredbranch with thejquery-and-ajaxbranch.This is to demonstrate the difference between @IrvHenri's implementation of the Book Finder App using the more up-to-date fetch API and a more legacy implementation using jQuery + Ajax.
All non-trivial suggested changes, and some cosmetic changes, have line notes directly on the diff. You can see the conversations about those changes below, or in the 'Files changed' tab.