feat(curriculum): add music filter workshop to FSDC (#57025)

Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>
This commit is contained in:
Dario-DC
2024-11-15 20:44:27 +01:00
committed by GitHub
parent 5d546447f5
commit 0a7d2ef58d
18 changed files with 3092 additions and 1 deletions

View File

@@ -2838,7 +2838,12 @@
"In these lecture videos, you will learn about the event object and event delegation."
]
},
"lbyi": { "title": "193", "intro": [] },
"workshop-music-instrument-filter": {
"title": "Build a Music Instrument Filter",
"intro": [
"In this workshop, you will build a music instrument filter with JavaScript."
]
},
"lab-real-time-counter": {
"title": "Build a Real Time Counter",
"intro": ["In this lab, you will build a real-time character counter"]

View File

@@ -0,0 +1,9 @@
---
title: Introduction to the Build a Music Instrument Filter
block: workshop-music-instrument-filter
superBlock: full-stack-developer
---
## Introduction to the Build a Music Instrument Filter
In this workshop, you will build a music instrument filter with JavaScript.

View File

@@ -0,0 +1,69 @@
{
"name": "Build a Music Instrument Filter",
"blockType": "workshop",
"blockLayout": "challenge-grid",
"isUpcomingChange": true,
"usesMultifileEditor": true,
"hasEditableBoundaries": true,
"dashedName": "workshop-music-instrument-filter",
"superBlock": "full-stack-developer",
"challengeOrder": [
{
"id": "6720fc487ab844522b5aa036",
"title": "Step 1"
},
{
"id": "6721089b71655f803ce3bef2",
"title": "Step 2"
},
{
"id": "67210c430ddf4889785aca66",
"title": "Step 3"
},
{
"id": "67210ef0bbb7c895a7351b0d",
"title": "Step 4"
},
{
"id": "672110bda073669bcc2302e6",
"title": "Step 5"
},
{
"id": "6721128fdf008f9fd484486a",
"title": "Step 6"
},
{
"id": "6721134b2844faa0be27c791",
"title": "Step 7"
},
{
"id": "6721145f25a6b9a1a5d19461",
"title": "Step 8"
},
{
"id": "67211aa4a8959cc122dfa0bb",
"title": "Step 9"
},
{
"id": "672134eef863b05aaee80c75",
"title": "Step 10"
},
{
"id": "67213641373a23696b74424b",
"title": "Step 11"
},
{
"id": "672137c47fa88d6f753f6d0b",
"title": "Step 12"
},
{
"id": "67213ce0a2ba1278a38df3a5",
"title": "Step 13"
},
{
"id": "672146dde7104896adb274ae",
"title": "Step 14"
}
],
"helpCategory": "JavaScript"
}

View File

@@ -0,0 +1,155 @@
---
id: 6720fc487ab844522b5aa036
title: Step 1
challengeType: 0
dashedName: step-1
demoType: onLoad
---
# --description--
You have been provided with a page containing several instrument cards. You are going to add functionality to this static page so you'll be able to filter the instruments depending on their family.
Start by creating a dropdown menu with the class of `select-container`.
# --hints--
You should have a `select` element.
```js
assert.exists(document.querySelector("select"));
```
Your `select` element should have the class `select-container`.
```js
assert.equal(document.querySelector("select").getAttribute("class"), "select-container");
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
--fcc-editable-region--
--fcc-editable-region--
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```

View File

@@ -0,0 +1,200 @@
---
id: 6721089b71655f803ce3bef2
title: Step 2
challengeType: 0
dashedName: step-2
---
# --description--
Now add four options to your dropdown, `All`, `Woodwinds`, `Brass`, and `Percussion`, in this order. For each option, use the lowercase option to specify the `id` attribute and the `value` attribute.
# --hints--
You should have four `option` elements in your `select` element.
```js
assert.lengthOf(document.querySelectorAll("select>option"), 4);
```
Your first `option` element should have the text `All`.
```js
assert.equal(document.querySelectorAll("select>option")[0].innerText,"All");
```
Your `All` option should have an `id` attribute and a `value` attribute with the value `all`.
```js
assert.equal(document.querySelectorAll("select>option")[0].getAttribute("id"),"all");
assert.equal(document.querySelectorAll("select>option")[0].getAttribute("value"),"all");
```
Your second `option` element should have the text `Woodwinds`.
```js
assert.equal(document.querySelectorAll("select>option")[1].innerText,"Woodwinds");
```
Your `Woodwinds` option should have an `id` attribute and a `value` attribute with the value `woodwinds`.
```js
assert.equal(document.querySelectorAll("select>option")[1].getAttribute("id"),"woodwinds");
assert.equal(document.querySelectorAll("select>option")[1].getAttribute("value"),"woodwinds");
```
Your third `option` element should have the text `Brass`.
```js
assert.equal(document.querySelectorAll("select>option")[2].innerText,"Brass");
```
Your `Brass` option should have an `id` attribute and a `value` attribute with the value `brass`.
```js
assert.equal(document.querySelectorAll("select>option")[2].getAttribute("id"),"brass");
assert.equal(document.querySelectorAll("select>option")[2].getAttribute("value"),"brass");
```
Your fourth `option` element should have the text `Percussion`.
```js
assert.equal(document.querySelectorAll("select>option")[3].innerText,"Percussion");
```
Your `Percussion` option should have an `id` attribute and a `value` attribute with the value `percussion`.
```js
assert.equal(document.querySelectorAll("select>option")[3].getAttribute("id"),"percussion");
assert.equal(document.querySelectorAll("select>option")[3].getAttribute("value"),"percussion");
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
--fcc-editable-region--
<select class="select-container">
</select>
--fcc-editable-region--
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```

View File

@@ -0,0 +1,154 @@
---
id: 67210c430ddf4889785aca66
title: Step 3
challengeType: 0
dashedName: step-3
---
# --description--
Before starting to add the filter functionality to your page, link your `script.js` file to the HTML.
# --hints--
You should have a `script` element with the `src` attribute set to `script.js`.
```js
const script = document.querySelector("body>script");
assert.match(script?.getAttribute("data-src"), /(?:\.\/)?script\.js/)
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
--fcc-editable-region--
--fcc-editable-region--
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```

View File

@@ -0,0 +1,158 @@
---
id: 67210ef0bbb7c895a7351b0d
title: Step 4
challengeType: 0
dashedName: step-4
---
# --description--
Declare an empty array named `instrumentsArr`.
# --hints--
You should have an empty array named `instrumentsArr`.
```js
assert.isArray(instrumentsArr);
assert.isEmpty(instrumentsArr);
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,185 @@
---
id: 672110bda073669bcc2302e6
title: Step 5
challengeType: 0
dashedName: step-5
---
# --description--
`instrumentsArr` is going to hold an objects for each of your instrument cards. Each object will have the keys `category`, `instrument`, and `price`.
Add a first object representing the flute to your array. For the values use `woodwinds`, `Flute`, and `500`, respectively.
# --hints--
Your `instrumentsArr` array should have one element.
```js
assert.lengthOf(instrumentsArr, 1);
```
You should have one object inside `instrumentsArr`.
```js
assert.isObject(instrumentsArr[0]);
```
The object inside `instrumentsArr` should have a `category` key with the value `woodwinds`.
```js
assert.equal(instrumentsArr[0].category, "woodwinds");
```
The object inside `instrumentsArr` should have an `instrument` key with the value `Flute`.
```js
assert.equal(instrumentsArr[0].instrument, "Flute");
```
The object inside `instrumentsArr` should have a `price` key with the value `500`.
```js
assert.strictEqual(instrumentsArr[0].price, 500);
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
--fcc-editable-region--
const instrumentsArr = [
]
--fcc-editable-region--
```

View File

@@ -0,0 +1,171 @@
---
id: 6721128fdf008f9fd484486a
title: Step 6
challengeType: 0
dashedName: step-6
---
# --description--
Add another two objects to your `instrumentsArr` to represent the remaining woodwinds instruments, clarinet and oboe.
# --hints--
You should have `{ category: "woodwinds", instrument: "Clarinet", price: 200 }` inside your `instrumentsArr`.
```js
assert.deepInclude(instrumentsArr, { category: "woodwinds", instrument: "Clarinet", price: 200 });
```
You should have `{ category: "woodwinds", instrument: "Oboe", price: 4000 }` inside your `instrumentsArr`.
```js
assert.deepInclude(instrumentsArr, { category: "woodwinds", instrument: "Oboe", price: 4000 });
```
You should still have `{ category: "woodwinds", instrument: "Flute", price: 500 }` inside your `instrumentsArr`.
```js
assert.deepInclude(instrumentsArr, { category: "woodwinds", instrument: "Flute", price: 500 });
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
--fcc-editable-region--
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 }
]
--fcc-editable-region--
```

View File

@@ -0,0 +1,189 @@
---
id: 6721134b2844faa0be27c791
title: Step 7
challengeType: 0
dashedName: step-7
---
# --description--
The remaining instruments have been added for you to the `instrumentsArr` array.
Now, declare two variables `selectContainer` and `productsContainer` and assign them your HTML dropdown and the element with the class `products-container`, respectively.
# --hints--
You should have a `selectContainer` variable.
```js
assert.exists(selectContainer);
```
Your `selectContainer` variable should have the value of your `select` element.
```js
assert.strictEqual(selectContainer, document.querySelector("select"));
```
You should have a `productsContainer` variable.
```js
assert.exists(productsContainer);
```
Your `productsContainer` variable should have the value of your `.products-container` element.
```js
assert.strictEqual(productsContainer, document.querySelector(".products-container"));
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,184 @@
---
id: 6721145f25a6b9a1a5d19461
title: Step 8
challengeType: 0
dashedName: step-8
---
# --description--
As you learned in the previous lesson videos, the `change` event is triggered when the user modifies the value of certain input elements. You want to be able to update your page any time that a new value is picked from the dropdown menu. For that, add an event listener for the `change` event to `selectContainer`.
For now, inside the callback, log the string `this is a test` to the console. Then, select different options from your dropdown menu and check the console to test that the event listener works correctly.
# --hints--
You should add an event listener for the `change` event to `selectContainer` and log the string `this is a test` inside the callback passed to the method.
```js
let flag = false;
const temp = console.log;
console.log = (arg) => {
if (arg === "this is a test") flag = true;
}
try {
selectContainer.dispatchEvent(new Event("change"));
assert.isTrue(flag);
} finally {
console.log = temp;
}
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,184 @@
---
id: 67211aa4a8959cc122dfa0bb
title: Step 9
challengeType: 0
dashedName: step-9
---
# --description--
Modify your `console.log` call to log the selected value from the dropdown.
# --hints--
You should log the selected value from the dropdown when a `change` event is triggered on `selectContainer`.
```js
let flag = false;
const temp = console.log;
console.log = (arg) => {
if (arg === selectContainer.value) flag = true;
}
try {
selectContainer.dispatchEvent(new Event("change"));
assert.isTrue(flag);
} finally {
console.log = temp;
}
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
--fcc-editable-region--
selectContainer.addEventListener("change", () => {
console.log("this is a test");
});
--fcc-editable-region--
```

View File

@@ -0,0 +1,181 @@
---
id: 672134eef863b05aaee80c75
title: Step 10
challengeType: 0
dashedName: step-10
---
# --description--
To implement the filter functionality, you'll need a function. Declare an empty function named `instrumentCards` that takes a single parameter.
# --hints--
You should have a function named `instrumentCards`.
```js
assert.isFunction(instrumentCards);
```
Your `instrumentCards` function should take a single parameter.
```js
assert.lengthOf(instrumentCards, 1);
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
--fcc-editable-region--
--fcc-editable-region--
selectContainer.addEventListener("change", () => {
console.log(selectContainer.value);
});
```

View File

@@ -0,0 +1,216 @@
---
id: 67213641373a23696b74424b
title: Step 11
challengeType: 0
dashedName: step-11
---
# --description--
Within your new function, you need to filter the instruments depending on the selected category.
Filter out items from `instrumentsArr` and make your function return an array containing the instrument objects with the the same category of `instrumentCategory`. If `instrumentCategory` is equal to `all`, return the whole `instrumentsArr` array.
Then, remove the `console.log` from the callback of your event listener and log the result of calling `instrumentCards` with the selected option from the dropdown menu as argument so you can test your function selecting different category options.
# --hints--
`instrumentCards("all")` should return `instrumentsArr`.
```js
assert.sameDeepMembers(instrumentCards("all"), instrumentsArr);
```
`instrumentCards("woodwinds")` should return `[{ category: "woodwinds", instrument: "Flute", price: 500 }, { category: "woodwinds", instrument: "Clarinet", price: 200 }, { category: "woodwinds", instrument: "Oboe", price: 4000 }]`.
```js
assert.sameDeepMembers(instrumentCards("woodwinds"), [{ category: "woodwinds", instrument: "Flute", price: 500 }, { category: "woodwinds", instrument: "Clarinet", price: 200 }, { category: "woodwinds", instrument: "Oboe", price: 4000 }]);
```
`instrumentCards("brass")` should return `[{ category: "brass", instrument: "Trumpet", price: 200 }, { category: "brass", instrument: "Trombone", price: 300 }, { category: "brass", instrument: "French Horn", price: 4300 }]`.
```js
assert.sameDeepMembers(instrumentCards("brass"), [{ category: "brass", instrument: "Trumpet", price: 200 }, { category: "brass", instrument: "Trombone", price: 300 }, { category: "brass", instrument: "French Horn", price: 4300 }]);
```
`instrumentCards("percussion")` should return `[{ category: "percussion", instrument: "Drum Set", price: 500 }, { category: "percussion", instrument: "Xylophone", price: 3000 }, { category: "percussion", instrument: "Cymbals", price: 200 }, { category: "percussion", instrument: "Marimba", price: 3000 }]`.
```js
assert.sameDeepMembers(instrumentCards("percussion"), [{ category: "percussion", instrument: "Drum Set", price: 500 }, { category: "percussion", instrument: "Xylophone", price: 3000 }, { category: "percussion", instrument: "Cymbals", price: 200 }, { category: "percussion", instrument: "Marimba", price: 3000 }]);
```
When you change the selected category from the dropdown menu, you should log the result of `instrumentCards(selectContainer.value)` to the console.
```js
let flag = false;
const temp = console.log;
console.log = (arg) => {
if (arg === instrumentCards(selectContainer.value)) flag = true;
}
try {
selectContainer.dispatchEvent(new Event("change"));
assert.isTrue(flag);
} finally {
console.log = temp;
}
```
# --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
--fcc-editable-region--
function instrumentCards(instrumentCategory) {
}
selectContainer.addEventListener("change", () => {
console.log(selectContainer.value);
});
--fcc-editable-region--
```

