http://dnajs.org/tutorial
dna.js REST-driven Search Component
Video Tutorial ~~ Transcript

1) Welcome to the dna.js REST-driven Search Component tutorial.  Over the next few minutes, we will use jQuery and dna.js to build from scratch a book search tool on top of the Google Books API.

2) Using your favorite code editor, create an HTML file named book-finder.html.  We'll begin with some very basic boilerplate HTML to give us a valid web page as a starting point.  Just after the <h1> header line, insert some plain old HTML for a search input box and a "Find" button.

3) Then add the HTML to display the search results.  The <div> with the "books" class is for a list of books, and we'll include one book stub inside the list so we can mockup and style the web page.  On the left side will be the thumbnail image for the book cover.  Use the sample book cover image from the dnajs.org website.  On the right side, will be meta information about the book showing title, publisher, and price.

4) Let's verify that the web page displays in a browser.  It does display, but it's quite ugly.  So, let's add just enough CSS to make the style reasonable.  For production code, you'll want to use a CSS preprocessor, such as LESS, which has nice, clean notation for variables and mixins.  For this tutorial, however, the <style> tag will get the job done.  This CSS will display each book as a blue box with an 80 pixel wide thumbnail and the book metadata as an inline-block.

5) The book-finder.html page looks better now, but it's still completely static.  Next we'll turn the static book HTML into a template that can take JSON data.  Before we convert the HTML into a data-driven template, we need to know the structure of the data.  Do this in your browser by entering the URL of a sample REST call and manually examining the JSON response.

6) The Google APIs are at "https://www.googleapis.com".  Tack on "books" to specify the Books API and "v1" for version 1 of the API.  We want the "volumes" data, and our sample search query is made with the parameter "q=ice".

7) Instead of getting back HTML to render a web page, the REST API sends us JSON data.  JSON stands for JavaScript Object Notation; it's simple and easy to read.  In this case, the search results are returned as an array of books in the "items" field.  We are only interested in four specific pieces of data for each book.  Three of those fields are in the book's "volumeInfo" object.  There's the "title" and the "publisher", and a little further down inside the "imageLinks" object is the "thumbnail" URL.  Over in the "salesInfo" object, we find the "listPrice" object, which contains the "amount" field.  Now we have the information necessary to turn our static HTML for one book into a data-driven template to generate a list of books.

8) Convert the book HTML into a template by changing the class "book" to an ID (so the template has a name) and adding the class "dna-template".  Now designate where data is to be injected into the template.  Wrap field names in double tildes (~~) and use dot notation to reference nested data in the JSON.  For example, the hard-coded value of the image's "src" attribute is replaced with "~~volumeInfo.imageLinks.thumbnail~~".  The title becomes "volumeInfo.title", and the publisher becomes "volumeInfo.publisher".  Lastly, inject price with "saleInfo.listPrice.amount".

9) So now our book template is done and next we'll load the jQuery and dna.js libraries.  A CDN, Content Delivery Network, makes it easy to load the CSS and JavaScript files for the libraries.  First, load the CSS file for dna.js.  Within the <head> section, insert a <link> tag to the stylesheet at "cdn.jsdelivr.net/npm/dna.js@1.3/dna.css".  Then right before the closing </body> tag insert a <script> tag to load jQuery followed by one to load dna.js.  Browsers cache the files from the CDN for improved performance, but for a production website you can further improve performance using a build process that unifies and minifies your CSS and JavaScript.

10) Now for the fun part: writing the JavaScript to make the REST call and display the search results.  Create a function named "findBooks".  The first line of code reads the user's search terms by getting the value of the <input> element.

11) Remember that URL we used for the sample REST call?  Use that same URL but with the search terms appended dynamically.  Then to make the actual REST call, use jQuery's handy getJSON function.  The first parameter is the URL of the REST call, and the second parameter is the callback function to handle the results.

12) Of course, now we need to define the handleResults function.  jQuery passes the response JSON into the callback function, and we are going to use that data to tell dna.js to clone the "book" template -- one clone for each book.  The first parameter for the dna.clone function is the name of the template and the second parameter is the data.  For the Google Books API, we'll use the "items" field which is the actual array of books.  Options are passed as the third parameter.  We need any previous results emptied out before displaying the new results, and we want to smoothly fade in the new results.

13) To make this all work, we have to actually call the findBooks function.  Use the "data-click" attribute to tell dna.js to call the function.  Add the attribute to the <button> tag with a value of "findBooks" so that when the user clicks the "Find" button, the findBooks function is called.

14) Let's test it in the browser by searching for books about "ice".  The first book returned by the REST call is The Book of Ice and it costs $9.99.  Clicking the "Find" button works and is simple, but it makes for a cumbersome user experience.  We can leverage the smart update feature of dna.js to replace the button with automatic live searching.

15) Add the attribute "data-smart-update" directly to the <input> tag.  This causes the findBooks function to be called when the user updates the input field, but the calls are throttled to reduce load on the server and prevent the REST responses from overlapping.  Now we can get rid of the annoying "Find" button.  Additionally, we can make the "findBooks" function more robust.  dna.js passes the element that was changed to the callback function, so the user's input can now be read with just elem.val.

16) Return to the browser and refresh the page to see the improved UI.  Let's search for "fireworks china".  Relevant books are displayed as the user types in the search terms.  Let's hop back to the code and step though the the process of going from user input to the REST call to displaying search results.

17) The findBooks function is called when the user updates the text in the <input> field.  dna.js passes the <input> element into the findBooks function where we read the value of the element.  Then the URL is constructed and passed into jQuery's getJSON function to make the REST call to the Google Books API.  And the handleResults function is called once the JSON response is received.  That data is passed into the clone function to make copies of the "book" template.  And that's all you need to make a REST-driven search component.

18) Visit dnajs.org for more information.  If you have any questions, follow the link to the GitHub project and submit an issue with your question.  Thanks.

---
