mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-24 16:01:05 -04:00
feat(curriculum): add music filter workshop to FSDC (#57025)
Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>
This commit is contained in:
@@ -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"]
|
||||
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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);
|
||||
});
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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));
|
||||
});
|
||||
```
|
||||
@@ -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--
|
||||
```
|
||||
@@ -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);
|
||||
});
|
||||
```
|
||||
@@ -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" },
|
||||
|
||||
Reference in New Issue
Block a user