View File

@@ -0,0 +1,333 @@
---
id: 672137c47fa88d6f753f6d0b
title: Step 12
challengeType: 0
dashedName: step-12
---
# --description--
Currently, your `instrumentCards` function returns an array with instrument objects, so you'll need another couple of steps before you can display your instrument cards on the page.
Modify your function so that it returns an array of strings containing the HTML code to display the instrument cards, each string corresponding to an object in the `instruments` array. The strings should have this format `<div class="card"><h2>[instrument]</h2><p>$[price]</p></div>`
# --hints--
`instrumentCards("all")` should return an array of strings representing instrument cards, each with the format `<div class="card"><h2>[instrument]</h2><p>$[price]</p></div>`.
```js
const all = instrumentCards("all");
assert.isNotEmpty(all);
all.forEach(i => {
assert.match(i, regex)
})
```
`instrumentCards("woodwinds")` should return an array of strings representing instrument cards, each with the format `<div class="card"><h2>[instrument]</h2><p>$[price]</p></div>`.
```js
const woodwinds = instrumentCards("woodwinds");
assert.isNotEmpty(woodwinds);
woodwinds.forEach(i => {
assert.match(i, regex)
})
```
`instrumentCards("brass")` should return an array of strings representing instrument cards, each with the format `<div class="card"><h2>[instrument]</h2><p>$[price]</p></div>`.
```js
const brass = instrumentCards("brass");
assert.isNotEmpty(brass);
brass.forEach(i => {
assert.match(i, regex)
})
```
`instrumentCards("percussion")` should return an array of strings representing instrument cards, each with the format `<div class="card"><h2>[instrument]</h2><p>$[price]</p></div>`.
```js
const percussion = instrumentCards("percussion");
assert.isNotEmpty(percussion);
percussion.forEach(i => {
assert.match(i, regex)
})
```
`instrumentCards("all")` should return an array with ten strings representing the instrument cards for all the instruments on your page.
```js
const instrArr = getInstrumentsArr("all");
const testDiv = document.createElement("div");
testDiv.innerHTML = instrumentCards("all").join("");
const cards = testDiv.querySelectorAll('div[class="card"]');
assert.lengthOf(cards, 10);
Array.from(cards).forEach(card => {
const h2 = card.firstElementChild;
assert.equal(h2.tagName, "H2");
const instrObjIndex = instrArr.findIndex(el => el.instrument === h2.innerText);
const p = card.lastElementChild;
assert.equal(p.tagName, "P");
assert.equal(p.previousElementSibling, h2);
assert.equal(p.innerText, `$${instrArr[instrObjIndex].price}`);
instrArr.splice(instrObjIndex, 1);
})
assert.isEmpty(instrArr);
```
`instrumentCards("woodwinds")` should return an array with three strings representing the instrument cards for the woodwind instruments on your page.
```js
const instrArr = getInstrumentsArr("woodwinds");
const testDiv = document.createElement("div");
testDiv.innerHTML = instrumentCards("woodwinds").join("");
const cards = testDiv.querySelectorAll('div[class="card"]');
assert.lengthOf(cards, 3);
Array.from(cards).forEach(card => {
const h2 = card.firstElementChild;
assert.equal(h2.tagName, "H2");
const instrObjIndex = instrArr.findIndex(el => el.instrument === h2.innerText);
const p = card.lastElementChild;
assert.equal(p.tagName, "P");
assert.equal(p.previousElementSibling, h2);
assert.equal(p.innerText, `$${instrArr[instrObjIndex].price}`);
instrArr.splice(instrObjIndex, 1);
})
assert.isEmpty(instrArr);
```
`instrumentCards("brass")` should return an array with three strings representing the instrument cards for the brass instruments on your page.
```js
const instrArr = getInstrumentsArr("brass");
const testDiv = document.createElement("div");
testDiv.innerHTML = instrumentCards("brass").join("");
const cards = testDiv.querySelectorAll('div[class="card"]');
assert.lengthOf(cards, 3);
Array.from(cards).forEach(card => {
const h2 = card.firstElementChild;
assert.equal(h2.tagName, "H2");
const instrObjIndex = instrArr.findIndex(el => el.instrument === h2.innerText);
const p = card.lastElementChild;
assert.equal(p.tagName, "P");
assert.equal(p.previousElementSibling, h2);
assert.equal(p.innerText, `$${instrArr[instrObjIndex].price}`);
instrArr.splice(instrObjIndex, 1);
})
assert.isEmpty(instrArr);
```
`instrumentCards("percussion")` should return an array with four strings representing the instrument cards for the percussion instruments on your page.
```js
const instrArr = getInstrumentsArr("percussion");
const testDiv = document.createElement("div");
testDiv.innerHTML = instrumentCards("percussion").join("");
const cards = testDiv.querySelectorAll('div[class="card"]');
assert.lengthOf(cards, 4);
Array.from(cards).forEach(card => {
const h2 = card.firstElementChild;
assert.equal(h2.tagName, "H2");
const instrObjIndex = instrArr.findIndex(el => el.instrument === h2.innerText);
const p = card.lastElementChild;
assert.equal(p.tagName, "P");
assert.equal(p.previousElementSibling, h2);
assert.equal(p.innerText, `$${instrArr[instrObjIndex].price}`);
instrArr.splice(instrObjIndex, 1);
})
assert.isEmpty(instrArr);
```
# --seed--
## --after-user-code--
```js
const allInstrmnts = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
function getInstrumentsArr(instrumentCategory) {
const instruments =
instrumentCategory === "all"
? JSON.parse(JSON.stringify(allInstrmnts))
: allInstrmnts.filter(
({ category }) => category === instrumentCategory
);
return instruments
}
const regex = /<\s*div\s+class=('|")card\1\s*>\s*<\s*h2\s*>[\s\w]+?<\/\s*h2\s*>\s*<\s*p\s*>\$\d+?<\/\s*p\s*>\s*<\/\s*div\s*>/;
```
## --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
--fcc-editable-region--
function instrumentCards(instrumentCategory) {
const instruments =
instrumentCategory === "all"
? instrumentsArr
: instrumentsArr.filter(
({ category }) => category === instrumentCategory
);
return instruments
}
--fcc-editable-region--
selectContainer.addEventListener("change", () => {
console.log(instrumentCards(selectContainer.value));
});
```

View File

@@ -0,0 +1,270 @@
---
id: 67213ce0a2ba1278a38df3a5
title: Step 13
challengeType: 0
dashedName: step-13
---
# --description--
Remove your `console.log` from the event listener and set the inner HTML of `productsContainer` to the result of calling `instrumentCards` with the selected category option.
Then, select different options from your dropdown and see the result in the preview window.
# --hints--
When the dropdown menu option is changed you should set the inner HTML of `productsContainer` to the result of the `instrumentCards` function called with the selected option as argument.
```js
let cardsArr = getCardsArr("all");
const testDiv = document.createElement("div");
testDiv.classList.add("products-container");
testDiv.innerHTML = cardsArr;
selectContainer.value = "all";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
cardsArr = getCardsArr("woodwinds");
testDiv.innerHTML = cardsArr;
selectContainer.value = "woodwinds";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
cardsArr = getCardsArr("brass");
testDiv.innerHTML = cardsArr;
selectContainer.value = "brass";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
cardsArr = getCardsArr("percussion");
testDiv.innerHTML = cardsArr;
selectContainer.value = "percussion";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
```
You should remove `console.log(instrumentCards(selectContainer.value))` from your event listener's callback.
```js
let flag = false;
const temp = console.log;
console.log = (arg) => {
if (arg === instrumentCards(selectContainer.value)) flag = true;
}
try {
selectContainer.dispatchEvent(new Event("change"));
assert.isFalse(flag);
} finally {
console.log = temp;
}
```
# --seed--
## --after-user-code--
```js
const allInstrmnts = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
function getCardsArr(family) {
const instrmnts =
family === "all"
? allInstrmnts
: allInstrmnts.filter(
({ category }) => category === family
);
return instrmnts
.map(({ instrument, price }) => {
return `
<div class="card">
<h2>${instrument}</h2>
<p>$${price}</p>
</div>
`;
})
}
```
## --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
function instrumentCards(instrumentCategory) {
const instruments =
instrumentCategory === "all"
? instrumentsArr
: instrumentsArr.filter(
({ category }) => category === instrumentCategory
);
return instruments
.map(({ instrument, price }) => {
return `
<div class="card">
<h2>${instrument}</h2>
<p>$${price}</p>
</div>
`;
})
}
--fcc-editable-region--
selectContainer.addEventListener("change", () => {
console.log(instrumentCards(selectContainer.value));
});
--fcc-editable-region--
```

