Creating a simple search site
Tags: javascript
Published: 2022-12-24 05:30:02

I created a site that allows users to enter a title to retrieve show details including the show summary, the network showing it, and show dates and times. This post describes how I captured the user's input, used an API to return shows based on the user's input, displayed the results on the page, and then resets everything for the next search.
## Add a form to collect search text
To begin, I needed to create a simple form in the `index.html` file consisting of a text field to collect the user's search terms and a button that allows the users to submit their search.

```
<form id='search-form'>
        <div id = "search">
          <input id='search' type='text' name='search' placeholder='Show Title'>
          <button type='submit' name='submit'>
            Search
          </button>
        </div>  
</form>
```
To 'hook it up', the following javascript was needed. It waits until the DOM is loaded and then listens for a `submit` event. Then, it calls the `findShow` function and passes the user's search text to it.

```
document.addEventListener('DOMContentLoaded', () => {
    const form = document.querySelector('form')
    form.addEventListener('submit', (e) => {
        e.preventDefault()
        findShow(e.target.search.value)
    })
}
```

## Display API results
Once I had the user's search text, I needed to display the results. But before that could be done, I needed to identify where to add the search results on the page by using an `id` attribute. My `index.html` file includes the following code. Each result will be added between the `ul` elements.

```
<div id='show-container'>
    <div class = "row">
      <ul id='show-list'>
      </ul>
    </div>
</div>
```
I then needed to iterate the results received from the API in order to display them. For this I used a simple `for` loop. 
```
function findShow(title) {
    fetch(`https://api.tvmaze.com/search/shows?q=${title}`)
    .then(response => response.json())
    .then(data => {
        //Promise returns an object containing items. Items are an array. This makes it easier to get to the array. 
        for (let i = 0; i < data.length; i++) {
            // Create friendly names for each show attribute
            showName = data[i].show.name;
            showSummary = data[i].show.summary;
            showIcon = data[i].show.image.medium;
            showUrl = data[i].show.officialSite;
            showNetwork = data[i].show.network.name;
            showSchedule = `${data[i].show.schedule.days}  ${data[i].show.schedule.time}`;
            showStatus = data[i].show.status;
            showGenres = data[i].show.genres;
    
            // Add show info to the page
            const node = document.createElement('p');
            node.innerHTML += `
                <img src ="${showIcon}">
                <h1>${showName}</h1>
                <div id = "information">${showSummary}</div>
                <section id="general-info-panel"
                    <br>Network: ${showNetwork}
                    <br>Status: ${showStatus}
                    <br>Genres: ${showGenres}
                    <br>Schedule: ${showSchedule}
                    <br> <a href="${showUrl}">Official Site</a>
                </section>`;
            document.getElementById("show-list").appendChild(node);
        }
    })
```
That's a lot of code so I'll walk through what's going on here.
<strong>Fetch</strong> The fetch paragraph does a number of things:
- it passes the search term `${title}` to the API
- it converts the returned data to json
- in the second `.then` is where we iterate through each result

<strong>Iterate through results</strong> In the second `.then` element, you'll see the iteration of results. I created an array for each item but this isn't necessary. A simple object iteration (e.g. `for` ... `in`) would work. Placing the results in an array allows for specific show references to be used later. The key to this iteration is including the HTML needed to display it on the page. Because I needed to add both HTML and variable references, everything is contained within backticks ('`').

<strong>Update the DOM</strong> While the iteration applies the HTML code to each item, actually displaying everything on the page requires adding the element to DOM. This is what the `document.getElementById("show-list").appendChild(node)` line does.

With these steps, the page is now building based on results returned from an API. Finally, we want to allow the user to do another search without having to reload the page.
## Resetting the page
It was easy to clear the search field. I simply added a `form.reset` to the end of the button event listener.

```
document.addEventListener('DOMContentLoaded', () => {
    const form = document.querySelector('form')
    form.addEventListener('submit', (e) => {
        e.preventDefault()
        findShow(e.target.search.value)
        form.reset()
    })
})
```

I also needed to clear the initial result listing on the page when users conduct subsequent searches. Doing this is as simple as targeting the same id attribute used above ('show-list in this example) and removing its child elements. Be sure to place this in a location that fires only after the first search. I added it immediately after the form reset.

```
document.addEventListener('DOMContentLoaded', () => {   
const form = document.querySelector('form')
    form.addEventListener('submit', (e) => {  
        e.preventDefault()
        findShow(e.target.search.value)
        form.reset()
    })
}
const div = document.getElementById('show-list');
while(div.firstChild){
    div.removeChild(div.firstChild);
}
```
## In Conclusion
There are many ways to approach this functionality. I did it as shown above to meet the Phase 1 project requirements of FlatIron's Software Engineering program. The first phase of their program demonstrates how even the basic concepts of html and javascript can equip learners' with the skills needed to build effective apps. It includes topics on javascript functions, array iteration, scope, manipulating the DOM, communicating with a server, and more! The concepts are clearly explained and links to more information are plenty. I found this phase interesting, exciting, and a real confidence booster.