---
id: 66ec4c8e9878d8441956516f
title: Build a Book Catalog Table
challengeType: 25
dashedName: build-a-book-catalog-table
demoType: onClick
---

# --description--

**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.

**User Stories:**

1. You should create a `table` element that lists book information.
1. Your table should have a table head element with one row in it.
1. The row in your table head element should have four table header elements, with the text of `Title`, `Author`, `Genre`, and `Publication Year`, in that order.
1. Your table should have a table body element with at least five rows in it.
1. Each row in your table body should have four table data elements that display the book's Title, Author, Genre, and Publication Year.
1. Your table should have a table footer element with one row in it.
1. The row in your table footer element should have a table data element that spans four columns and has the text `Total Books: N` where `N` should be replaced by the number of books in your table.

# --hints--

You should have one `table` element.

```js
assert.lengthOf(document.querySelectorAll('table'), 1);
```

You should have one `thead` element within your `table` element.

```js
assert.lengthOf(document.querySelectorAll('table thead'), 1);
```

You should have one `tr` element within your `thead` element.

```js
assert.lengthOf(document.querySelectorAll('thead tr'), 1);
```

You should have four `th` elements within your `thead` element's row.

```js
assert.lengthOf(document.querySelectorAll('thead tr th'), 4);
```

Your four `th` elements should have the text `Title`, `Author`, `Genre`, and `Publication Year`, in that order.

```js
const ths = document.querySelectorAll('thead tr th');
assert.equal(ths[0]?.textContent.trim(), 'Title');
assert.equal(ths[1]?.textContent.trim(), 'Author');
assert.equal(ths[2]?.textContent.trim(), 'Genre');
assert.equal(ths[3]?.textContent.trim(), 'Publication Year');
```

You should have one `tbody` element within your `table` element.

```js
assert.lengthOf(document.querySelectorAll('table tbody'), 1);
```

Your `tbody` element should have at least five rows.

```js
assert.isAtLeast(document.querySelectorAll('tbody tr').length, 5);
```

Each row in your `tbody` element should have exactly four `td` elements as children.

```js
const rows = document.querySelectorAll('tbody tr');
assert.isAtLeast(rows.length, 1);

rows.forEach(row => {
  assert.lengthOf(row.querySelectorAll('td'), 4);
  assert.lengthOf(row.children, 4);
});
```

Each `td` element in your table body should have text with book information.

```js
const tds = document.querySelectorAll('tbody tr td');
assert.isAtLeast(tds.length, 1);

tds.forEach(td => {
  assert.isAtLeast(td.textContent.trim().length, 1);
});
```

You should have one `tfoot` element within your `table` element.

```js
assert.lengthOf(document.querySelectorAll('table tfoot'), 1);
```

You should have exactly one `tr` element in your `tfoot` element.

```js
assert.lengthOf(document.querySelectorAll('tfoot tr'), 1);
```

The `td` element in your `tfoot` element's row should have it's `colspan` attribute set to `4`.

```js
assert.equal(document.querySelector('tfoot tr td')?.colSpan, 4);
```

The `td` element in your `tfoot` element's row should have the text `Total Books: N` where `N` is the number of books in your table.

```js
const numberOfBooks = document.querySelectorAll('tbody tr')?.length;
assert.equal(document.querySelector('tfoot tr td').textContent.trim(), `Total Books: ${numberOfBooks}`);
```

# --seed--

## --seed-contents--

```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Book Catalog</title>
</head>

<body>
</body>

</html>
```

# --solutions--

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Book Catalog</title>
</head>
<body>
    <h1>Book Catalog</h1>
  <table>
    <thead>
      <tr>
        <th>Title</th>
        <th>Author</th>
        <th>Genre</th>
        <th>Publication Year</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>How to Contribute to Open-Source Projects – A Handbook for Beginners</td>
        <td>Hillary Nyakundi</td>
        <td>Open Source</td>
        <td>2023</td>
      </tr>
      <tr>
        <td>Learn Linux for Beginners: From Basics to Advanced Techniques</td>
        <td>Zaira Hira</td>
        <td>Linux</td>
        <td>2024</td>
      </tr>
      <tr>
        <td>How to Learn to Code and Get a Developer Job</td>
        <td>Quincy Larson</td>
        <td>Learn To Code</td>
        <td>2024</td>
      </tr>
      <tr>
        <td>The Regular Expressions Book – RegEx for JavaScript Developers</td>
        <td>Kolade Chris</td>
        <td>Regular Expressions</td>
        <td>2023</td>
      </tr>
      <tr>
        <td>The Python Code Example Handbook</td>
        <td>Farhan Hasin Chowdhury</td>
        <td>Python</td>
        <td>2023</td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td colspan="4">Total Books: 5</td>
      </tr>
    </tfoot>
  </table>
</body>
</html>
```