View File

@@ -0,0 +1,427 @@
---
id: 672146dde7104896adb274ae
title: Step 14
challengeType: 0
dashedName: step-14
---
# --description--
When you select a category from the dropdown menu, the instrument cards are correctly filtered and displayed on the page, but you have to get rid of those commas in between the cards.
Do it by joining the array returned by `instrumentCards`. With that, your music instrument filter is complete.
# --hints--
You should join the array returned by the `instrumentCards` function. Do not modify your event listener.
```js
let cardsArr = getCardsArr("all");
const testDiv = document.createElement("div");
testDiv.classList.add("products-container");
testDiv.innerHTML = cardsArr;
selectContainer.value = "all";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
cardsArr = getCardsArr("woodwinds");
testDiv.innerHTML = cardsArr;
selectContainer.value = "woodwinds";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
cardsArr = getCardsArr("brass");
testDiv.innerHTML = cardsArr;
selectContainer.value = "brass";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
cardsArr = getCardsArr("percussion");
testDiv.innerHTML = cardsArr;
selectContainer.value = "percussion";
selectContainer.dispatchEvent(new Event("change"));
assert(productsContainer.isEqualNode(testDiv))
```
# --seed--
## --after-user-code--
```js
const allInstrmnts = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
function getCardsArr(family) {
const instrmnts =
family === "all"
? allInstrmnts
: allInstrmnts.filter(
({ category }) => category === family
);
return instrmnts
.map(({ instrument, price }) => {
return `
<div class="card">
<h2>${instrument}</h2>
<p>$${price}</p>
</div>
`;
})
.join("");
}
```
## --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>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
--fcc-editable-region--
function instrumentCards(instrumentCategory) {
const instruments =
instrumentCategory === "all"
? instrumentsArr
: instrumentsArr.filter(
({ category }) => category === instrumentCategory
);
return instruments
.map(({ instrument, price }) => {
return `
<div class="card">
<h2>${instrument}</h2>
<p>$${price}</p>
</div>
`;
})
}
--fcc-editable-region--
selectContainer.addEventListener("change", () => {
productsContainer.innerHTML = instrumentCards(selectContainer.value);
});
```
# --solutions--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Music Instruments product page</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<h1>Student Instruments</h1>
<main>
<select class="select-container">
<option id="all" value="all">All</option>
<option id="woodwinds" value="woodwinds">Woodwinds</option>
<option id="brass" value="brass">Brass</option>
<option id="percussion" value="percussion">Percussion</option>
</select>
<div class="products-container">
<div class="card">
<h2>Flute</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Clarinet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Oboe</h2>
<p>$4000</p>
</div>
<div class="card">
<h2>Trumpet</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Trombone</h2>
<p>$300</p>
</div>
<div class="card">
<h2>French Horn</h2>
<p>$4300</p>
</div>
<div class="card">
<h2>Drum Set</h2>
<p>$500</p>
</div>
<div class="card">
<h2>Xylophone</h2>
<p>$3000</p>
</div>
<div class="card">
<h2>Cymbals</h2>
<p>$200</p>
</div>
<div class="card">
<h2>Marimba</h2>
<p>$3000</p>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--dark-grey: #0a0a23;
--white: #ffffff;
--yellow: #f1be32;
}
body {
background-color: var(--dark-grey);
color: var(--white);
}
h1 {
text-align: center;
margin-top: 20px;
}
.select-container {
display: block;
margin: 25px auto;
padding: 8px;
border: 4px solid var(--white);
border-radius: 4px;
width: 200px;
}
.products-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (min-width: 760px) {
.products-container {
flex-direction: row;
}
}
.card {
background-color: var(--white);
color: var(--dark-grey);
border: 4px solid var(--yellow);
border-radius: 5px;
padding: 10px;
width: 200px;
}
```
```js
const instrumentsArr = [
{ category: "woodwinds", instrument: "Flute", price: 500 },
{ category: "woodwinds", instrument: "Clarinet", price: 200 },
{ category: "woodwinds", instrument: "Oboe", price: 4000 },
{ category: "brass", instrument: "Trumpet", price: 200 },
{ category: "brass", instrument: "Trombone", price: 300 },
{ category: "brass", instrument: "French Horn", price: 4300 },
{ category: "percussion", instrument: "Drum Set", price: 500 },
{ category: "percussion", instrument: "Xylophone", price: 3000 },
{ category: "percussion", instrument: "Cymbals", price: 200 },
{ category: "percussion", instrument: "Marimba", price: 3000 }
]
const selectContainer = document.querySelector("select");
const productsContainer = document.querySelector(".products-container");
function instrumentCards(instrumentCategory) {
const instruments =
instrumentCategory === "all"
? instrumentsArr
: instrumentsArr.filter(
({ category }) => category === instrumentCategory
);
return instruments
.map(({ instrument, price }) => {
return `
<div class="card">
<h2>${instrument}</h2>
<p>$${price}</p>
</div>
`;
})
.join("");
}
selectContainer.addEventListener("change", () => {
productsContainer.innerHTML = instrumentCards(selectContainer.value);
});
```

View File

@@ -402,6 +402,7 @@
{
"dashedName": "lecture-understanding-the-event-object-and-event-delegation"
},
{ "dashedName": "workshop-music-instrument-filter" },
{ "dashedName": "lab-real-time-counter" },
{ "dashedName": "lab-lightbox-viewer" },
{ "dashedName": "workshop-rps-game" },