How To Create A Recipe Book Using HTML, CSS, & JavaScript
Tags: javascripttutorial, webdev, programming, htmltutorial
Published: 2023-03-30 14:02:28

---
title: How To Create A Recipe Book Using HTML, CSS, & JavaScript
published: true
date: 2023-03-22 08:01:16 UTC
tags: javascripttutorial,webdevelopment,programming,htmltutorial
canonical_url: 
---

![Create A Recipe Book Using HTML, CSS, & JavaScript](https://cdn-images-1.medium.com/max/1024/1*5S7HNZaH2GhzLHX3404yTA.png)

Projects are an excellent way to boost your HTML, CSS, and JavaScript skills while teaching key concepts and practices.

A recipe book, which you can run in a browser like Google Chrome or Firefox, is a good place to start.

The recipe book has a place on the left side of the webpage where the user may enter new recipes.

The user may see and search for existing recipes on the right side of the page.

### How to Request a New Recipe from a User

![Recipe illuration](https://cdn-images-1.medium.com/max/1024/1*8Ore-uEgxYB2GUjl0IxRGw.png)

Complete the blanks in the HTML, CSS, and JavaScript files.

If you are unfamiliar with web development concepts, there are a few sites online that can help you learn web development.

In a new HTML file called index.html, add the following basic HTML structure:

```
<!DOCTYPE html>
<html>
  <head>
    <title>Recipe App</title>
  </head>
  <body>
    <nav>
      <h1>Recipe App</h1>
    </nav>
    <div class="container">
      <!-- Content here -->
    </div>
  </body>
</html>
```

Separate the page into a left and a right column within the container class:

```
<div class="left-column">

</div>
<div class="right-column">

</div>
```

Create a form in the left column for the user to enter a new recipe.

The user can input the name of the recipe, the ingredients list, and the method:

```
<h3>Add Recipe</h3>

<form>
  <label for="recipe-name">Name:</label>
  <input type="text" id="recipe-name" required>
  <br />

  <label for="recipe-ingredients">Ingredients:</label>
  <textarea id="recipe-ingredients" rows="5" required></textarea>
  <br />

 <label for="recipe-method">Method:</label>
  <textarea id="recipe-method" rows="5" required></textarea>
  <br />

  <button type="submit">Add Recipe</button>
</form>
```

Provide such a link to a new CSS file called styles.css in the HTML file’s head tag.

Put the following file in the same folder as your HTML file:

```
<link rel="stylesheet" href="styles.css">
```

Add some style for the overall page to the CSS file:

```
body {
  font-family: sans-serif;
}

nav {
  background-color: #333;
  position: fixed;
  top: 0;
  width: 100%;
  padding: 20px;
  left: 0;
  color: white;
  text-align: center;
}

.container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  margin: 150px 5%;
}

.left-column {
  width: 25%;
}

.right-column {
  width: 65%;
}
```

Style the Add Recipes form as follows:

```
form {
  display: flex;
  flex-direction: column;
}

label {
  margin-bottom: 10px;
}

input[type="text"], textarea {
  padding: 10px;
  margin-bottom: 10px;
  border-radius: 5px;
  border: 1px solid #ccc;
  width: 100%;
  box-sizing: border-box;
}

button[type="submit"] {
  padding: 10px;
  background-color: #3338;
  color: #fff;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
```

Have included a link to a JavaScript file called script.js at the bottom of the body element in your HTML file.

Create the following file in the same folder:

```
<body>
  <!-- Content -->
  <script src="script.js"></script>
</body>
```

Use the querySelector method in script.js to traverse the DOM and get the form element from the page.

```
const form = document.querySelector('form');
```

Build a new array to hold recipes entered by the user into the form:

```
let recipes = [];
```

Get the name, ingredients, and method fields from the form in a new function.

You can also employ client-side form validation to avoid invalid inputs or to verify if a recipe already exists.

```
function handleSubmit(event) {
  // Prevent default form submission behavior
  event.preventDefault();
  
  // Get recipe name, ingredients, and method input values
  const nameInput = document.querySelector('#recipe-name');
  const ingrInput = document.querySelector('#recipe-ingredients');
  const methodInput = document.querySelector('#recipe-method');
  const name = nameInput.value.trim();
  const ingredients = ingrInput.value.trim().split(',').map(i => i.trim());
  const method = methodInput.value.trim();
}
```

If the inputs are valid, add them to the array of recipes:

```
if (name && ingredients.length > 0 && method) {
  const newRecipe = { name, ingredients, method };
  recipes.push(newRecipe);
}
```

Clear the form’s inputs:

```
nameInput.value = '';
ingrInput.value = '';
methodInput.value = '';
```

Add an event listener after the handleSubmit() function to call the code when the user submits the form:

```
form.addEventListener('submit', handleSubmit);
```

See the form on the left by opening index.html in a browser:

![form in the index.html](https://cdn-images-1.medium.com/max/1024/1*GrdJkkvhl8Gi5n9xZ3112Q.png)

### How to Show New Recipes

![3d Sushi](https://cdn-images-1.medium.com/max/1024/1*YcVuc_wj_dEutfC_pUwzig.png)

The recipes recorded in the recipe array may be viewed on the right side of the page.

Include a div into the HTML code to show the recipes list inside the right column.

Add another div to display a message if no recipes are found:

```
<div class="right-column">
  <div id="recipe-list"></div>
  <div id="no-recipes">You have no recipes.</div>
</div>
```

Add the following CSS style to the recipe list:

```
#recipe-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-gap: 20px;
}

#no-recipes {
  display: flex;
  background-color: #FFCCCC;
  padding: 20px;
  border-radius: 8px;
  margin-top: 44px;
}
```

Get the HTML elements used to show the recipe list and error warning at the start of the JavaScript file:

```
const recipeList = document.querySelector('#recipe-list');
const noRecipes = document.getElementById('no-recipes');
```

Loop over each recipe in the recipes array within a new function.

Create a new div for each recipe to show it:

```
function displayRecipes() {
  recipeList.innerHTML = '';
  recipes.forEach((recipe, index) => {
    const recipeDiv = document.createElement('div');
  });
}
```

To show the name, ingredients, and method, add some content to the single recipe div.

A delete button will be a part of the div. This feature will be added in the following steps:

```
recipeDiv.innerHTML = `
  <h3>${recipe.name}</h3>
  <p><strong>Ingredients:</strong></p>
  <ul>
    ${recipe.ingredients.map(ingr => `<li>${ingr}</li>`).join('')}
  </ul>
  <p><strong>Method:</strong></p>
  <p>${recipe.method}</p>
  <button class="delete-button" data-index="${index}">Delete</button>`;
```

To style the div, add the following class:

```
recipeDiv.classList.add('recipe');
```

Add the new div to the recipeList HTML element like follows:

```
recipeList.appendChild(recipeDiv);
```

In the CSS file, add the following style for the class:

```
.recipe {
  border: 1px solid #ccc;
  padding: 10px;
  border-radius: 5px;
  box-shadow: 0 2px 4px rgba(0,0,0,.2);
}

.recipe h3 {
  margin-top: 0;
  margin-bottom: 10px;
}

.recipe ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.recipe ul li {
  margin-bottom: 5px;
}
```

Check to see whether there are many recipes. If this is the case, hide the error message:

```
noRecipes.style.display = recipes.length > 0 ? 'none' : 'flex';
```

After adding the new recipe to the recipes array, call the new method from within the handleSubmit() function:

```
displayRecipes();
```

With a browser, go to index.html:

![Error check on recipe website](https://cdn-images-1.medium.com/max/1024/1*NUosc0UoC-sW7EILvUrMBw.png)

Add recipes to the list to go and see them display on the right:

![new recipes in website](https://cdn-images-1.medium.com/max/1024/1*Hhv2VumbJfH1F2kteVvUew.png)

### How to Get Clear of Recipes

![3d Sando Totem](https://cdn-images-1.medium.com/max/1024/0*NFyahs38--awvHjy.png)

Recipes can be deleted by clicking the Delete button next to the recipe’s instructions.

Apply the following CSS style to the delete button:

```
.delete-button {
  background-color: #dc3545;
  color: #fff;
  border: none;
  border-radius: 5px;
  padding: 5px 10px;
  cursor: pointer;
}

.delete-button:hover {
  background-color: #c82333;
}
```

Add a new method to the JavaScript code to remove a recipe:

```
function handleDelete(event) {

}
```

Get the index of the recipe that the user clicked on using the JavaScript event:

```
if (event.target.classList.contains('delete-button')) {
  const index = event.target.dataset.index;
}
```

To remove the chosen recipe from the recipes array, use the index:

```
recipes.splice(index, 1);
```

Refresh the recipe list displayed on the page:

```
displayRecipes();
```

When the user clicks the delete button, add an event listener that calls the handleDelete() function:

```
recipeList.addEventListener('click', handleDelete);
```

Launch a browser and go to index.html. To see the delete button, add a recipe:

![Delete button on recipe website](https://cdn-images-1.medium.com/max/1024/1*NpOQnER3VJjVdV1yGwR7yQ.png)

### How to Look for Recipes

![3d Festa](https://cdn-images-1.medium.com/max/1024/1*NjKjp8o7f_to9VGdvmlEFw.png)

You can use the search box to see if a given recipe is available.

Add a search bar before the recipe list in the right-column:

```
<div id="search-section">
  <h3>Recipes List</h3>
  <label for="search-box">Search:</label>
  <input type="text" id="search-box">
</div>
```

Apply the following CSS style to the search bar label:

```
label[for="search-box"] {
  display: block;
  margin-bottom: 10px;
}
```

Get the HTML element of the search box in script.js:

```
const searchBox = document.getElementById('search-box');
```

Create a new array within a new function that contains recipes whose names match the search input:

```
function search(query) {
  const filteredRecipes = recipes.filter(recipe => {
    return recipe.name.toLowerCase().includes(query.toLowerCase());
  });
}
```

Clear the recipe list that is presently showing on the screen:

```
recipeList.innerHTML = '';
```

Create a new div element for each filtered recipe that fits the search result:

```
filteredRecipes.forEach(recipe => {
  const recipeEl = document.createElement('div'); 
});
```

Fill in the div with the HTML content for the filtered recipe:

```
recipeEl.innerHTML = `
  <h3>${recipe.name}</h3>
  <p><strong>Ingredients:</strong></p>
  <ul>
    ${recipe.ingredients.map(ingr => `<li>${ingr}</li>`).join('')}
  </ul>
  <p><strong>Method:</strong></p>
  <p>${recipe.method}</p>
  <button class="delete-button" data-index="${recipes.indexOf(recipe)}">
    Delete
  </button>`;
```

For a consistent look, use the same recipe class. Add the following div to the page’s list:

```
recipeEl.classList.add('recipe');
recipeList.appendChild(recipeEl);
```

When the user types into the search bar, add an event listener that calls the search() function:

```
searchBox.addEventListener('input', event => search(event.target.value));
```

To refresh the list, clear the search box inside the handleDelete() method whenever the user deletes an item:

```
searchBox.value = '';
```

To see the new search bar, open index.html in a web browser and add some recipes:

![Adding recipe on website](https://cdn-images-1.medium.com/max/1024/1*EI29cEXJpu0oMskLow8JNA.png)

To filter the recipes list, enter a recipe name into the search bar:

![filter the recipes list](https://cdn-images-1.medium.com/max/1024/1*5AINWO_0tXM9xmOa8rgXAA.png)

### Creating HTML, CSS, and JavaScript Projects

This project shows how to create a front-end interface for a basic recipe book.

There is no backend server, and the app does not save data; if you reload the page, your modifications will be erased.

One such addition is a method for saving and loading data using localStorage.

Continue exploring other interesting and enjoyable projects you can make on your desktop to boost your web development skills.

* * *