feat: rewrite calorie counter project (#48927)

Co-authored-by: Jessica Wilkins  <67210629+jdwilkin4@users.noreply.github.com>
Co-authored-by: Krzysztof G. <60067306+gikf@users.noreply.github.com>
Co-authored-by: scissorsneedfoodtoo <scissorsneedfoodtoo@gmail.com>
Co-authored-by: Kristofer Koishigawa <scissorsneedfoodtoo@gmail.com>
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Naomi Carrigan
2023-03-27 01:36:35 -07:00
committed by GitHub
parent e3b25be4d9
commit 1d1174d4dd
171 changed files with 20725 additions and 13330 deletions

View File

@@ -15,303 +15,376 @@
"Step 1"
],
[
"5ddb965c65d27e1512d44d9b",
"63b606f09a14cc1781aea1fb",
"Step 2"
],
[
"5ddb965c65d27e1512d44d9c",
"63b6075a62883218d282504c",
"Step 3"
],
[
"5ddb965c65d27e1512d44d9d",
"63b607af6fcdb119aae9b16a",
"Step 4"
],
[
"5ddb965c65d27e1512d44d9e",
"63b60821c855d01b1eda3c0b",
"Step 5"
],
[
"5ddb965c65d27e1512d44d9f",
"63b6088bb56e2d1cac364043",
"Step 6"
],
[
"5ddb965c65d27e1512d44da0",
"63b608ebf40c871d960fc004",
"Step 7"
],
[
"5ddb965c65d27e1512d44da1",
"63b60a140bf5a321d50a7315",
"Step 8"
],
[
"5ddb965c65d27e1512d44da2",
"63b60aaaa65f8922bfce6b7e",
"Step 9"
],
[
"5ddb965c65d27e1512d44da3",
"63b60af1a0b9f7238a9dd294",
"Step 10"
],
[
"5ddb965c65d27e1512d44da4",
"63b60c09c5039f25a3b2dda9",
"Step 11"
],
[
"5ddb965c65d27e1512d44da5",
"63b60ca38c897f2721b27959",
"Step 12"
],
[
"5ddb965c65d27e1512d44da6",
"63b60cfaca25bb27edd40f62",
"Step 13"
],
[
"5ddb965c65d27e1512d44da7",
"63b60d3c5048302906962231",
"Step 14"
],
[
"5ddb965c65d27e1512d44da8",
"63b613f367584d2a5d041b7d",
"Step 15"
],
[
"5ddb965c65d27e1512d44da9",
"63b61490e633a22b4593e62f",
"Step 16"
],
[
"5ddb965c65d27e1512d44daa",
"63b614e6a1f7fe2cef6312dc",
"Step 17"
],
[
"5ddb965c65d27e1512d44dab",
"63b6152e6aff882db819fc1e",
"Step 18"
],
[
"5ddb965c65d27e1512d44dac",
"63b61584def8fa2ebcc259e0",
"Step 19"
],
[
"5ddb965c65d27e1512d44dad",
"63bf43be3f969d24d4ed233c",
"Step 20"
],
[
"5e302e80e003129199103c78",
"63bf446945d34d25e6db6e4f",
"Step 21"
],
[
"5e302e8ce003129199103c79",
"63bf45ce0dc8d4270760c6d0",
"Step 22"
],
[
"5ddb965c65d27e1512d44dae",
"63bf461011fca327d3b60fa8",
"Step 23"
],
[
"5ddb965c65d27e1512d44daf",
"63bf47fd40599f29827f484d",
"Step 24"
],
[
"5ddb965c65d27e1512d44db0",
"63bf492b6dfb292a79f0e675",
"Step 25"
],
[
"5ddb965c65d27e1512d44db1",
"63bf4bfe9de3852be51c8f86",
"Step 26"
],
[
"5ddb965c65d27e1512d44db2",
"63bf4d351e06432ce9bf3627",
"Step 27"
],
[
"5ddb965c65d27e1512d44db3",
"63bf511b85b6082e54dc1573",
"Step 28"
],
[
"5ddb965c65d27e1512d44db4",
"63bf5230bccd1c2f5c13e1ce",
"Step 29"
],
[
"5ddb965c65d27e1512d44db5",
"63bf598a4c807930a13a1a27",
"Step 30"
],
[
"5ddb965c65d27e1512d44db6",
"63bf5a518d54f63181ab639a",
"Step 31"
],
[
"5ddb965c65d27e1512d44db7",
"63bf5a92fd148d3264d5322b",
"Step 32"
],
[
"5ddb965c65d27e1512d44db8",
"63bf5adfe2981b332eb007b6",
"Step 33"
],
[
"5ddb965c65d27e1512d44db9",
"63bf5bcfebff0734593fad19",
"Step 34"
],
[
"5ddb965c65d27e1512d44dba",
"63bf5c438f523a359769106c",
"Step 35"
],
[
"5ddb965c65d27e1512d44dbb",
"63bf5cf03b50bf36cfbe94ea",
"Step 36"
],
[
"5ddb965c65d27e1512d44dbc",
"63c1dfbd56c71e278800010c",
"Step 37"
],
[
"5ddb965c65d27e1512d44dbd",
"63c1e0af28078f2dfad9eb3e",
"Step 38"
],
[
"5ddb965c65d27e1512d44dbe",
"63c1e1965a898d302e0af4e3",
"Step 39"
],
[
"5ddb965c65d27e1512d44dbf",
"63c1e5b4b3c8a031def3bd65",
"Step 40"
],
[
"5ddb965c65d27e1512d44dc0",
"63c1e704ee12703347625900",
"Step 41"
],
[
"5ddb965c65d27e1512d44dc1",
"63c2164c0df38a382062c4af",
"Step 42"
],
[
"5ddb965c65d27e1512d44dc2",
"63c216da562fbb3957b9cb2c",
"Step 43"
],
[
"5ddb965c65d27e1512d44dc3",
"63c2171c1e5b6e3aa51768d0",
"Step 44"
],
[
"5ddb965c65d27e1512d44dc4",
"63c21774193de43bbc6a769f",
"Step 45"
],
[
"5ddb965c65d27e1512d44dc5",
"63c217ccd939053ce4fa16d6",
"Step 46"
],
[
"5ddb965c65d27e1512d44dc6",
"63c21839f56eaf3ef4e027c4",
"Step 47"
],
[
"5ddb965c65d27e1512d44dc7",
"63c2187f55eb0f400269568f",
"Step 48"
],
[
"5ddb965c65d27e1512d44dc8",
"63c218c028c56a411b2a379a",
"Step 49"
],
[
"5ddb965c65d27e1512d44dc9",
"63c21dea919c8e4adb0df8e8",
"Step 50"
],
[
"5ddb965c65d27e1512d44dca",
"63c2194dce265f429300c8b1",
"Step 51"
],
[
"5ddb965c65d27e1512d44dcb",
"63c21c17fa8fd6447ff0389d",
"Step 52"
],
[
"5ddb965c65d27e1512d44dcc",
"63c21cd2c34541469f5700a9",
"Step 53"
],
[
"5ddb965c65d27e1512d44dcd",
"63c21d4f48267a47c2946788",
"Step 54"
],
[
"5ddb965c65d27e1512d44dce",
"63c8ab51214c8c1f1b9a49f7",
"Step 55"
],
[
"5ddb965c65d27e1512d44dcf",
"63c8ad0cd8f1e5201c4ef2e4",
"Step 56"
],
[
"5ddb965c65d27e1512d44dd0",
"63c8b0187cceff21c8389543",
"Step 57"
],
[
"5ddb965c65d27e1512d44dd1",
"63c8be904ffff922f3c6f8d0",
"Step 58"
],
[
"5ddb965c65d27e1512d44dd2",
"63c8c00bfb671b23f9de4159",
"Step 59"
],
[
"5ddb965c65d27e1512d44dd3",
"63c8c15fd337ad24b9b68049",
"Step 60"
],
[
"5ddb965c65d27e1512d44dd4",
"63c9bc53735149084390e5d0",
"Step 61"
],
[
"5ddb965c65d27e1512d44dd5",
"63c9bcc26219e7090da0f549",
"Step 62"
],
[
"5ddb965c65d27e1512d44dd6",
"63c9bce376ca4f09c15a3768",
"Step 63"
],
[
"5ddb965c65d27e1512d44dd7",
"63c9bdd916e0c10af01ed8d7",
"Step 64"
],
[
"5ddb965c65d27e1512d44dd8",
"63c9be334f4a050c0b94bc93",
"Step 65"
],
[
"5ddb965c65d27e1512d44dd9",
"63c9bef7fec05c0d38853828",
"Step 66"
],
[
"5ddb965c65d27e1512d44dda",
"63c9bf80558d780e848b2987",
"Step 67"
],
[
"5ddb965c65d27e1512d44ddb",
"63c9c09a7daa4f0ff92c4023",
"Step 68"
],
[
"5ddb965c65d27e1512d44ddc",
"63c9c0d0857f0a10a57af936",
"Step 69"
],
[
"5ddb965c65d27e1512d44ddd",
"63c9c11a0a090311dff55564",
"Step 70"
],
[
"5ddb965c65d27e1512d44dde",
"63c9c16dd75dd212dc12363c",
"Step 71"
],
[
"5ddb965c65d27e1512d44ddf",
"63c9c1ef134f3513e751c975",
"Step 72"
],
[
"5ddb965c65d27e1512d44de0",
"63c9e3a83bb3e61a80eea564",
"Step 73"
],
[
"5ddb965c65d27e1512d44de1",
"63c9e45519caf31b987fbb5f",
"Step 74"
],
[
"5ddb965c65d27e1512d44de2",
"63c9e4d2ff41811dd640504f",
"Step 75"
],
[
"5ddb965c65d27e1512d44de3",
"63c9e51b3a007a1eba1cd0f6",
"Step 76"
],
[
"63c9e55b4b06c11fff555c64",
"Step 77"
],
[
"63c9e5eea8261d22856ead1c",
"Step 78"
],
[
"63c9e63bb1e32d23b6adbe44",
"Step 79"
],
[
"63c9e6b7c0303524af2d0bc2",
"Step 80"
],
[
"63c9e769df38c92635c158ba",
"Step 81"
],
[
"63c9e7d5b21eee2776ecc226",
"Step 82"
],
[
"63c9e84c9fe8ca28c4101189",
"Step 83"
],
[
"63c9e8fe3a6f022a05a04675",
"Step 84"
],
[
"63c9e94e9df7d72aed1c24bd",
"Step 85"
],
[
"63c9ea23dbadbf2c2764e3f5",
"Step 86"
],
[
"63c9ea9b16430f2d54522464",
"Step 87"
],
[
"63c9eb09bcfaa72e3da820a1",
"Step 88"
],
[
"63c9eb4a5d68f12f32d9b440",
"Step 89"
],
[
"63c9ebb7b12bca3025b0a935",
"Step 90"
],
[
"63c9ec044acedf312c4974ff",
"Step 91"
],
[
"63c9f24afbc9cf324dcaa9a4",
"Step 92"
],
[
"63c9f28bda3e3f336e21b6b4",
"Step 93"
],
[
"63c9f2bff625af342023512c",
"Step 94"
]
]}
]
}

View File

@@ -0,0 +1,122 @@
---
id: 5ddb965c65d27e1512d44d9a
title: Step 1
challengeType: 0
dashedName: step-1
---
# --description--
You have been provided with boilerplate CSS and HTML. However, you need to build your calorie counter form.
Feel free to explore the HTML and CSS, then add a `form` element and give it an `id` set to `calorie-counter`.
# --hints--
You should have a `form` element.
```js
assert.exists(document.querySelector('form'));
```
Your `form` element should have an `id` attribute set to `calorie-counter`.
```js
assert.equal(document.querySelector('form')?.id, 'calorie-counter');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
--fcc-editable-region--
--fcc-editable-region--
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,146 @@
---
id: 63b606f09a14cc1781aea1fb
title: Step 2
challengeType: 0
dashedName: step-2
---
# --description--
Create a `label` element, give it a `for` attribute set to `budget` and the text `Budget`, then create an `input` element with the `id` set to `budget`.
# --hints--
You should create a `label` element in your `form`.
```js
assert.exists(document.querySelector('form label'));
```
Your `label` element should have a `for` attribute set to `budget`.
```js
assert.equal(document.querySelector('form label')?.getAttribute('for'), 'budget');
```
Your `label` element should have the text `Budget`.
```js
assert.equal(document.querySelector('form label')?.innerText, 'Budget');
```
You should create an `input` element within your `form`.
```js
assert.exists(document.querySelector('form input'));
```
Your `input` element should come after your `label` element.
```js
assert.equal(document.querySelector('form input')?.previousElementSibling?.tagName, "LABEL");
```
Your `input` element should have an `id` set to `budget`.
```js
assert.equal(document.querySelector('form input')?.id, "budget");
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
--fcc-editable-region--
<form id="calorie-counter">
</form>
--fcc-editable-region--
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,131 @@
---
id: 63b6075a62883218d282504c
title: Step 3
challengeType: 0
dashedName: step-3
---
# --description--
Your `input` element needs some additional attributes. Give it a `type` set to `number` to only allow numeric inputs, a `min` attribute set to `0` to only allow positive numbers, and a `placeholder` set to `Daily calorie budget`.
Finally, mark the `input` element as `required`.
# --hints--
Your `input` element should have a `type` attribute set to `number`.
```js
assert.equal(document.querySelector('form input').type, 'number');
```
Your `input` element should have a `min` attribute set to `0`.
```js
assert.equal(document.querySelector('form input').min, '0');
```
Your `input` element should have a `placeholder` attribute set to `Daily calorie budget`.
```js
assert.equal(document.querySelector('form input').placeholder, 'Daily calorie budget');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
--fcc-editable-region--
<form id="calorie-counter">
<label for="budget">Budget</label>
<input id="budget" />
</form>
--fcc-editable-region--
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,168 @@
---
id: 63b607af6fcdb119aae9b16a
title: Step 4
challengeType: 0
dashedName: step-4
---
# --description--
Create a `fieldset` element with the `id` set to `breakfast`.
Within that element, create a `legend` with the text `Breakfast`, and an empty `div` with the `class` set to `input-container`.
# --hints--
You should create a `fieldset` element in your `form`.
```js
assert.exists(document.querySelector('form fieldset'));
```
Your `fieldset` element should come after your `input` element.
```js
assert.equal(document.querySelector('form fieldset')?.previousElementSibling?.tagName, "INPUT");
```
Your `fieldset` element should have an `id` set to `breakfast`.
```js
assert.equal(document.querySelector('form fieldset')?.id, "breakfast");
```
You should create a `legend` element within your `fieldset`.
```js
assert.exists(document.querySelector('form fieldset legend'));
```
Your `legend` element should have the text `Breakfast`.
```js
assert.equal(document.querySelector('form fieldset legend')?.innerText, "Breakfast");
```
You should create a `div` element within your `fieldset`.
```js
assert.exists(document.querySelector('form fieldset div'));
```
Your `div` element should come after your `legend` element.
```js
assert.equal(document.querySelector('form fieldset div')?.previousElementSibling?.tagName, "LEGEND");
```
Your `div` element should have a `class` set to `input-container`.
```js
assert.equal(document.querySelector('form fieldset div')?.className, "input-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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
--fcc-editable-region--
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,164 @@
---
id: 63b60821c855d01b1eda3c0b
title: Step 5
challengeType: 0
dashedName: step-5
---
# --description--
Now create a `fieldset` with an `id` set to `lunch`, and a corresponding `legend` and `div` element.
# --hints--
You should create a second `fieldset` element in your `form`.
```js
assert.exists(document.querySelectorAll('form fieldset')[1]);
```
Your second `fieldset` element should come after your first `fieldset` element.
```js
assert.equal(document.querySelectorAll('form fieldset')[1]?.previousElementSibling?.tagName, "FIELDSET");
```
Your second `fieldset` element should have an `id` set to `lunch`.
```js
assert.equal(document.querySelectorAll('form fieldset')[1]?.id, "lunch");
```
Your second `fieldset` element should contain a `legend` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[1]?.querySelector('legend'));
```
Your new `legend` element should have the text `Lunch`.
```js
assert.equal(document.querySelectorAll('form fieldset')[1]?.querySelector('legend')?.innerText, "Lunch");
```
Your second `fieldset` element should contain a `div` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[1]?.querySelector('div'));
```
Your new `div` element should have a `class` set to `input-container`.
```js
assert.equal(document.querySelectorAll('form fieldset')[1]?.querySelector('div')?.className, "input-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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
--fcc-editable-region--
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,168 @@
---
id: 63b6088bb56e2d1cac364043
title: Step 6
challengeType: 0
dashedName: step-6
---
# --description--
Continuing the pattern, create a `fieldset` for `dinner` with the same nested elements.
# --hints--
You should create a third `fieldset` element in your `form`.
```js
assert.exists(document.querySelectorAll('form fieldset')[2]);
```
Your third `fieldset` element should come after your second `fieldset` element.
```js
assert.equal(document.querySelectorAll('form fieldset')[2]?.previousElementSibling?.tagName, "FIELDSET");
```
Your third `fieldset` element should have an `id` set to `dinner`.
```js
assert.equal(document.querySelectorAll('form fieldset')[2]?.id, "dinner");
```
Your third `fieldset` element should contain a `legend` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[2]?.querySelector('legend'));
```
Your new `legend` element should have the text `Dinner`.
```js
assert.equal(document.querySelectorAll('form fieldset')[2]?.querySelector('legend')?.innerText, "Dinner");
```
Your third `fieldset` element should contain a `div` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[2]?.querySelector('div'));
```
Your new `div` element should have a `class` set to `input-container`.
```js
assert.equal(document.querySelectorAll('form fieldset')[2]?.querySelector('div')?.className, "input-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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
--fcc-editable-region--
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,214 @@
---
id: 63b608ebf40c871d960fc004
title: Step 7
challengeType: 0
dashedName: step-7
---
# --description--
You need two more of these `fieldset` code blocks one for `snacks` and one for `exercise`.
# --hints--
You should create a fourth `fieldset` element in your `form`.
```js
assert.exists(document.querySelectorAll('form fieldset')[3]);
```
Your fourth `fieldset` element should come after your third `fieldset` element.
```js
assert.equal(document.querySelectorAll('form fieldset')[3]?.previousElementSibling?.tagName, "FIELDSET");
```
Your fourth `fieldset` element should have an `id` set to `snacks`.
```js
assert.equal(document.querySelectorAll('form fieldset')[3]?.id, "snacks");
```
Your fourth `fieldset` element should contain a `legend` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[3]?.querySelector('legend'));
```
Your fourth `legend` element should have the text `Snacks`.
```js
assert.equal(document.querySelectorAll('form fieldset')[3]?.querySelector('legend')?.innerText, "Snacks");
```
Your fourth `fieldset` element should contain a `div` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[3]?.querySelector('div'));
```
Your fifth `div` element should have a `class` set to `input-container`.
```js
assert.equal(document.querySelectorAll('form fieldset')[3]?.querySelector('div')?.className, "input-container");
```
You should create a fifth `fieldset` element in your `form`.
```js
assert.exists(document.querySelectorAll('form fieldset')[4]);
```
Your fifth `fieldset` element should come after your fourth `fieldset` element.
```js
assert.equal(document.querySelectorAll('form fieldset')[4]?.previousElementSibling?.tagName, "FIELDSET");
```
Your fifth `fieldset` element should have an `id` set to `exercise`.
```js
assert.equal(document.querySelectorAll('form fieldset')[4]?.id, "exercise");
```
Your fifth `fieldset` element should contain a `legend` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[4]?.querySelector('legend'));
```
Your fifth `legend` element should have the text `Exercise`.
```js
assert.equal(document.querySelectorAll('form fieldset')[4]?.querySelector('legend')?.innerText, "Exercise");
```
Your fifth `fieldset` element should contain a `div` element.
```js
assert.exists(document.querySelectorAll('form fieldset')[4]?.querySelector('div'));
```
Your fifth `div` element should have a `class` set to `input-container`.
```js
assert.equal(document.querySelectorAll('form fieldset')[4]?.querySelector('div')?.className, "input-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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
--fcc-editable-region--
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,163 @@
---
id: 63b60a140bf5a321d50a7315
title: Step 8
challengeType: 0
dashedName: step-8
---
# --description--
Create a `div` and give it a `class` set to `controls`. Nest a `span` element within that `div`.
# --hints--
You should create a new `div` element in your `form`.
```js
assert.exists(document.querySelector('form > div'));
```
Your `div` element should come after your `fieldset` elements.
```js
assert.equal(document.querySelector('form > div')?.previousElementSibling?.tagName, "FIELDSET");
assert.notExists(document.querySelector('form > div')?.nextElementSibling);
```
Your `div` element should have a `class` attribute set to `controls`.
```js
assert.equal(document.querySelector('form > div')?.className, "controls");
```
You should nest a `span` element within your `div`.
```js
assert.exists(document.querySelector('form > div > span'));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
--fcc-editable-region--
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,210 @@
---
id: 63b60aaaa65f8922bfce6b7e
title: Step 9
challengeType: 0
dashedName: step-9
---
# --description--
In your `span` element, create a `label` element for an `entry-dropdown` and give it the text `Add food or exercise:`. Then create a `select` element with the `id` set to `entry-dropdown` and a `name` set to `options`. Below that, add a `button` element with the `id` set to `add-entry` and the text `Add Entry`.
Give your `button` element a `type` attribute set to `button` to prevent automatic form submission.
# --hints--
You should add a `label` element to your `span` element.
```js
assert.exists(document.querySelector('.controls > span > label'));
```
Your new `label` element should have a `for` attribute set to `entry-dropdown`.
```js
assert.equal(document.querySelector('.controls > span > label')?.getAttribute('for'), 'entry-dropdown');
```
Your new `label` element should have the text `Add food or exercise:`.
```js
assert.equal(document.querySelector('.controls > span > label')?.innerText, 'Add food or exercise:');
```
You should add a `select` element to your `span` element.
```js
assert.exists(document.querySelector('.controls > span > select'));
```
Your `select` element should come after your `label` element.
```js
assert(document.querySelector('.controls > span > select')?.previousElementSibling?.tagName === 'LABEL');
```
Your new `select` element should have an `id` attribute set to `entry-dropdown`.
```js
assert.equal(document.querySelector('.controls > span > select')?.getAttribute('id'), 'entry-dropdown');
```
Your new `select` element should have a `name` attribute set to `options`.
```js
assert.equal(document.querySelector('.controls > span > select')?.getAttribute('name'), 'options');
```
You should add a `button` element to your `span` element.
```js
assert.exists(document.querySelector('.controls > span > button'));
```
Your `button` element should come after your `select` element.
```js
assert(document.querySelector('.controls > span > button')?.previousElementSibling?.tagName === 'SELECT');
```
Your new `button` element should have an `id` attribute set to `add-entry`.
```js
assert.equal(document.querySelector('.controls > span > button')?.getAttribute('id'), 'add-entry');
```
Your new `button` element should have the text `Add Entry`.
```js
assert.equal(document.querySelector('.controls > span > button')?.innerText, 'Add Entry');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
--fcc-editable-region--
<div class="controls">
<span>
</span>
</div>
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,220 @@
---
id: 63b60af1a0b9f7238a9dd294
title: Step 10
challengeType: 0
dashedName: step-10
---
# --description--
Your select menu needs options for each of the food and exercise `fieldset` elements you created in the previous steps. Use the `option` element to create a new option for each `fieldset`. The `value` attribute of each option should be the `id` of the `fieldset`, and the text of each option should be the text of the `legend`.
Set the `Breakfast` option as the `selected` option.
# --hints--
You should create five `option` elements within your `select` element.
```js
assert.equal(document.querySelectorAll('.controls select option')?.length, 5);
```
Your first `option` should have the text `Breakfast`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[0]?.textContent, 'Breakfast');
```
Your first `option` should have the `value` attribute set to `breakfast`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[0]?.value, 'breakfast');
```
Your second `option` should have the text `Lunch`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[1]?.textContent, 'Lunch');
```
Your second `option` should have the `value` attribute set to `lunch`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[1]?.value, 'lunch');
```
Your third `option` should have the text `Dinner`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[2]?.textContent, 'Dinner');
```
Your third `option` should have the `value` attribute set to `dinner`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[2]?.value, 'dinner');
```
Your fourth `option` should have the text `Snacks`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[3]?.textContent, 'Snacks');
```
Your fourth `option` should have the `value` attribute set to `snacks`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[3]?.value, 'snacks');
```
Your fifth `option` should have the text `Exercise`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[4]?.textContent, 'Exercise');
```
Your fifth `option` should have the `value` attribute set to `exercise`.
```js
assert.equal(document.querySelectorAll('.controls select option')?.[4]?.value, 'exercise');
```
Your first `option` should be selected by default.
```js
assert.isTrue(document.querySelectorAll('.controls select option')?.[0]?.getAttributeNames()?.includes('selected'));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
--fcc-editable-region--
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,207 @@
---
id: 63b60c09c5039f25a3b2dda9
title: Step 11
challengeType: 0
dashedName: step-11
---
# --description--
Create another `div` element. Within it, nest a `button` to `submit` the form, with an `id` set to `calculate-calories`. This button should have the text `Calculate Remaining Calories`.
Then add a `button` with the `id` set to `clear` to clear the form (don't forget to give it a `type` attribute that prevents it from submitting the form). This button needs the text `Clear`.
# --hints--
You should create a second `div` element.
```js
assert.equal(document.querySelectorAll('form > div')?.length, 2);
```
Your new `div` element should have a `button` element.
```js
assert.exists(document.querySelectorAll('form > div')?.[1]?.querySelector('button'));
```
Your `button` element should have a `type` attribute set to `submit`.
```js
assert.equal(document.querySelectorAll('form > div')?.[1]?.querySelector('button')?.getAttribute('type'), 'submit');
```
Your `button` element should have an `id` attribute set to `calculate-calories`.
```js
assert.equal(document.querySelectorAll('form > div')?.[1]?.querySelector('button')?.getAttribute('id'), 'calculate-calories');
```
Your `button` element should have the text `Calculate Remaining Calories`.
```js
assert.equal(document.querySelectorAll('form > div')?.[1]?.querySelector('button')?.innerText, 'Calculate Remaining Calories');
```
Your `div` element should have a second `button` element.
```js
assert.exists(document.querySelectorAll('form > div')?.[1]?.querySelectorAll('button')?.[1]);
```
Your second `button` element should have a `type` attribute set to `button`.
```js
assert.equal(document.querySelectorAll('form > div')?.[1]?.querySelectorAll('button')?.[1]?.getAttribute('type'), 'button');
```
Your second `button` element should have an `id` attribute set to `clear`.
```js
assert.equal(document.querySelectorAll('form > div')?.[1]?.querySelectorAll('button')?.[1]?.getAttribute('id'), 'clear');
```
Your second `button` element should have the text `Clear`.
```js
assert.equal(document.querySelectorAll('form > div')?.[1]?.querySelectorAll('button')?.[1]?.innerText, 'Clear');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
--fcc-editable-region--
--fcc-editable-region--
</form>
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,182 @@
---
id: 63b60ca38c897f2721b27959
title: Step 12
challengeType: 0
dashedName: step-12
---
# --description--
Your form needs somewhere to display the results. Add an empty `div` element and give it an `id` of `output` and the `class` values of `output` and `hide`.
# --hints--
You should add a `div` element after your `form`.
```js
assert.exists(document.querySelector('.container > div'));
```
Your new `div` element should have an `id` set to `output`.
```js
assert.equal(document.querySelector('.container > div')?.id, 'output');
```
Your new `div` element should have the `class` values of `output` and `hide`.
```js
assert.include(document.querySelector('.container > div')?.className.split(/\s+/), 'output');
assert.include(document.querySelector('.container > div')?.className.split(/\s+/), 'hide');
```
Your new `div` should be empty.
```js
assert.equal(document.querySelector('.container > div')?.innerHTML, '');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
--fcc-editable-region--
--fcc-editable-region--
</div>
</main>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,170 @@
---
id: 63b60cfaca25bb27edd40f62
title: Step 13
challengeType: 0
dashedName: step-13
---
# --description--
Finally, you need to link your JavaScript file to your HTML. Create a `script` element to do so.
# --hints--
You should have a `script` element.
```js
assert.isAtLeast(document.querySelectorAll('script')?.length, 1);
```
Your `script` element should have the `src` set to `./script.js`.
```js
assert.match(code, /script\s*?src\s*?=\s*?('|")(\.\/)?script\.js\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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
--fcc-editable-region--
--fcc-editable-region--
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
```

View File

@@ -0,0 +1,176 @@
---
id: 63b60d3c5048302906962231
title: Step 14
challengeType: 0
dashedName: step-14
---
# --description--
It is time to start writing the script that makes your form work. Begin by getting the `form` element (using the `id`) and storing it in a variable called `calorieCounter`.
# --hints--
You should create a variable called `calorieCounter`.
```js
assert.isDefined(calorieCounter);
```
You should use `document.getElementById()` to get the `#calorie-counter` element.
```js
assert.match(code, /document\.getElementById\(\s*('|")calorie-counter\1\s*\)/g);
```
You should store the `#calorie-counter` element in a variable called `calorieCounter`.
```js
assert.equal(calorieCounter, document.getElementById('calorie-counter'));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,195 @@
---
id: 63b613f367584d2a5d041b7d
title: Step 15
challengeType: 0
dashedName: step-15
---
# --description--
Get your `#budget` element and assign it to `budgetNumberInput`, and your `#entry-dropdown` element and assign it to `entryDropdown`.
# --hints--
You should declare a variable called `budgetNumberInput`.
```js
assert.isDefined(budgetNumberInput);
```
You should use `document.getElementById()` to get the `#budget` element.
```js
assert.match(code, /document\.getElementById\(\s*('|")budget\1\s*\)/g);
```
You should store the `#budget` element in a variable called `budgetNumberInput`.
```js
assert.equal(budgetNumberInput, document.getElementById('budget'));
```
You should declare a variable called `entryDropdown`.
```js
assert.isDefined(entryDropdown);
```
You should use `document.getElementById()` to get the `#entry-dropdown` element.
```js
assert.match(code, /document\.getElementById\(\s*('|")entry-dropdown\1\s*\)/g);
```
You should store the `#entry-dropdown` element in a variable called `entryDropdown`.
```js
assert.equal(entryDropdown, document.getElementById('entry-dropdown'));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
--fcc-editable-region--
const calorieCounter = document.getElementById('calorie-counter');
--fcc-editable-region--
```

View File

@@ -0,0 +1,215 @@
---
id: 63b61490e633a22b4593e62f
title: Step 16
challengeType: 0
dashedName: step-16
---
# --description--
Following the same pattern, assign your `#add-entry` element to `addEntryButton`, your `#clear` element to `clearButton`, and your `#output` element to `output`.
# --hints--
You should declare a variable called `addEntryButton`.
```js
assert.isDefined(addEntryButton);
```
You should use `document.getElementById()` to get the `#add-entry` element.
```js
assert.match(code, /document\.getElementById\(\s*('|")add-entry\1\s*\)/g);
```
You should assign the `#add-entry` element to `addEntryButton`.
```js
assert.equal(addEntryButton, document.getElementById('add-entry'));
```
You should declare a variable called `clearButton`.
```js
assert.isDefined(clearButton);
```
You should use `document.getElementById()` to get the `#clear` element.
```js
assert.match(code, /document\.getElementById\(\s*('|")clear\1\s*\)/g);
```
You should assign the `#clear` element to `clearButton`.
```js
assert.equal(clearButton, document.getElementById('clear'));
```
You should declare a variable called `output`.
```js
assert.isDefined(output);
```
You should use `document.getElementById()` to get the `#output` element.
```js
assert.match(code, /document\.getElementById\(\s*('|")output\1\s*\)/g);
```
You should assign the `#output` element to `output`.
```js
assert.equal(output, document.getElementById("output"));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
--fcc-editable-region--
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
--fcc-editable-region--
```

View File

@@ -0,0 +1,182 @@
---
id: 63b614e6a1f7fe2cef6312dc
title: Step 17
challengeType: 0
dashedName: step-17
---
# --description--
Declare an `isError` variable and set it to `false`, but use `let` so you can reassign it later.
# --hints--
You should declare an `isError` variable.
```js
assert.isDefined(isError);
```
Your `isError` variable should be set to `false`.
```js
assert.isFalse(isError);
```
You should use `let` to declare your `isError` variable.
```js
assert.match(code, /let\s+isError\s*=\s*false/g);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
--fcc-editable-region--
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
--fcc-editable-region--
```

View File

@@ -0,0 +1,192 @@
---
id: 63b6152e6aff882db819fc1e
title: Step 18
challengeType: 0
dashedName: step-18
---
# --description--
Even though you set an `input` element to be a number, JavaScript receives a string value. You need to write a function to clean the string value and ensure you have a number.
Start by declaring a `cleanInputString` function that takes a `str` argument.
# --hints--
You should declare a `cleanInputString` variable.
```js
assert.isDefined(cleanInputString);
```
Your `cleanInputString` variable should be a function.
```js
assert.isFunction(cleanInputString);
```
Your `cleanInputString` function should take a `str` argument.
```js
assert.match(cleanInputString?.toString(), /\(str\)/);
```
`cleanInputString` should be an empty function.
```js
assert.match(cleanInputString?.toString(), /\{\s*\}/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,182 @@
---
id: 63b61584def8fa2ebcc259e0
title: Step 19
challengeType: 0
dashedName: step-19
---
# --description--
You need to split your `str` into individual characters. Remember that strings have a `.split()` method, and if you pass an empty string it will split on every character.
Declare a `strArray` variable and assign it that split value.
# --hints--
Your `cleanInputString` function should declare a `strArray` variable.
```js
assert.match(cleanInputString.toString(), /strArray\s*=/);
```
Your `strArray` variable should be assigned the value of `str.split('')`.
```js
assert.match(cleanInputString.toString(), /strArray\s*=\s*str\.split\(\s*('|")\1\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,181 @@
---
id: 63bf43be3f969d24d4ed233c
title: Step 20
challengeType: 0
dashedName: step-20
---
# --description--
Declare a `cleanStrArray` variable and assign it an empty array. You will use this to store your valid number characters.
# --hints--
Your `cleanInputString` should declare a variable called `cleanStrArray`.
```js
assert.match(cleanInputString.toString(), /cleanStrArray\s*/g);
```
Your `cleanStrArray` variable should be assigned an empty array.
```js
assert.match(cleanInputString.toString(), /cleanStrArray\s*=\s*\[\s*\]/g);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const strArray = str.split('');
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,195 @@
---
id: 63bf446945d34d25e6db6e4f
title: Step 21
challengeType: 0
dashedName: step-21
---
# --description--
Use a `for` loop to iterate through each character in your `strArray` array.
# --hints--
Your `cleanInputString` function should have a `for` loop.
```js
assert.match(cleanInputString.toString(), /for\s*\(/g);
```
Your `for` loop should initialize a variable called `i` to `0`.
```js
assert.match(cleanInputString.toString(), /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;/g);
```
Your `for` loop should have a condition that checks if `i` is less than the length of `strArray`.
```js
assert.match(cleanInputString.toString(), /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*strArray\.length\s*;/g);
```
Your `for` loop should increment `i` by `1` each time it runs. Use the increment operator for this.
```js
assert.match(cleanInputString.toString(), /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*strArray\.length\s*;\s*i\s*\+\+\s*\)/g);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const strArray = str.split('');
const cleanStrArray = [];
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,200 @@
---
id: 63bf45ce0dc8d4270760c6d0
title: Step 22
challengeType: 0
dashedName: step-22
---
# --description--
Within your loop, you need to check if the character in `strArray` at index `i` is not `+`, `-`, or a space. If it is not, `push` it to the `cleanStrArray`.
To check your character, see if the array `["+", "-", " "]` includes the character you can use the `.includes()` method on the array to do this.
# --hints--
Your `for` loop should have an `if` statement.
```js
assert.match(cleanInputString.toString(), /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*strArray\.length\s*;\s*i\s*\+\+\s*\)\s*\{\s*if\s*\(/);
```
Your `for` loop should use `!["+", "-", " "].includes()`.
```js
// the loop protection injects code so we have to look at the raw code directly
assert.match(code, /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*strArray\.length\s*;\s*i\s*\+\+\s*\)\s*\{\s*if\s*\(!\[("|')\+\2\s*,\s*("|')-\3\s*,\s*("|')\s\4\s*\]\.includes\(/);
```
Your `for` loop should see if `strArray[i]` is found in `["+", "-", " "]`.
```js
assert.match(code, /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*strArray\.length\s*;\s*i\s*\+\+\s*\)\s*\{\s*if\s*\(!\[("|')\+\2\s*,\s*("|')-\3\s*,\s*("|')\s\4\s*\]\.includes\(\s*strArray\[i\]\s*\)\)\s*\{/);
```
Your `for` loop should `push` `strArray[i]` to `cleanStrArray`.
```js
assert.match(code, /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*strArray\.length\s*;\s*i\s*\+\+\s*\)\s*\{\s*if\s*\(!\[("|')\+\2\s*,\s*("|')-\3\s*,\s*("|')\s\4\s*\]\.includes\(\s*strArray\[i\]\s*\)\)\s*\{\s*cleanStrArray\.push\(\s*strArray\[i\]\s*\)\s*\}/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const strArray = str.split('');
const cleanStrArray = [];
for (let i = 0; i < strArray.length; i++) {
}
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,213 @@
---
id: 63bf461011fca327d3b60fa8
title: Step 23
challengeType: 0
dashedName: step-23
---
# --description--
While looping through the string works, creating a new array is inefficient for memory and runtime performance. Instead, you can use Regular Expressions (referred to as "regex") to match specific characters.
Regex in JavaScript is indicated by a pattern wrapped in forward slashes for example:
```js
const regex = /hello/;
```
Remove your existing code within the `cleanInputString` function. Declare a `regex` variable and assign it the value from the example above.
# --hints--
You should remove the `cleanStrArray` variable.
```js
assert.notMatch(cleanInputString.toString(), /cleanStrArray/);
```
You should remove the `strArray` variable.
```js
assert.notMatch(cleanInputString.toString(), /strArray/);
```
You should not have a `for` loop.
```js
assert.notMatch(cleanInputString.toString(), /for/);
```
You should declare a `regex` variable.
```js
assert.match(cleanInputString.toString(), /regex\s*=/);
```
Your `regex` variable should be set to the regular expression `/hello/`.
```js
assert.match(cleanInputString.toString(), /regex\s*=\s*\/hello\//);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const strArray = str.split('');
const cleanStrArray = [];
for (let i = 0; i < strArray.length; i++) {
if (!["+", "-", " "].includes(strArray[i])) {
cleanStrArray.push(strArray[i])
}
}
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,176 @@
---
id: 63bf47fd40599f29827f484d
title: Step 24
challengeType: 0
dashedName: step-24
---
# --description--
The pattern you currently have will match the exact text `hello`, which is not what you want to match. You want to look for `+`, `-`, or spaces. Replace the pattern in your `regex` variable with `\+-` to look for plus and minus characters.
Note that you need to use the `\` to <dfn>escape</dfn> the `+`, because a `+` has a special meaning in regular expressions.
# --hints--
Your `regex` variable should be set to the regular expression `/\+-/`.
```js
assert.match(cleanInputString.toString(), /regex\s*=\s*\/\\\+-\//);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const regex = /hello/;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,174 @@
---
id: 63bf492b6dfb292a79f0e675
title: Step 25
challengeType: 0
dashedName: step-25
---
# --description--
In regex, shorthand character classes allow you to match specific characters without having to write those characters in your pattern. Shorthand character classes are preceded with a backslash (`\`). The character class `\s` will match any whitespace character. Add this to your regex pattern.
# --hints--
Your `regex` variable should be set to the regular expression `/\+-\s/`.
```js
assert.match(cleanInputString.toString(), /regex\s*=\s*\/\\\+-\\s\//)
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const regex = /\+-/;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,188 @@
---
id: 63bf4bfe9de3852be51c8f86
title: Step 26
challengeType: 0
dashedName: step-26
---
# --description--
Your current pattern won't work just yet. `/+-\s/` looks for `+`, `-`, and a space *in order*. This would match `+- hello` but would not match `+hello`.
To tell the pattern to match each of these characters individually, you need to turn them into a character class. This is done by wrapping the characters you want to match in brackets. For example, this pattern will match the characters `h`, `e`, `l`, or `o`:
```js
const regex = /[helo]/;
```
Turn your `+-\s` pattern into a character class. Note that you no longer need to escape the `+` character, because you are using a character class.
# --hints--
Your `regex` variable should be set to the regular expression `[+-\s]`.
```js
assert.match(cleanInputString.toString(), /regex\s*=\s*\/\[\\?\+-\\s\]\//)
```
You should not escape the `+` character in your regular expression.
```js
assert.match(cleanInputString.toString(), /regex\s*=\s*\/\[\+-\\s\]\//);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const regex = /\+-\s/;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,180 @@
---
id: 63bf4d351e06432ce9bf3627
title: Step 27
challengeType: 0
dashedName: step-27
---
# --description--
Regex can also take specific flags to alter the pattern matching behavior. Flags are added after the closing `/`. The `g` flag, which stands for "global", will tell the pattern to continue looking after it has found a match. Here is an example:
```js
const helloRegex = /hello/g;
```
Add the `g` flag to your regex pattern.
# --hints--
You should add the `g` flag to your `regex` value.
```js
assert.match(cleanInputString.toString(), /regex\s*=\s*\/\[\+-\\s\]\/g/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const regex = /[+-\s]/;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,199 @@
---
id: 63bf511b85b6082e54dc1573
title: Step 28
challengeType: 0
dashedName: step-28
---
# --description--
Strings have a `.replace()` method which allows you to replace characters in the string with another string. `.replace` takes two arguments. The first is the character sequence to replace this can either be a string or a regex pattern. The second is the string to replace that sequence with. For example, this would replace all instances of `l` with `1`:
```js
"hello".replace(/l/g, "1");
```
Use your `regex` to replace all instances of `+`, `-`, and a space in `str` with an empty string. Return this value.
# --hints--
Your `cleanInputString` should call the `replace` method of `str`.
```js
assert.match(cleanInputString.toString(), /str\.replace\(/);
```
You should pass `regex` as the first argument to `replace`.
```js
assert.match(cleanInputString.toString(), /str\.replace\(\s*regex\s*/);
```
You should pass `""` as the second argument to `replace`.
```js
assert.match(cleanInputString.toString(), /str\.replace\(\s*regex\s*,\s*("|')\1\s*\)/);
```
Your `cleanInputString` function should directly return the result of your `replace` method.
```js
assert.match(cleanInputString.toString(), /return\s*str\.replace\(\s*regex\s*,\s*("|')\1\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
--fcc-editable-region--
function cleanInputString(str) {
const regex = /[+-\s]/g;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,191 @@
---
id: 63bf5230bccd1c2f5c13e1ce
title: Step 29
challengeType: 0
dashedName: step-29
---
# --description--
In HTML, number inputs allow for exponential notation (such as `1e10`). You need to filter those out.
Start by creating a function called `isInvalidInput` it should take a single `str` parameter.
# --hints--
You should declare an `isInvalidInput` variable.
```js
assert.isDefined(isInvalidInput)
```
`isInvalidInput` should be a function.
```js
assert.isFunction(isInvalidInput)
```
`isInvalidInput` should take a single `str` parameter.
```js
assert.match(isInvalidInput?.toString(), /\(\s*str\s*\)/)
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,185 @@
---
id: 63bf598a4c807930a13a1a27
title: Step 30
challengeType: 0
dashedName: step-30
---
# --description--
Declare a `regex` variable, and assign it a regex that matches the character `e`.
# --hints--
Your `isInvalidInput` function should have a `regex` variable.
```js
assert.match(isInvalidInput.toString(), /regex\s*=/);
```
Your `regex` variable should be set to `/e/`.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/e\//);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
--fcc-editable-region--
function isInvalidInput(str) {
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,179 @@
---
id: 63bf5a518d54f63181ab639a
title: Step 31
challengeType: 0
dashedName: step-31
---
# --description--
The `e` in a number input can also be an uppercase `E`. Regex has a flag for this, however the `i` flag, which stands for "insensitive". This flag makes your pattern case-insensitive. Add the `i` flag to your regex pattern.
# --hints--
Your `regex` value should have the `i` flag.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/e\/i/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
--fcc-editable-region--
function isInvalidInput(str) {
const regex = /e/;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,187 @@
---
id: 63bf5a92fd148d3264d5322b
title: Step 32
challengeType: 0
dashedName: step-32
---
# --description--
Number inputs only allow the `e` to occur between two digits. To match any number, you can use the character class `[0-9]`. This will match any digit between `0` and `9`.
Add this character class before and after `e` in your pattern.
# --hints--
You should add the `[0-9]` character class before `e` in your regular expression.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/\[0-9\]e/);
```
You should add the `[0-9]` character class after `e` in your regular expression.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/\[0-9\]e\[0-9\]\//);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
--fcc-editable-region--
function isInvalidInput(str) {
const regex = /e/i;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,185 @@
---
id: 63bf5adfe2981b332eb007b6
title: Step 33
challengeType: 0
dashedName: step-33
---
# --description--
The `+` modifier in a regex allows you to match a pattern that occurs one or more times. To match your digit pattern one or more times, add a plus after each of the digit character classes. For example: `[0-9]+`.
# --hints--
You should add the `+` modifier to the character class before `e` in your regular expression.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/\[0-9\]\+e/);
```
You should add the `+` modifier to the character class after `e` in your regular expression.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/\[0-9\]\+e\[0-9\]\+\//);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
--fcc-editable-region--
function isInvalidInput(str) {
const regex = /[0-9]e[0-9]/i;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,185 @@
---
id: 63bf5bcfebff0734593fad19
title: Step 34
challengeType: 0
dashedName: step-34
---
# --description--
There is a shorthand character class to match any digit: `\d`. Replace your `[0-9]` character classes with this shorthand.
# --hints--
You should replace the `[0-9]` character class before `e` with `\d` in your regular expression.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/\\d\+e/);
```
You should replace the `[0-9]` character class after `e` with `\d` in your regular expression.
```js
assert.match(isInvalidInput.toString(), /regex\s*=\s*\/\\d\+e\\d\+\//);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
--fcc-editable-region--
function isInvalidInput(str) {
const regex = /[0-9]+e[0-9]+/i;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,194 @@
---
id: 63bf5c438f523a359769106c
title: Step 35
challengeType: 0
dashedName: step-35
---
# --description--
Strings have a `.match()` method, which takes a regex argument. `.match()` will return an array of match results containing either the first match, or all matches if the global flag is used.
Return the result of calling the `.match()` method on `str` and passing your `regex` variable as the argument. You'll use this match result later on.
# --hints--
Your `isInvalidInput` function should call the `.match()` method on `str`.
```js
assert.match(isInvalidInput.toString(), /str\.match\(/);
```
You should pass `regex` as the argument to the `.match()` method.
```js
assert.match(isInvalidInput.toString(), /str\.match\(\s*regex\s*\)/);
```
Your `isInvalidInput` function should directly return the result of the `.match()` call.
```js
assert.match(isInvalidInput.toString(), /return\s+str\.match\(\s*regex\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
--fcc-editable-region--
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,194 @@
---
id: 63bf5cf03b50bf36cfbe94ea
title: Step 36
challengeType: 0
dashedName: step-36
---
# --description--
Your next step is to allow users to add entries to the calorie counter. Declare an empty function `addEntry`. This function should not take any parameters.
# --hints--
You should declare an `addEntry` variable.
```js
assert.isDefined(addEntry);
```
Your `addEntry` variable should be a function.
```js
assert.isFunction(addEntry);
```
Your `addEntry` function should not take any parameters.
```js
assert.match(addEntry?.toString(), /\(\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,198 @@
---
id: 63c1dfbd56c71e278800010c
title: Step 37
challengeType: 0
dashedName: step-37
---
# --description--
You'll need to know which category the entry goes in. Thankfully, you added a dropdown for the user to select a category.
Remember that you queried that dropdown earlier in your JavaScript and assigned it to the `entryDropdown` button. Use concatenation to add `#` to the beginning of the `value` property of `entryDropdown`, and assign that result to a `targetId` variable.
# --hints--
Your `addEntry` function should have a `targetId` variable.
```js
assert.match(addEntry.toString(), /targetId\s*=/);
```
Your `targetId` variable should start with the string `#`.
```js
assert.match(addEntry.toString(), /targetId\s*=\s*('|")#\1/);
```
You should use concatenation to add `entryDropdown.value` after your `#` string.
```js
assert.match(addEntry.toString(), /targetId\s*=\s*('|")#\1\s*\+\s*entryDropdown\.value/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,203 @@
---
id: 63c1e0af28078f2dfad9eb3e
title: Step 38
challengeType: 0
dashedName: step-38
---
# --description--
Now you need to target the `.input-container` element within the element that has your `targetId`. Declare a new `targetInputContainer` variable, and assign it the value of `document.querySelector()`. Use concatenation to separate `targetId` and `'.input-container'` with a space, and pass that string to `querySelector()`.
# --hints--
Your `addEntry` function should have a `targetInputContainer` variable.
```js
assert.match(addEntry.toString(), /targetInputContainer\s*=/);
```
Your `targetInputContainer` variable should be set to `document.querySelector()`.
```js
assert.match(addEntry.toString(), /targetInputContainer\s*=\s*document\.querySelector\(/);
```
You should pass `targetId` to your `querySelector()` method.
```js
assert.match(addEntry.toString(), /targetInputContainer\s*=\s*document\.querySelector\(\s*targetId\s*/);
```
You should concatenate `' .input-container'` to `targetId`. Remember to include the space at the beginning of `.input-container`.
```js
assert.match(addEntry.toString(), /targetInputContainer\s*=\s*document\.querySelector\(\s*targetId\s*\s*\+\s*('|")\s\.input-container\1\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetId = '#' + entryDropdown.value;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,203 @@
---
id: 63c1e1965a898d302e0af4e3
title: Step 39
challengeType: 0
dashedName: step-39
---
# --description--
JavaScript has a feature called <dfn>template literals</dfn>, which allow you to interpolate variables directly within a string. Template literals are denoted with backticks ``` `` ```, as opposed to single or double quotes. Variables can be passed in to a template literal by surrounding the variable with `${}` the value of the variable will be inserted into the string.
For example:
```js
const name = "Naomi";
const templateLiteral = `Hello, my name is ${name}~!`;
console.log(templateLiteral);
```
The console will show the string "Hello, my name is Naomi~!".
Replace your concatenated string in the `querySelector` with a template literal be sure to keep the space between your `targetId` variable and `.input-container`.
# --hints--
You should use a template literal in your `querySelector` method.
```js
assert.match(code, /const\s+targetInputContainer\s*=\s*document\.querySelector\(`.*`\)/);
```
Your template literal should have the value `{targetId} .input-container`.
```js
assert.match(code, /const\s+targetInputContainer\s*=\s*document\.querySelector\(`\$\{targetId\}\s\.input-container`\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetId = '#' + entryDropdown.value;
const targetInputContainer = document.querySelector(targetId + ' .input-container');
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,197 @@
---
id: 63c1e5b4b3c8a031def3bd65
title: Step 40
challengeType: 0
dashedName: step-40
---
# --description--
Thanks to template literals, you actually don't need the `targetId` variable at all. Remove that variable, and update your template literal to replace `targetId` with `entryDropdown.value` remember to add `#` before that, in the string.
# --hints--
You should remove the `targetId` variable.
```js
assert.notMatch(addEntry.toString(), /targetId\s*=/);
```
You should replace the `targetId` reference in your template literal with `entryDropdown.value`.
```js
assert.match(code, /const\s+targetInputContainer\s*=\s*document\.querySelector\(`#?\$\{entryDropdown\.value\}\s\.input-container`\s*\)/);
```
You should add `#` at the beginning of your template literal.
```js
assert.match(code, /const\s+targetInputContainer\s*=\s*document\.querySelector\(`#\$\{entryDropdown\.value\}\s\.input-container`\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetId = '#' + entryDropdown.value;
const targetInputContainer = document.querySelector(`${targetId} .input-container`);
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,197 @@
---
id: 63c1e704ee12703347625900
title: Step 41
challengeType: 0
dashedName: step-41
---
# --description--
You will want to number the entries a user adds. Declare an `entryNumber` variable and give it the value of `targetInputContainer.querySelectorAll()`. You do not need to pass an argument to the query selector yet.
# --hints--
You should have an `entryNumber` variable.
```js
assert.match(addEntry.toString(), /entryNumber\s*=/);
```
Your `entryNumber` variable should have the value of `targetInputContainer.querySelectorAll()`.
```js
assert.match(addEntry.toString(), /entryNumber\s*=\s*targetInputContainer\.querySelectorAll\(/);
```
You should not pass an argument to `querySelectorAll()`.
```js
assert.match(addEntry.toString(), /entryNumber\s*=\s*targetInputContainer\.querySelectorAll\(\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,201 @@
---
id: 63c2164c0df38a382062c4af
title: Step 42
challengeType: 0
dashedName: step-42
---
# --description--
Each entry will have a text input for the entry's name, and a number input for the calories. To get a count of the number of entries, you can query by text inputs. Note that you cannot query by number inputs, as you have an extra number input for the user's calorie budget.
Pass the string `input[type="text"]` to the `querySelectorAll()` method. Remember that you will need to use single quotes for your string, so that you can use double quotes within.
This will return a `NodeList` of all the text inputs in the form. You can then access the `length` property of the `NodeList` to get the number of entries. Do this on the same line.
# --hints--
You should pass the string `input[type="text"]` to the `querySelectorAll()` method.
```js
assert.match(addEntry.toString(), /entryNumber\s*=\s*targetInputContainer\.querySelectorAll\(\s*'input\[type="text"]'\)/)
```
You should access the `length` property of your `querySelectorAll()`.
```js
assert.match(addEntry.toString(), /\.querySelectorAll\(\s*'input\[type="text"]'\)\.length/)
```
Your `entryNumber` variable should be the `length` of the `querySelectorAll`.
```js
assert.match(addEntry.toString(), /entryNumber\s*=\s*targetInputContainer\.querySelectorAll\(\s*'input\[type="text"]'\)\.length/)
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll();
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,192 @@
---
id: 63c216da562fbb3957b9cb2c
title: Step 43
challengeType: 0
dashedName: step-43
---
# --description--
Now you need to build your dynamic HTML string to add to the webpage. Declare a new `HTMLString` variable, and assign it an empty template literal string.
# --hints--
Your `addEntry` function should have an `HTMLString` variable.
```js
assert.match(addEntry.toString(), /HTMLString\s*=/)
```
Your `HTMLString` should be an empty template literal.
```js
assert.match(code, /HTMLString\s*=\s*``/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,198 @@
---
id: 63c2171c1e5b6e3aa51768d0
title: Step 44
challengeType: 0
dashedName: step-44
---
# --description--
Start your `HTMLString` with a new line, then create a `label` element. Give that element the text `Entry # Name`, using your template literal syntax to replace `#` with the value of `entryNumber`.
# --hints--
Your `HTMLString` variable should start with a new line.
```js
assert.match(code, /HTMLString\s*=\s*`\n/);
```
You should add a `label` element on the new line.
```js
assert.match(code, /HTMLString\s*=\s*`\n\s*<label>.*<\/label>/);
```
Your `label` element should have the text `Entry ${entryNumber} Name`.
```js
assert.match(code, /HTMLString\s*=\s*`\n\s*<label>Entry\s\$\{entryNumber\}\sName<\/label>/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = ``;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,193 @@
---
id: 63c21774193de43bbc6a769f
title: Step 45
challengeType: 0
dashedName: step-45
---
# --description--
Give your `label` element a `for` attribute with the value `X-#-name`, where `X` is the `value` of the `entryDropdown` element and `#` is the value of `entryNumber`. Remember that HTML attributes should be wrapped in double quotes.
# --hints--
Your `label` element should have a `for` attribute set to `${entryDropdown.value}-${entryNumber}-name`.
```js
assert.match(code, /HTMLString\s*=\s*`\n\s*<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-name"\s*>/)
```
Your `label` element should have the same text as before.
```js
assert.match(code, /HTMLString\s*=\s*`\n\s*<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-name"\s*>Entry\s\$\{entryNumber\}\sName<\/label>/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = `
<label>Entry ${entryNumber} Name</label>`;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,217 @@
---
id: 63c217ccd939053ce4fa16d6
title: Step 46
challengeType: 0
dashedName: step-46
---
# --description--
After your `label` element, and on a new line in your template string, create an `input` element. Give it a `type` attribute set to `text`, a `placeholder` attribute set to `Name`, and an `id` attribute that matches the `for` attribute of your `label` element.
# --hints--
You should not modify your `label` element.
```js
assert.match(code, /HTMLString\s*=\s*`\n\s*<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-name"\s*>Entry\s\$\{entryNumber\}\sName<\/label>/);
```
You should add an `input` element on a new line.
```js
assert.match(code, /HTMLString\s*=\s*`\n\s*<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-name"\s*>Entry\s\$\{entryNumber\}\sName<\/label>\n\s*<input/);
```
Your `input` element should have a `type` attribute set to `text`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputAttributes = HTMLstring.match(/<input\s+.*?>/)[0];
assert.include(inputAttributes, 'type="text"');
```
Your `input` element should have a `placeholder` attribute set to `Name`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputAttributes = HTMLstring.match(/<input\s+.*?>/)[0];
assert.include(inputAttributes, 'placeholder="Name"');
```
Your `input` element should have an `id` attribute set to `${entryDropdown.value}-${entryNumber}-name`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputAttributes = HTMLstring.match(/<input\s+.*?>/)[0];
assert.include(inputAttributes, 'id="${entryDropdown.value}-${entryNumber}-name"');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>`;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,228 @@
---
id: 63c21839f56eaf3ef4e027c4
title: Step 47
challengeType: 0
dashedName: step-47
---
# --description--
Create another `label` element (on a new line) at the end of your `HTMLString`. This `label` should have the text `Entry # Calories`, using your template literal syntax to replace `#` with the value of `entryNumber`, and the `for` attribute set to `X-#-calories`, where `X` is the `value` of `entryDropdown` and `#` is the value of `entryNumber`.
# --hints--
You should have two `label` elements in your `HTMLString`.
```js
const HTMLstring = code.split("HTMLString =")[1];
assert.equal(HTMLstring.match(/<label/g).length, 2);
```
Your new `label` element should be on a new line.
```js
const HTMLstring = code.split("HTMLString =")[1];
assert.equal(HTMLstring.match(/\n\s*<label/g).length, 2);
```
Your new `label` element should come after your `input` element.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputIndex = HTMLstring.indexOf("<input");
const labelIndex = HTMLstring.lastIndexOf("<label");
assert.isBelow(inputIndex, labelIndex);
```
Your new `label` element should have a `for` attribute set to `${entryDropdown.value}-${entryNumber}-calories`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const label = HTMLstring.match(/<label.*>.*<\/label>/g)[1];
assert.match(label, /<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-calories"\s*>/)
```
Your new `label` element should have the text `Entry ${entryNumber} Calories`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const label = HTMLstring.match(/<label.*>.*<\/label>/g)[1];
assert.match(label, /<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-calories"\s*>Entry\s\$\{entryNumber\}\sCalories<\/label>/);
```
You should not modify your existing elements.
```js
const HTMLstring = code.split("HTMLString =")[1];
assert.match(HTMLstring, /`\n\s*<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-name"\s*>Entry\s\$\{entryNumber\}\sName<\/label>\n\s*<input\stype="text"\sid="\$\{entryDropdown.value\}-\$\{entryNumber\}-name"\splaceholder="Name"\s\/>\n\s*<label\s+for="\$\{entryDropdown.value\}-\$\{entryNumber\}-calories"\s*>Entry\s\$\{entryNumber\}\sCalories<\/label>/)
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />`;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,238 @@
---
id: 63c2187f55eb0f400269568f
title: Step 48
challengeType: 0
dashedName: step-48
---
# --description--
Finally, on a new line after your second `label`, create another `input` element. Give this one a `type` attribute set to `number`, a `min` attribute set to `0` (to ensure negative calories cannot be added), a `placeholder` attribute set to `Calories`, and an `id` attribute that matches the `for` attribute of your second `label` element.
# --hints--
You should have two `input` elements in your `HTMLString`.
```js
const HTMLstring = code.split("HTMLString =")[1];
assert.equal(HTMLstring.match(/<input/g).length, 2);
```
Your new `input` element should be on a new line.
```js
const HTMLstring = code.split("HTMLString =")[1];
assert.equal(HTMLstring.match(/\n\s*<input/g).length, 2);
```
Your new `input` element should come after your second `label` element.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputIndex = HTMLstring.lastIndexOf("<input");
const labelIndex = HTMLstring.lastIndexOf("<label");
assert.isAbove(inputIndex, labelIndex);
```
Your new `input` element should have a `type` attribute set to `number`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputAttributes = HTMLstring.match(/<input\s+[^>]*>/g)[1];
assert.include(inputAttributes, 'type="number"');
```
Your `input` element should have a `placeholder` attribute set to `Calories`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputAttributes = HTMLstring.match(/<input\s+[^>]*>/g)[1];
assert.include(inputAttributes, 'placeholder="Calories"');
```
Your `input` element should have an `id` attribute set to `${entryDropdown.value}-${entryNumber}-name`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputAttributes = HTMLstring.match(/<input\s+[^>]*>/g)[1];
assert.include(inputAttributes, 'id="${entryDropdown.value}-${entryNumber}-calories"');
```
Your `input` element should have a `min` attribute set to `0`.
```js
const HTMLstring = code.split("HTMLString =")[1];
const inputAttributes = HTMLstring.match(/<input\s+[^>]*>/g)[1];
assert.include(inputAttributes, 'min="0"');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>`;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,208 @@
---
id: 63c218c028c56a411b2a379a
title: Step 49
challengeType: 0
dashedName: step-49
---
# --description--
Finally, add your new `HTMLString` to the `targetInputContainer` by using the `innerHTML` property. Remember to use the `+=` operator to add to the existing HTML instead of replacing it.
# --hints--
Your `addEntry` function should access the `innerHTML` property of `targetInputContainer`.
```js
assert.match(addEntry.toString(), /targetInputContainer\.innerHTML/);
```
You should use the `+=` operator on `targetInputContainer.innerHTML`.
```js
assert.match(addEntry.toString(), /targetInputContainer\.innerHTML\s*\+=/);
```
You should add your `HTMLString` to the `innerHTML` of the `targetInputContainer` element.
```js
assert.match(addEntry.toString(), /targetInputContainer\.innerHTML\s*\+=\s*HTMLString/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,200 @@
---
id: 63c2194dce265f429300c8b1
title: Step 51
challengeType: 0
dashedName: step-51
---
# --description--
Try adding a couple of entries to the `Breakfast` category, and you may notice some bugs! The first thing we need to fix is the entry counts the first entry should have a count of `1`, not `0`.
This bug occurs because you are querying for `input[type="text"]` elements *before* adding the new entry to the page. To fix this, update your `entryNumber` variable to be the value of the `length` of the query plus `1`. Add this on your declaration line, not in your template strings.
# --hints--
You should add `1` to the `.length` of your `querySelectorAll()` method.
```js
assert.match(addEntry.toString(), /entryNumber\s*=\s*targetInputContainer\.querySelectorAll\(\s*'input\[type="text"]'\)\.length\s*\+\s*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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.innerHTML += HTMLString;
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,212 @@
---
id: 63c21c17fa8fd6447ff0389d
title: Step 52
challengeType: 0
dashedName: step-52
---
# --description--
Your other bug occurs if you add a `Breakfast` entry, fill it in, then add a second `Breakfast` entry. You'll see that the values you added disappeared.
This is because you are updating `innerHTML` directly, which does not preserve your input content. Change your `innerHTML` assignment to use the `insertAdjacentHTML()` method of `targetInputContainer` instead. Do not pass any arguments yet.
# --hints--
You should not access the `innerHTML` property of `targetInputContainer`.
```js
assert.notMatch(addEntry.toString(), /targetInputContainer\.innerHTML/);
```
You should call the `insertAdjacentHTML()` method of `targetInputContainer`.
```js
assert.match(addEntry.toString(), /targetInputContainer\.insertAdjacentHTML\(/);
```
You should not pass any arguments to `insertAdjacentHTML()`.
```js
assert.match(addEntry.toString(), /targetInputContainer\.insertAdjacentHTML\(\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.innerHTML += HTMLString;
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,208 @@
---
id: 63c21cd2c34541469f5700a9
title: Step 53
challengeType: 0
dashedName: step-53
---
# --description--
The `insertAdjacentHtml` method takes two arguments. The first argument is a string that specifies the position of the inserted element. The second argument is a string containing the HTML to be inserted.
For the first argument, pass the string `beforeend` to insert the new element as the last child of `targetInputContainer`.
For the second argument, pass your `HTMLString` variable.
# --hints--
You should pass the string `beforeend` as the first argument to `insertAdjacentHTML`.
```js
assert.match(addEntry.toString(), /insertAdjacentHTML\(\s*('|")beforeend\1/);
```
You should pass your `HTMLString` variable as the second argument to `insertAdjacentHTML`.
```js
assert.match(addEntry.toString(), /insertAdjacentHTML\(\s*('|")beforeend\1\s*,\s*HTMLString\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
--fcc-editable-region--
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML();
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,216 @@
---
id: 63c21d4f48267a47c2946788
title: Step 54
challengeType: 0
dashedName: step-54
---
# --description--
Great! Now you can add entries without losing your previous inputs.
Your next step is to write a function that will get the calorie counts from the user's entries.
Declare a `getCaloriesFromInputs` function, and give it a parameter called `list`.
# --hints--
You should declare a `getCaloriesFromInputs` variable.
```js
assert.isDefined(getCaloriesFromInputs);
```
Your `getCaloriesFromInputs` variable should be a function.
```js
assert.isFunction(getCaloriesFromInputs);
```
Your `getCaloriesFromInputs` function should take a parameter called `list`.
```js
assert.match(getCaloriesFromInputs?.toString(), /\(\s*list\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,212 @@
---
id: 63c21dea919c8e4adb0df8e8
title: Step 50
challengeType: 0
dashedName: step-50
---
# --description--
In the Role Playing Game project, you learned how to set a button's behavior by editing its `onclick` property. You can also edit an element's behavior by adding an event listener.
Call the `.addEventListener()` method of the `addEntryButton`. This takes two arguments. The first is the event to listen to you should pass the string `click`. The second is the callback function, or the function that runs when the event is triggered. Pass the `addEntry` function as the second argument. Note that you should not *call* `addEntry`, but pass the variable (or <dfn>function reference</dfn>) directly.
# --hints--
You should call the `.addEventListener()` method of the `addEntryButton`.
```js
assert.match(code, /addEntryButton\.addEventListener\(/);
```
You should pass `click` as the first argument to the `.addEventListener()` method.
```js
assert.match(code, /addEntryButton\.addEventListener\(\s*('|")click\1\s*/);
```
You should pass `addEntry` as the second argument to the `.addEventListener()` method.
```js
assert.match(code, /addEntryButton\.addEventListener\(\s*('|")click\1\s*,\s*addEntry\s*/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.innerHTML += HTMLString;
}
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,216 @@
---
id: 63c8ab51214c8c1f1b9a49f7
title: Step 55
challengeType: 0
dashedName: step-55
---
# --description--
In your new function, declare a `calories` variable and assign it the value `0`. Use `let` to declare it, since you will be reassigning it later.
# --hints--
You should declare a `calories` variable.
```js
assert.match(getCaloriesFromInputs.toString(), /calories\s*=/);
```
Your `calories` variable should be assigned the value `0`.
```js
assert.match(getCaloriesFromInputs.toString(), /calories\s*=\s*0/);
```
You should declare your `calories` variable with `let`.
```js
// babel transforms the code, so we gotta do a hack here
const getCaloriesFromInputsString = code.split('function getCaloriesFromInputs')[1];
assert.match(getCaloriesFromInputsString, /let\s+calories\s*=\s*0/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,224 @@
---
id: 63c8ad0cd8f1e5201c4ef2e4
title: Step 56
challengeType: 0
dashedName: step-56
---
# --description--
The `list` parameter is going to be the result of a query selector, which will return a `NodeList`. A `NodeList` is an array-like which contains the elements that match the query selector.
You'll need to loop through these elements, so start by creating a `for` loop. Your iterator `i` should start at `0`, continue while it is less than the length of the list, and increment by `1` each iteration.
# --hints--
Your `getCaloriesFromInputs` function should have a `for` loop.
```js
assert.match(getCaloriesFromInputs.toString(), /for\s*\(/g);
```
Your `for` loop should initialize a variable called `i` to `0`.
```js
assert.match(getCaloriesFromInputs.toString(), /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;/g);
```
Your `for` loop should have a condition that checks if `i` is less than the length of `list`.
```js
assert.match(getCaloriesFromInputs.toString(), /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*list\.length\s*;/g);
```
Your `for` loop should increment `i` by `1` each time it runs. Use the increment operator for this.
```js
assert.match(getCaloriesFromInputs.toString(), /for\s*\(\s*(let|var)\s+i\s*=\s*0\s*;\s*i\s*<\s*list\.length\s*;\s*i\s*\+\+\s*\)/g);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,234 @@
---
id: 63c8b0187cceff21c8389543
title: Step 57
challengeType: 0
dashedName: step-57
---
# --description--
The `NodeList` values you will pass to `list` will consist of `input` elements. So you will want to look at the `value` attribute of each element.
Assign the `value` of the element in `list` at index `i` to a variable called `currVal`.
# --hints--
You should have a `currVal` variable.
```js
assert.match(getCaloriesFromInputs.toString(), /currVal\s*=/);
```
You should access the element in `list` at index `i` using bracket notation.
```js
assert.match(getCaloriesFromInputs.toString(), /list\[i\]/);
```
You should access the `value` attribute of the element in `list` at index `i`.
```js
assert.match(getCaloriesFromInputs.toString(), /list\[i\]\.value/);
```
You should assign the `value` of the element in `list` at index `i` to a variable called `currVal`.
```js
assert.match(getCaloriesFromInputs.toString(), /currVal\s*=\s*list\[i\]\.value/);
```
Your `currVal` assignment should be in your `for` loop.
```js
// another hack, because the loop protection injects stuff
const getCaloriesString = code.split("function getCaloriesFromInputs")[1];
assert.match(getCaloriesString, /for\s*\(\s*let\s+i\s*=\s*0\s*;\s*i\s*<\s*list\.length\s*;\s*i\s*\+\+\s*\)\s*\{\s*const|let\s*currVal\s*=\s*list\[i\]\.value/g);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,221 @@
---
id: 63c8be904ffff922f3c6f8d0
title: Step 58
challengeType: 0
dashedName: step-58
---
# --description--
Remember that you wrote a function earlier to clean the user's input? You'll need to use that function here.
Update your `currVal` declaration to be the result of calling `cleanInputString` with `list[i].value`.
# --hints--
Your `getCaloriesFromInputs` function should call your `cleanInputString` function.
```js
assert.match(getCaloriesFromInputs.toString(), /cleanInputString\(/);
```
You should pass `list[i].value` as the parameter for `cleanInputString`.
```js
assert.match(getCaloriesFromInputs.toString(), /cleanInputString\(\s*list\[i\]\.value\)/);
```
You should assign the result of your `cleanInputString` call to your `currVal` variable.
```js
assert.match(getCaloriesFromInputs.toString(), /currVal\s*=\s*cleanInputString\(\s*list\[i\]\.value\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = list[i].value;
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,219 @@
---
id: 63c8c00bfb671b23f9de4159
title: Step 59
challengeType: 0
dashedName: step-59
---
# --description--
You also need to confirm the input is valid. Declare an `invalidInputMatch` variable, and assign it the result of calling your `isInvalidInput` function with `currVal` as the argument.
# --hints--
You should declare an `invalidInputMatch` variable.
```js
assert.match(getCaloriesFromInputs.toString(), /invalidInputMatch\s*=/);
```
You should assign the result of calling `isInvalidInput` to your `invalidInputMatch` variable.
```js
assert.match(getCaloriesFromInputs.toString(), /invalidInputMatch\s*=\s*isInvalidInput\(/);
```
You should pass `currVal` as the parameter to `isInvalidInput`.
```js
assert.match(getCaloriesFromInputs.toString(), /invalidInputMatch\s*=\s*isInvalidInput\(\s*currVal\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,233 @@
---
id: 63c8c15fd337ad24b9b68049
title: Step 60
challengeType: 0
dashedName: step-60
---
# --description--
Remember that your `isInvalidInput` function returns `String.match`, which is an array of matches or `null` if no matches are found.
In JavaScript, values can either be <dfn>truthy</dfn> or <dfn>falsy</dfn>. A value is truthy if it evaluates to `true` when converted to a Boolean. A value is falsy if it evaluates to `false` when converted to a Boolean. `null` is an example of a falsy value.
You need to check if `invalidInputMatch` is truthy you can do this by passing the variable directly to your `if` condition (without a comparison operator). Here's an example of checking the truthiness of `helloWorld`.
```js
if (helloWorld) {
}
```
Add an `if` statement that checks if `invalidInputMatch` is truthy.
# --hints--
You should add an `if` statement to your `getCaloriesFromInputs` function.
```js
assert.match(getCaloriesFromInputs.toString(), /if\s*\(/);
```
You should check the truthiness of `invalidInputMatch` in your `if` condition.
```js
assert.match(getCaloriesFromInputs.toString(), /if\s*\(\s*invalidInputMatch\s*\)/);
```
Your `if` statement should be inside your `for` loop.
```js
assert.isBelow(getCaloriesFromInputs.toString().indexOf("for"), getCaloriesFromInputs.toString().indexOf("if"));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,226 @@
---
id: 63c9bc53735149084390e5d0
title: Step 61
challengeType: 0
dashedName: step-61
---
# --description--
Browsers have a built in `alert()` function, which you can use to display a pop-up message to the user. The message to display is passed as the argument to the `alert()` function.
Using a template literal, in your `if` block, call the `alert()` function to tell the user `Invalid Input: `, followed by the first value in the `invalidInputMatch` array.
# --hints--
You should call the `alert()` function in your `if` block.
```js
assert.match(getCaloriesFromInputs.toString(), /if\s*\(\s*invalidInputMatch\s*\)\s*\{\s*alert\(/);
```
You should use a template literal to pass the `Invalid Input: ` message to the `alert()` function.
```js
// because it transforms template literals...
assert.match(code.split("function getCaloriesFromInputs")[1], /alert\(`Invalid Input: /);
```
You should use template literal syntax to display the first value in the `invalidInputMatch` array after the `Invalid Input: ` text.
```js
assert.match(code.split("function getCaloriesFromInputs")[1], /alert\(`Invalid Input: \${invalidInputMatch\[0\]}`\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
}
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,218 @@
---
id: 63c9bcc26219e7090da0f549
title: Step 62
challengeType: 0
dashedName: step-62
---
# --description--
Still within your `if` block, set `isError` to `true` and return `null`.
# --hints--
After your `alert`, you should set `isError` to `true`.
```js
assert.match(code.split("function getCaloriesFromInputs")[1], /alert\(`Invalid Input: \${invalidInputMatch\[0\]}`\s*\);\s*isError\s*=\s*true/);
```
After you modify `isError`, you should `return` the value `null`.
```js
assert.match(code.split("function getCaloriesFromInputs")[1], /alert\(`Invalid Input: \${invalidInputMatch\[0\]}`\s*\);\s*isError\s*=\s*true;?\s*return\s+null;?\s*\}/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
}
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,234 @@
---
id: 63c9bce376ca4f09c15a3768
title: Step 63
challengeType: 0
dashedName: step-63
---
# --description--
Remember that `return` ends the execution of a function. After your `if` block, you need to handle the logic for when the input is valid. Because your `if` statement returns a value, you do not need an `else` statement.
Use the addition assignment operator to add `currVal` to your `calories` total. You'll need to use the `Number` constructor to convert `currVal` to a number.
# --hints--
You should not add an `else` statement.
```js
assert.notMatch(getCaloriesFromInputs.toString(), /else/);
```
After your `if` statement, you should use the addition assignment operator on `calories`.
```js
assert.match(getCaloriesFromInputs.toString(), /if.*}\s*calories\s*\+=/s);
```
You should pass `currVal` to the `Number()` constructor.
```js
assert.match(getCaloriesFromInputs.toString(), /Number\(\s*currVal\s*\)/);
```
You should add the value of `Number(currVal)` to `calories`.
```js
assert.match(getCaloriesFromInputs.toString(), /calories\s*\+=\s*Number\(\s*currVal\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,221 @@
---
id: 63c9bdd916e0c10af01ed8d7
title: Step 64
challengeType: 0
dashedName: step-64
---
# --description--
After your `for` loop has completed, return the `calories` value.
# --hints--
You should `return` the `calories` value.
```js
assert.match(getCaloriesFromInputs.toString(), /return\s+calories/);
```
Your new `return` statement should come after your `for` loop.
```js
assert.match(getCaloriesFromInputs.toString(), /calories\s*\+=\sNumber\(currVal\);\n\s*}\n\s*return\s+calories/)
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,229 @@
---
id: 63c9be334f4a050c0b94bc93
title: Step 65
challengeType: 0
dashedName: step-65
---
# --description--
Now it's time to start putting it all together. Declare an empty `calculateCalories` function, which takes a parameter named `e`. This function will be another event listener, so the first argument passed will be the browser event `e` is a common name for this parameter.
# --hints--
You should declare a `calculateCalories` variable.
```js
assert.isDefined(calculateCalories);
```
Your `calculateCalories` variable should be a function.
```js
assert.isFunction(calculateCalories);
```
Your `calculateCalories` function should take an `e` argument.
```js
assert.match(calculateCalories?.toString(), /\(e\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,227 @@
---
id: 63c9bef7fec05c0d38853828
title: Step 66
challengeType: 0
dashedName: step-66
---
# --description--
You will be attaching this function to the `submit` event of the form. The `submit` event is triggered when the form is submitted. The default action of the `submit` event is to reload the page. You need to prevent this default action using the `preventDefault()` method of your `e` parameter.
Add a line to your `calculateCalories` function that calls the `preventDefault()` method on the `e` parameter. Then, reset your global error flag to `false`.
# --hints--
Your `calculateCalories` function should call `e.preventDefault()`.
```js
assert.match(calculateCalories.toString(), /e\.preventDefault\(\)/);
```
Your `calculateCalories` function should reset the global error flag to `false`.
```js
assert.match(calculateCalories.toString(), /isError\s*=\s*false/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,236 @@
---
id: 63c9bf80558d780e848b2987
title: Step 67
challengeType: 0
dashedName: step-67
---
# --description--
Your function needs to get the values from the entries the user has added.
Declare a `breakfastNumberInputs` variable, and give it the value of calling `document.querySelectorAll()` with the selector `#breakfast input[type=number]`. This will return any `number` inputs that are in the `#breakfast` element.
# --hints--
You should declare a `breakfastNumberInputs` variable.
```js
assert.match(calculateCalories.toString(), /breakfastNumberInputs\s*=/);
```
You should call `document.querySelectorAll()` with `#breakfast input[type=number]`.
```js
assert.match(calculateCalories.toString(), /document\.querySelectorAll\(('|")#breakfast input\[type=number\]\1\)/);
```
You should assign the result of your `odocument.querySelectorAll()` call to `breakfastNumberInputs`.
```js
assert.match(calculateCalories.toString(), /breakfastNumberInputs\s*=\s*document\.querySelectorAll\(('|")#breakfast input\[type=number\]\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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,235 @@
---
id: 63c9c09a7daa4f0ff92c4023
title: Step 68
challengeType: 0
dashedName: step-68
---
# --description--
Using that same syntax, query your `number` inputs in the `#lunch` element and assign them to `lunchNumberInputs`.
# --hints--
You should declare a `lunchNumberInputs` variable.
```js
assert.match(calculateCalories.toString(), /lunchNumberInputs\s*=/);
```
You should call `document.querySelectorAll()` with `#lunch input[type=number]`.
```js
assert.match(calculateCalories.toString(), /document\.querySelectorAll\(('|")#lunch input\[type=number\]\1\)/);
```
You should assign the result of your `document.querySelectorAll()` call to `lunchNumberInputs`.
```js
assert.match(calculateCalories.toString(), /lunchNumberInputs\s*=\s*document\.querySelectorAll\(('|")#lunch input\[type=number\]\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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,272 @@
---
id: 63c9c0d0857f0a10a57af936
title: Step 69
challengeType: 0
dashedName: step-69
---
# --description--
Following the same pattern, query for your `number` inputs in the `#dinner`, `#snacks`, and `#exercise` elements. Assign them to variables following the naming scheme of the previous two.
# --hints--
You should declare a `dinnerNumberInputs` variable.
```js
assert.match(calculateCalories.toString(), /dinnerNumberInputs\s*=/);
```
You should call `document.querySelectorAll()` with `#dinner input[type=number]`.
```js
assert.match(calculateCalories.toString(), /document\.querySelectorAll\(('|")#dinner input\[type=number\]\1\)/);
```
You should assign the result of your `document.querySelectorAll()` call to `dinnerNumberInputs`.
```js
assert.match(calculateCalories.toString(), /dinnerNumberInputs\s*=\s*document\.querySelectorAll\(('|")#dinner input\[type=number\]\1\)/);
```
You should declare a `snacksNumberInputs` variable.
```js
assert.match(calculateCalories.toString(), /snacksNumberInputs\s*=/);
```
You should call `document.querySelectorAll()` with `#snacks input[type=number]`.
```js
assert.match(calculateCalories.toString(), /document\.querySelectorAll\(('|")#snacks input\[type=number\]\1\)/);
```
You should assign the result of your `document.querySelectorAll()` call to `snacksNumberInputs`.
```js
assert.match(calculateCalories.toString(), /snacksNumberInputs\s*=\s*document\.querySelectorAll\(('|")#snacks input\[type=number\]\1\)/);
```
You should declare a `exerciseNumberInputs` variable.
```js
assert.match(calculateCalories.toString(), /exerciseNumberInputs\s*=/);
```
You should call `document.querySelectorAll()` with `#exercise input[type=number]`.
```js
assert.match(calculateCalories.toString(), /document\.querySelectorAll\(('|")#exercise input\[type=number\]\1\)/);
```
You should assign the result of your `document.querySelectorAll()` call to `exerciseNumberInputs`.
```js
assert.match(calculateCalories.toString(), /exerciseNumberInputs\s*=\s*document\.querySelectorAll\(('|")#exercise input\[type=number\]\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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,242 @@
---
id: 63c9c11a0a090311dff55564
title: Step 70
challengeType: 0
dashedName: step-70
---
# --description--
Now that you have your lists of elements, you can pass them to your `getCaloriesFromInputs` function to extract the calorie total.
Declare a `breakfastCalories` variable, and assign it the result of calling `getCaloriesFromInputs` with `breakfastNumberInputs` as the argument.
# --hints--
Your `calculateCalories` function should have a `breakfastCalories` variable.
```js
assert.match(calculateCalories.toString(), /breakfastCalories\s*=/);
```
You should call `getCaloriesFromInputs` with `breakfastNumberInputs` as the argument.
```js
assert.match(calculateCalories.toString(), /getCaloriesFromInputs\s*\(\s*breakfastNumberInputs\s*\)/);
```
You should assign the result of `getCaloriesFromInputs` to `breakfastCalories`.
```js
assert.match(calculateCalories.toString(), /breakfastCalories\s*=\s*getCaloriesFromInputs\s*\(\s*breakfastNumberInputs\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,241 @@
---
id: 63c9c16dd75dd212dc12363c
title: Step 71
challengeType: 0
dashedName: step-71
---
# --description--
Now declare a `lunchCalories` variable, and give it the value of calling `getCaloriesFromInputs` with your `lunchNumberInputs`.
# --hints--
Your `calculateCalories` function should have a `lunchCalories` variable.
```js
assert.match(calculateCalories.toString(), /lunchCalories\s*=/);
```
You should call `getCaloriesFromInputs` with `lunchNumberInputs` as the argument.
```js
assert.match(calculateCalories.toString(), /getCaloriesFromInputs\s*\(\s*lunchNumberInputs\s*\)/);
```
You should assign the result of `getCaloriesFromInputs` to `lunchCalories`.
```js
assert.match(calculateCalories.toString(), /lunchCalories\s*=\s*getCaloriesFromInputs\s*\(\s*lunchNumberInputs\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,278 @@
---
id: 63c9c1ef134f3513e751c975
title: Step 72
challengeType: 0
dashedName: step-72
---
# --description--
Following this same pattern, declare variables for the `number` inputs in the `#dinner`, `#snacks`, and `#exercise` elements. Assign them the appropriate `getCaloriesFromInputs` calls.
# --hints--
Your `calculateCalories` function should have a `dinnerCalories` variable.
```js
assert.match(calculateCalories.toString(), /dinnerCalories\s*=/);
```
You should call `getCaloriesFromInputs` with `dinnerNumberInputs` as the argument.
```js
assert.match(calculateCalories.toString(), /getCaloriesFromInputs\s*\(\s*dinnerNumberInputs\s*\)/);
```
You should assign the result of `getCaloriesFromInputs` to `dinnerCalories`.
```js
assert.match(calculateCalories.toString(), /dinnerCalories\s*=\s*getCaloriesFromInputs\s*\(\s*dinnerNumberInputs\s*\)/);
```
Your `calculateCalories` function should have a `snacksCalories` variable.
```js
assert.match(calculateCalories.toString(), /snacksCalories\s*=/);
```
You should call `getCaloriesFromInputs` with `snacksNumberInputs` as the argument.
```js
assert.match(calculateCalories.toString(), /getCaloriesFromInputs\s*\(\s*snacksNumberInputs\s*\)/);
```
You should assign the result of `getCaloriesFromInputs` to `snacksCalories`.
```js
assert.match(calculateCalories.toString(), /snacksCalories\s*=\s*getCaloriesFromInputs\s*\(\s*snacksNumberInputs\s*\)/);
```
Your `calculateCalories` function should have a `exerciseCalories` variable.
```js
assert.match(calculateCalories.toString(), /exerciseCalories\s*=/);
```
You should call `getCaloriesFromInputs` with `exerciseNumberInputs` as the argument.
```js
assert.match(calculateCalories.toString(), /getCaloriesFromInputs\s*\(\s*exerciseNumberInputs\s*\)/);
```
You should assign the result of `getCaloriesFromInputs` to `exerciseCalories`.
```js
assert.match(calculateCalories.toString(), /exerciseCalories\s*=\s*getCaloriesFromInputs\s*\(\s*exerciseNumberInputs\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,249 @@
---
id: 63c9e3a83bb3e61a80eea564
title: Step 73
challengeType: 0
dashedName: step-73
---
# --description--
You also need to get the value of your `#budget` input. You already queried this at the top of your code, and set it to the `budgetNumberInput` variable. However, you used `getElementById`, which returns an `Element`, not a `NodeList`.
A `NodeList` is an array-like, which means you can iterate through it and it shares some common methods with an array. For your `getCaloriesFromInputs` function, an array will work for the argument just as well as a `NodeList` does.
Declare a `budgetCalories` variable and set it to the result of calling `getCaloriesFromInputs` pass an array containing your `budgetNumberInput` as the argument.
# --hints--
Your `calculateCalories` function should have a `budgetCalories` variable.
```js
assert.match(calculateCalories.toString(), /budgetCalories\s*=/);
```
You should call `getCaloriesFromInputs` with `[budgetNumberInput]` as the argument.
```js
assert.match(calculateCalories.toString(), /getCaloriesFromInputs\s*\(\s*\[\s*budgetNumberInput\s*\]\s*\)/);
```
You should assign the result of `getCaloriesFromInputs` to `budgetCalories`.
```js
assert.match(calculateCalories.toString(), /budgetCalories\s*=\s*getCaloriesFromInputs\s*\(\s*\[\s*budgetNumberInput\s*\]\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,247 @@
---
id: 63c9e45519caf31b987fbb5f
title: Step 74
challengeType: 0
dashedName: step-74
---
# --description--
Your `getCaloriesFromInputs` function will set the global error flag to `true` if an invalid input is detected. Add an `if` statement to your `calculateCalories` function that checks the truthiness of your global error flag, and if it is truthy then use `return` to end the function execution.
# --hints--
Your `calculateCalories` function should have an `if` statement.
```js
assert.match(calculateCalories.toString(), /if\s*\(/);
```
Your `if` statement should check the truthiness of the `isError` variable.
```js
assert.match(calculateCalories.toString(), /if\s*\(\s*isError\s*\)/);
```
Your `if` statement should use `return` to end the function execution.
```js
assert.match(calculateCalories.toString(), /if\s*\(\s*isError\s*\)\s*\{?\s*return;?\s*\}?\s*/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,257 @@
---
id: 63c9e4d2ff41811dd640504f
title: Step 75
challengeType: 0
dashedName: step-75
---
# --description--
It is time to start preparing your calculations. Start by declaring a `consumedCalories` variable, and assign it the sum of `breakfastCalories`, `lunchCalories`, `dinnerCalories`, and `snacksCalories` (note that order matters for the tests). Be sure to do this after your `if` statement.
# --hints--
Your function should have a `consumedCalories` variable.
```js
assert.match(calculateCalories.toString(), /consumedCalories\s*=/);
```
Your `consumedCalories` variable should come after your `if` statement.
```js
assert.isAbove(calculateCalories.toString().indexOf('consumedCalories'), calculateCalories.toString().indexOf('if'));
```
You should calculate the sum of `breakfastCalories`, `lunchCalories`, `dinnerCalories`, and `snacksCalories`, in order.
```js
assert.match(calculateCalories.toString(), /breakfastCalories\s*\+\s*lunchCalories\s*\+\s*dinnerCalories\s*\+\s*snacksCalories/);
```
You should assign the sum of `breakfastCalories`, `lunchCalories`, `dinnerCalories`, and `snacksCalories` to `consumedCalories`.
```js
assert.match(calculateCalories.toString(), /consumedCalories\s*=\s*breakfastCalories\s*\+\s*lunchCalories\s*\+\s*dinnerCalories\s*\+\s*snacksCalories/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,252 @@
---
id: 63c9e51b3a007a1eba1cd0f6
title: Step 76
challengeType: 0
dashedName: step-76
---
# --description--
Now declare a `remainingCalories` variable, and give it the value of subtracting `consumedCalories` from `budgetCalories` and adding `exerciseCalories`.
# --hints--
Your `calculateCalories` function should have a `remainingCalories` variable.
```js
assert.match(calculateCalories.toString(), /remainingCalories\s*=/);
```
You should find the value of `budgetCalories - consumedCalories + exerciseCalories`.
```js
assert.match(calculateCalories.toString(), /budgetCalories\s*-\s*consumedCalories\s*\+\s*exerciseCalories/);
```
You should assign the value of `budgetCalories - consumedCalories + exerciseCalories` to `remainingCalories`.
```js
assert.match(calculateCalories.toString(), /remainingCalories\s*=\s*budgetCalories\s*-\s*consumedCalories\s*\+\s*exerciseCalories/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,267 @@
---
id: 63c9e55b4b06c11fff555c64
title: Step 77
challengeType: 0
dashedName: step-77
---
# --description--
You need to know if the user's calories are a surplus or a deficit. Declare a `surplusOrDeficit` variable.
Use a ternary operator to set `surplusOrDeficit` to the string `Surplus` or `Deficit` depending on whether `remainingCalories` is greater than or equal to `0`. If it is greater than or equal to `0`, then `surplusOrDeficit` should be `Surplus`. Otherwise, it should be `Deficit`.
# --hints--
Your `calculateCalories` function should have a `surplusOrDeficit` variable.
```js
assert.match(calculateCalories.toString(), /surplusOrDeficit\s*=/g);
```
You should have a ternary operator that checks if `remainingCalories` is greater than or equal to `0`.
```js
assert.match(calculateCalories.toString(), /remainingCalories\s*>=\s*0\s*\?/g);
```
Your ternary operator return the string `Surplus` if `remainingCalories` is greater than or equal to `0`.
```js
assert.match(calculateCalories.toString(), /remainingCalories\s*>=\s*0\s*\?\s*('|")Surplus\1\s*:/g);
```
Your ternary operator return the string `Deficit` if `remainingCalories` is not greater than or equal to `0`.
```js
assert.match(calculateCalories.toString(), /remainingCalories\s*>=\s*0\s*\?\s*('|")Surplus\1\s*:\s*('|")Deficit\2/g);
```
You should assign the result of your ternary operator to `surplusOrDeficit`.
```js
assert.match(calculateCalories.toString(), /surplusOrDeficit\s*=\s*remainingCalories\s*>=\s*0\s*\?\s*('|")Surplus\1\s*:\s*('|")Deficit\2/g);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,250 @@
---
id: 63c9e5eea8261d22856ead1c
title: Step 78
challengeType: 0
dashedName: step-78
---
# --description--
You need to construct the HTML string that will be displayed in the `output` element. Start by assigning an empty template literal to the `innerHTML` property of the `output` element.
# --hints--
You should access the `innerHTML` property of the `output` element.
```js
assert.match(calculateCalories.toString(), /output\s*\.\s*innerHTML/);
```
You should assign an empty template literal to the `innerHTML` property of the `output` element.
```js
// again, template literals don't play well with the parser so we have to look at the raw code.
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/;?\s*\}/)[0];
assert.equal(htmlString, '``');
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,266 @@
---
id: 63c9e63bb1e32d23b6adbe44
title: Step 79
challengeType: 0
dashedName: step-79
---
# --description--
Your `output.innerHTML` string will need a `span` element. Create that, and give it a `class` attribute set to the `surplusOrDeficit` variable, but lowercased.
Strings have a `.toLowerCase()` method that can help you with this. Do not give your `span` any text yet.
# --hints--
You should create a `span` element in your template literal.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<span/);
```
Your `span` element should have a `class` attribute.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<span\s+class\s*=/);
```
Your `span` should have the `class` attribute set to `surplusOrDeficit.toLowerCase()`.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<span\s+class\s*=\s*"\$\{surplusOrDeficit\s*\.toLowerCase\(\s*\)\}"\s*>/);
```
Your `span` should not have any text.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<span\s+class\s*=\s*"\$\{surplusOrDeficit\s*\.toLowerCase\(\s*\)\}"\s*><\/span>/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = ``;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,245 @@
---
id: 63c9e6b7c0303524af2d0bc2
title: Step 80
challengeType: 0
dashedName: step-80
---
# --description--
Give your span the text `remainingCalories Calorie surplusOrDeficit`, using interpolation to replace `remainingCalories` and `surplusOrDeficit` with the appropriate variables.
# --hints--
Your `span` should have the text `${remainingCalories} Calorie ${surplusOrDeficit}`.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<span\s+class\s*=\s*"\$\{surplusOrDeficit\s*\.toLowerCase\(\s*\)\}"\s*>\$\{remainingCalories\} Calorie \$\{surplusOrDeficit\}<\/span>/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}"></span>
`;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,254 @@
---
id: 63c9e769df38c92635c158ba
title: Step 81
challengeType: 0
dashedName: step-81
---
# --description--
When the user has a calorie deficit, the `remainingCalories` value will be negative. You don't want to display a negative number in the result string.
`Math.abs()` is a built-in JavaScript method that will return the absolute value of a number. In your `span` text, wrap your `remainingCalories` reference in `Math.abs()` to ensure that the value is positive.
# --hints--
You should wrap the `remainingCalories` variable in `Math.abs()`.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /Math\.abs\(\s*remainingCalories\s*\)/);
```
Your `span` should have the text `${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}`.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<span\s+class\s*=\s*"\$\{surplusOrDeficit\s*\.toLowerCase\(\s*\)\}"\s*>\$\{Math\.abs\(remainingCalories\)\} Calorie \$\{surplusOrDeficit\}<\/span>/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${remainingCalories} Calorie ${surplusOrDeficit}</span>
`;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,262 @@
---
id: 63c9e7d5b21eee2776ecc226
title: Step 82
challengeType: 0
dashedName: step-82
---
# --description--
After your `span` element, add an `hr` element to create a horizontal line.
To keep your code clean and readable, you should add this on a new line in the template literal.
# --hints--
You should add an `hr` element to your `output.innerHTML` string.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<hr\s*\/?>/);
```
Your `hr` element should come after your `span` element.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.isAbove(htmlString.indexOf('<hr'), htmlString.indexOf('<span'));
```
Your `hr` element should be on a new line.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /\n\s*<hr\s*\/?>/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
`;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,270 @@
---
id: 63c9e84c9fe8ca28c4101189
title: Step 83
challengeType: 0
dashedName: step-83
---
# --description--
Now create a `p` element with the text `budgetCalories Calories Budgeted`, using interpolation to replace `budgetCalories` with the appropriate variable.
This should come after your `hr` element.
# --hints--
You should create a `p` element.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<p>/);
```
Your `p` element should come after your `hr` element.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.isAbove(htmlString.indexOf('<p'), htmlString.indexOf('<hr'));
```
Your `p` element should be on a new line.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /\n\s*<p/);
```
Your `p` element should have the text `${budgetCalories} Calories Budgeted`.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /<p>\$\{budgetCalories\}\s*Calories\s*Budgeted<\/p>/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
`;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,269 @@
---
id: 63c9e8fe3a6f022a05a04675
title: Step 84
challengeType: 0
dashedName: step-84
---
# --description--
Using the same interpolation syntax, add a second `p` element with the text `consumedCalories Calories Consumed` and a third with the text `exerciseCalories Calories Burned`. Remember to replace your `consumedCalories` and `exerciseCalories` variables with the appropriate values.
# --hints--
You should add a second `p` element to your template literal.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.isAtLeast(htmlString.match(/<p>/g).length, 2);
```
Your second `p` element should be on a new line.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert.match(htmlString, /\n\s*<p/)
```
Your second `p` element should come after your existing `p` element.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert(htmlString.match(/<p>\$\{budgetCalories\}\s*Calories\s*Budgeted<\/p>\n\s*<p/));
```
Your second `p` element should have the text `${consumedCalories} Calories Consumed`.
```js
const htmlString = code.split(/output\s*\.\s*innerHTML\s*=\s*/)[1].split(/`/)[1];
assert(htmlString.match(/<p>\$\{consumedCalories\}\s*Calories\s*Consumed<\/p>/));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
`;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,264 @@
---
id: 63c9e94e9df7d72aed1c24bd
title: Step 85
challengeType: 0
dashedName: step-85
---
# --description--
Finally, you need to make the `#output` element visible so the user can see your text. Your `output` variable is an Element, which has a `classList` property. This property has a `.remove()` method, which accepts a string representing the class to remove from the element.
Use the `.remove()` method of the `output` variable's `classList` property to remove the `hide` class. Don't forget to place the word `hide` inside quotes.
# --hints--
You should access the `classList` property of the `output` element.
```js
assert.match(calculateCalories.toString(), /output\.classList/);
```
You should call the `.remove()` method of the `classList` property.
```js
assert.match(calculateCalories.toString(), /output\.classList\.remove\(/);
```
You should pass `hide` as the argument to the `.remove()` method.
```js
assert.match(calculateCalories.toString(), /output\.classList\.remove\(\s*('|")hide\1\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
--fcc-editable-region--
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
}
--fcc-editable-region--
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
```

View File

@@ -0,0 +1,265 @@
---
id: 63c9ea23dbadbf2c2764e3f5
title: Step 86
challengeType: 0
dashedName: step-86
---
# --description--
If you click on your `Calculate Remaining Calories` button, you'll see that nothing happens. You still need to mount the event listener.
Add an event listener to your `calorieCounter` element. The event type should be `submit`, and the callback function should be `calculateCalories`.
# --hints--
You should use the `.addEventListener()` method of your `calorieCounter` element.
```js
assert.match(code, /calorieCounter\.addEventListener\(/);
```
You should pass `submit` as the first argument to `.addEventListener()`.
```js
assert.match(code, /calorieCounter\.addEventListener\(\s*('|")submit\1\s*/);
```
You should pass `calculateCalories` as the second argument to `.addEventListener()`.
```js
assert.match(code, /calorieCounter\.addEventListener\(\s*('|")submit\1\s*,\s*calculateCalories\s*/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
addEntryButton.addEventListener("click", addEntry);
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,265 @@
---
id: 63c9ea9b16430f2d54522464
title: Step 87
challengeType: 0
dashedName: step-87
---
# --description--
Your final feature to add is the ability for a user to clear the form. Start by declaring an empty function called `clearForm` it should not take any arguments.
# --hints--
You should declare a `clearForm` variable.
```js
assert.isDefined(clearForm);
```
Your `clearForm` variable should be a function.
```js
assert.isFunction(clearForm);
```
Your `clearForm` function should not take any arguments.
```js
assert.match(clearForm?.toString(), /\(\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
--fcc-editable-region--
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
```

View File

@@ -0,0 +1,267 @@
---
id: 63c9eb09bcfaa72e3da820a1
title: Step 88
challengeType: 0
dashedName: step-88
---
# --description--
You need to get all of the input containers. Declare an `inputContainers` variable, and assign it to the value of querying the document for all elements with the class `input-container`.
# --hints--
You should declare an `inputContainers` variable in your `clearForm` function.
```js
assert.match(clearForm.toString(), /inputContainers\s*=/);
```
You should use the `querySelectorAll` method to get all of the elements with the class `input-container`.
```js
assert.match(clearForm.toString(), /document\.querySelectorAll\(\s*('|")\.input-container\1\s*\)/);
```
You should assign the value of the `querySelectorAll` method to the `inputContainers` variable.
```js
assert.match(clearForm.toString(), /inputContainers\s*=\s*document\.querySelectorAll\(\s*('|")\.input-container\1\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
--fcc-editable-region--
function clearForm() {
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
```

View File

@@ -0,0 +1,263 @@
---
id: 63c9eb4a5d68f12f32d9b440
title: Step 89
challengeType: 0
dashedName: step-89
---
# --description--
Remember that `document.querySelectorAll` returns a `NodeList`, which is array-like but is not an array. However, the `Array` object has a `.from()` method that accepts an array-like and returns an array. This is helpful when you want access to more robust array methods, which you will learn about in a future project.
Wrap your `inputContainers` query selector in `Array.from()`. Do this on the same line as your declaration.
# --hints--
You should wrap your `querySelectorAll` in `Array.from()`.
```js
assert.match(clearForm, /Array\.from\(\s*document\.querySelectorAll\(\s*('|")\.input-container*\1\s*\)\s*\)/);
```
You should assign the result of `Array.from()` to your `inputContainers` variable.
```js
assert.match(clearForm, /inputContainers\s*=\s*Array\.from\(\s*document\.querySelectorAll\(\s*('|")\.input-container*\1\s*\)\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
--fcc-editable-region--
function clearForm() {
const inputContainers = document.querySelectorAll('.input-container');
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
```

View File

@@ -0,0 +1,276 @@
---
id: 63c9ebb7b12bca3025b0a935
title: Step 90
challengeType: 0
dashedName: step-90
---
# --description--
It is time for another loop. Use a `for` loop to iterate through the `inputContainers` array.
Inside the loop, set the `innerHTML` property of the element at the current index to an empty string. This will clear all of the contents of that input container.
# --hints--
Your `clearForm` function should have a `for` loop.
```js
// loop protect injects stuff, so let's look at the raw code again
const clearForm = code.split("function clearForm()")[1];
assert.match(clearForm, /for\s*\(/);
```
Your `for` loop should iterate through the `inputContainers` array. Remember to use `i` as your iterator.
```js
const clearForm = code.split("function clearForm()")[1];
assert.match(clearForm, /for\s*\(\s*let\s+i\s*=\s*0\s*;\s*i\s*<\s*inputContainers\.length\s*;\s*i\s*\+\+\s*\)/);
```
Your `for` loop should set the `innerHTML` property of `inputContainers[i]` to an empty string.
```js
const clearForm = code.split("function clearForm()")[1];
const forLoop = clearForm.split("for")[1];
assert.match(forLoop, /inputContainers\[\s*i\s*\]\s*\.innerHTML\s*=\s*(`|'|")\1\s*/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
--fcc-editable-region--
function clearForm() {
const inputContainers = Array.from(document.querySelectorAll('.input-container'));
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
```

View File

@@ -0,0 +1,275 @@
---
id: 63c9ec044acedf312c4974ff
title: Step 91
challengeType: 0
dashedName: step-91
---
# --description--
After your loop completes, you need to clear the `budgetNumberInput`. Set the `value` property of `budgetNumberInput` to an empty string.
# --hints--
Your `clearForm` function should access the `value` property of the `budgetNumberInput` element.
```js
assert.match(clearForm.toString(), /budgetNumberInput\.value/);
```
Your `clearForm` function should set the `value` property of the `budgetNumberInput` element to an empty string.
```js
assert.match(clearForm.toString(), /budgetNumberInput\.value\s*=\s*('|"|`)\1/);
```
You should modify the `budgetNumberInput` after your `for` loop.
```js
const clearForm = code.split("function clearForm()")[1];
const afterLoop = clearForm.split("}")[1];
assert.match(afterLoop, /budgetNumberInput\.value/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
--fcc-editable-region--
function clearForm() {
const inputContainers = Array.from(document.querySelectorAll('.input-container'));
for (let i = 0; i < inputContainers.length; i++) {
inputContainers[i].innerHTML = '';
}
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
```

View File

@@ -0,0 +1,276 @@
---
id: 63c9f24afbc9cf324dcaa9a4
title: Step 92
challengeType: 0
dashedName: step-92
---
# --description--
You also need to clear the `output` element's text. You can do this by setting the `innerText` property to an empty string.
The difference between `innerText` and `innerHTML` is that `innerText` will not render HTML elements, but will display the tags and content as raw text.
# --hints--
Your `clearForm` function should access the `innerText` property of the `output` element.
```js
assert.match(clearForm.toString(), /output\.innerText/);
```
Your `clearForm` function should set the `innerText` property of the `output` element to an empty string.
```js
assert.match(clearForm.toString(), /output\.innerText\s*=\s*('|"|`)\1/);
```
You should modify `output` after modifying `budgetNumberInput`.
```js
assert.isAbove(clearForm.toString().indexOf('output'), clearForm.toString().indexOf('budgetNumberInput'));
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
--fcc-editable-region--
function clearForm() {
const inputContainers = Array.from(document.querySelectorAll('.input-container'));
for (let i = 0; i < inputContainers.length; i++) {
inputContainers[i].innerHTML = '';
}
budgetNumberInput.value = '';
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
```

View File

@@ -0,0 +1,277 @@
---
id: 63c9f28bda3e3f336e21b6b4
title: Step 93
challengeType: 0
dashedName: step-93
---
# --description--
To finish off this function, you need to restore the `hide` class to the `output` element. The `classList` property has an `.add()` method which is the opposite of the `.remove()` method. It accepts a string representing the class to add to the element.
Add the `hide` class to your `output`.
# --hints--
You should access the `classList` property of the `output` element.
```js
assert.match(clearForm.toString(), /output\.classList/);
```
You should call the `.add()` method on the `classList` property of the `output` element.
```js
assert.match(clearForm.toString(), /output\.classList\.add/);
```
You should pass `hide` as the argument to the `.add()` method.
```js
assert.match(clearForm.toString(), /output\.classList\.add\(\s*('|")hide\1\s*\)/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
--fcc-editable-region--
function clearForm() {
const inputContainers = Array.from(document.querySelectorAll('.input-container'));
for (let i = 0; i < inputContainers.length; i++) {
inputContainers[i].innerHTML = '';
}
budgetNumberInput.value = '';
output.innerText = '';
}
--fcc-editable-region--
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
```

View File

@@ -0,0 +1,520 @@
---
id: 63c9f2bff625af342023512c
title: Step 94
challengeType: 0
dashedName: step-94
---
# --description--
To complete this project, add an event listener to the `clearButton` button. When the button is clicked, it should call the `clearForm` function.
Congratulations! Your project is complete.
# --hints--
You should add an event listener to the `clearButton` button.
```js
assert.match(code, /clearButton\s*\.addEventListener\s*\(/);
```
You should pass `click` as the first argument to `.addEventListener()`.
```js
assert.match(code, /clearButton\s*\.addEventListener\s*\(\s*('|"|`)click\1\s*/);
```
You should pass `clearForm` as the second argument to `.addEventListener()`.
```js
assert.match(code, /clearButton\s*\.addEventListener\s*\(\s*('|"|`)click\1\s*,\s*clearForm\s*/);
```
# --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" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
function clearForm() {
const inputContainers = Array.from(document.querySelectorAll('.input-container'));
for (let i = 0; i < inputContainers.length; i++) {
inputContainers[i].innerHTML = '';
}
budgetNumberInput.value = '';
output.innerText = '';
output.classList.add('hide');
}
addEntryButton.addEventListener("click", addEntry);
calorieCounter.addEventListener("submit", calculateCalories);
--fcc-editable-region--
--fcc-editable-region--
```
# --solutions--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Calorie Counter</title>
</head>
<body>
<main>
<h1>Calorie Counter</h1>
<div class="container">
<form id="calorie-counter">
<label for="budget">Budget</label>
<input
type="number"
min="0"
id="budget"
placeholder="Daily calorie budget"
required
/>
<fieldset id="breakfast">
<legend>Breakfast</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="lunch">
<legend>Lunch</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="dinner">
<legend>Dinner</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="snacks">
<legend>Snacks</legend>
<div class="input-container"></div>
</fieldset>
<fieldset id="exercise">
<legend>Exercise</legend>
<div class="input-container"></div>
</fieldset>
<div class="controls">
<span>
<label for="entry-dropdown">Add food or exercise:</label>
<select id="entry-dropdown" name="options">
<option value="breakfast" selected>Breakfast</option>
<option value="lunch">Lunch</option>
<option value="dinner">Dinner</option>
<option value="snacks">Snacks</option>
<option value="exercise">Exercise</option>
</select>
<button type="button" id="add-entry">Add Entry</button>
</span>
</div>
<div>
<button type="submit" id="calculate-calories">
Calculate Remaining Calories
</button>
<button type="button" id="clear">Clear</button>
</div>
</form>
<div id="output" class="output hide"></div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
```
```css
body {
font-family: "Lato", Arial;
}
h1 {
text-align: center;
}
.container {
width: 90%;
max-width: 680px;
}
h1,
.container,
.output {
margin: 20px auto;
}
label,
legend {
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
}
button:hover {
cursor: pointer;
}
fieldset,
label,
button,
input,
select {
margin-bottom: 10px;
}
.output {
border: 2px solid black;
padding: 10px;
text-align: center;
}
.hide {
display: none;
}
.output span {
font-weight: bold;
font-size: 1.2em;
}
.surplus {
color: #006627;
}
.deficit {
color: #B30000;
}
```
```js
const calorieCounter = document.getElementById('calorie-counter');
const budgetNumberInput = document.getElementById('budget');
const entryDropdown = document.getElementById('entry-dropdown');
const addEntryButton = document.getElementById('add-entry');
const clearButton = document.getElementById('clear');
const output = document.getElementById('output');
let isError = false;
function cleanInputString(str) {
const regex = /[+-\s]/g;
return str.replace(regex, '');
}
function isInvalidInput(str) {
const regex = /\d+e\d+/i;
return str.match(regex);
}
function addEntry() {
const targetInputContainer = document.querySelector(`#${entryDropdown.value} .input-container`);
const entryNumber = targetInputContainer.querySelectorAll('input[type="text"]').length + 1;
const HTMLString = `
<label for="${entryDropdown.value}-${entryNumber}-name">Entry ${entryNumber} Name</label>
<input type="text" id="${entryDropdown.value}-${entryNumber}-name" placeholder="Name" />
<label for="${entryDropdown.value}-${entryNumber}-calories">Entry ${entryNumber} Calories</label>
<input
type="number"
min="0"
id="${entryDropdown.value}-${entryNumber}-calories"
placeholder="Calories"
/>`;
targetInputContainer.insertAdjacentHTML('beforeend', HTMLString);
}
function calculateCalories(e) {
e.preventDefault();
isError = false;
const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]');
const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]');
const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]');
const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]');
const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]');
const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs);
const lunchCalories = getCaloriesFromInputs(lunchNumberInputs);
const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs);
const snacksCalories = getCaloriesFromInputs(snacksNumberInputs);
const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs);
const budgetCalories = getCaloriesFromInputs([budgetNumberInput]);
if (isError) {
return;
}
const consumedCalories = breakfastCalories + lunchCalories + dinnerCalories + snacksCalories;
const remainingCalories = budgetCalories - consumedCalories + exerciseCalories;
const surplusOrDeficit = remainingCalories >= 0 ? 'Surplus' : 'Deficit';
output.innerHTML = `
<span class="${surplusOrDeficit.toLowerCase()}">${Math.abs(remainingCalories)} Calorie ${surplusOrDeficit}</span>
<hr>
<p>${budgetCalories} Calories Budgeted</p>
<p>${consumedCalories} Calories Consumed</p>
<p>${exerciseCalories} Calories Burned</p>
`;
output.classList.remove('hide');
}
function getCaloriesFromInputs(list) {
let calories = 0;
for (let i = 0; i < list.length; i++) {
const currVal = cleanInputString(list[i].value);
const invalidInputMatch = isInvalidInput(currVal);
if (invalidInputMatch) {
alert(`Invalid Input: ${invalidInputMatch[0]}`);
isError = true;
return null;
}
calories += Number(currVal);
}
return calories;
}
function clearForm() {
const inputContainers = Array.from(document.querySelectorAll('.input-container'));
for (let i = 0; i < inputContainers.length; i++) {
inputContainers[i].innerHTML = '';
}
budgetNumberInput.value = '';
output.innerText = '';
output.classList.add('hide');
}
addEntryButton.addEventListener('click', addEntry);
calorieCounter.addEventListener('submit', calculateCalories);
clearButton.addEventListener('click', clearForm);
```

View File

@@ -1,100 +0,0 @@
---
id: 5ddb965c65d27e1512d44d9a
title: Step 1
challengeType: 0
dashedName: step-1
---
# --description--
When a browser loads a page, it creates a Document Object Model (DOM) representation of the page which includes all of the HTML elements in a tree structure.
In JavaScript, you can access the DOM by referencing the global `document` object.
To view the DOM, log it to the console with `console.log(document)`.
# --hints--
See description above for instructions.
```js
assert(code.replace(/\s/g, '').match(/console\.log\(document\)/));
```
# --seed--
## --before-user-code--
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<form id="calorie-form">
<h2 class="center">Calorie Counter</h2>
<div class="grid">
<legend>Sex</legend>
<div>
<input type="radio" name="sex" id="female" value="F" checked />
<label for="female">
Female (2,000 calories)
</label>
<div>
<input type="radio" name="sex" id="male" value="M" />
<label for="male">
Male (2,500 calories)
</label>
</div>
</div>
</div>
<div class="grid" id="entries">
Breakfast <input type="number" min="0" class="cal-control" id="breakfast" /><br>
Lunch <input type="number" min="0" class="cal-control" id="lunch" /><br>
Dinner <input type="number" min="0" class="cal-control" id="dinner" />
</div>
<button type="button" class="btn-add" id="add">
Add Entry
</button>
<button type="submit" class="btn-solid" id="calculate">
Calculate
</button>
<button type="button" class="btn-outline" id="clear">
Clear
</button>
</form>
<div id="output"></div>
</div>
```
## --after-user-code--
```html
</body>
</html>
```
## --seed-contents--
```html
<script>
--fcc-editable-region--
--fcc-editable-region--
</script>
```
# --solutions--
```html
<script>
console.log(document);
</script>
```

View File

@@ -1,114 +0,0 @@
---
id: 5ddb965c65d27e1512d44d9b
title: Step 2
challengeType: 0
dashedName: step-2
---
# --description--
In our HTML document, we have a form element with an `id` attribute: `<form id="calorie-form">`
To reference and access this particular form in JavaScript, we can use the getElementById() method on the document and provide the ID.
The code `document.getElementById('my-form')` gets a reference to an HTML element with an `id` of `my-form`. Get a reference to the HTML element with the `id` of `calorie-form`.
# --hints--
See description above for instructions.
```js
assert(
code
.replace(/\s/g, '')
.match(/document\.getElementById\([\'\"\`]calorie\-form[\'\"\`]\)/)
);
```
# --seed--
## --before-user-code--
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<form id="calorie-form">
<h2 class="center">Calorie Counter</h2>
<div class="grid">
<legend>Sex</legend>
<div>
<input type="radio" name="sex" id="female" value="F" checked />
<label for="female">
Female (2,000 calories)
</label>
<div>
<input type="radio" name="sex" id="male" value="M" />
<label for="male">
Male (2,500 calories)
</label>
</div>
</div>
</div>
<div class="grid" id="entries">
Breakfast
<input
type="number"
min="0"
class="cal-control"
id="breakfast"
/><br />
Lunch
<input type="number" min="0" class="cal-control" id="lunch" /><br />
Dinner <input type="number" min="0" class="cal-control" id="dinner" />
</div>
<button type="button" class="btn-add" id="add">
Add Entry
</button>
<button type="submit" class="btn-solid" id="calculate">
Calculate
</button>
<button type="button" class="btn-outline" id="clear">
Clear
</button>
</form>
<div id="output"></div>
</div>
</body>
</html>
```
## --after-user-code--
```html
</body>
</html>
```
## --seed-contents--
```html
<script>
--fcc-editable-region--
//console.log(document);
--fcc-editable-region--
</script>
```
# --solutions--
```html
<script>
//console.log(document);
document.getElementById('calorie-form');
</script>
```

View File

@@ -1,119 +0,0 @@
---
id: 5ddb965c65d27e1512d44d9c
title: Step 3
challengeType: 0
dashedName: step-3
---
# --description--
Now we need to specify what should be done with the form when the user submits it by clicking the Calculate button.
Forms have an `onsubmit` event that can execute a function when the form is submitted.
For example, in `document.getElementById('my-form').onsubmit = processForm;`, the function `processForm` will run when the form is submitted.
Assign a function named `calculate` to the `onsubmit` event of your form.
You will create the `calculate` function later.
# --hints--
See description above for instructions.
```js
assert(
code
.replace(/\s/g, '')
.match(
/document\.getElementById\([\'\"\`]calorie\-form[\'\"\`]\)\.onsubmit\=calculate/
)
);
```
# --seed--
## --before-user-code--
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<form id="calorie-form">
<h2 class="center">Calorie Counter</h2>
<div class="grid">
<legend>Sex</legend>
<div>
<input type="radio" name="sex" id="female" value="F" checked />
<label for="female">
Female (2,000 calories)
</label>
<div>
<input type="radio" name="sex" id="male" value="M" />
<label for="male">
Male (2,500 calories)
</label>
</div>
</div>
</div>
<div class="grid" id="entries">
Breakfast
<input
type="number"
min="0"
class="cal-control"
id="breakfast"
/><br />
Lunch
<input type="number" min="0" class="cal-control" id="lunch" /><br />
Dinner <input type="number" min="0" class="cal-control" id="dinner" />
</div>
<button type="button" class="btn-add" id="add">
Add Entry
</button>
<button type="submit" class="btn-solid" id="calculate">
Calculate
</button>
<button type="button" class="btn-outline" id="clear">
Clear
</button>
</form>
<div id="output"></div>
</div>
</body>
</html>
```
## --after-user-code--
```html
</body>
</html>
```
## --seed-contents--
```html
<script>
--fcc-editable-region--
document.getElementById('calorie-form');
--fcc-editable-region--
</script>
```
# --solutions--
```html
<script>
document.getElementById('calorie-form').onsubmit = calculate;
</script>
```

View File

@@ -1,112 +0,0 @@
---
id: 5ddb965c65d27e1512d44d9d
title: Step 4
challengeType: 0
dashedName: step-4
---
# --description--
Create the `calculate` function that will hold the code to sum up the user's calorie inputs. Leave the body blank for now. Here is an example of an empty function called `square`:
```js
function square() {}
```
# --hints--
See description above for instructions.
```js
assert(typeof calculate === 'function');
```
# --seed--
## --before-user-code--
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<form id="calorie-form">
<h2 class="center">Calorie Counter</h2>
<div class="grid">
<legend>Sex</legend>
<div>
<input type="radio" name="sex" id="female" value="F" checked />
<label for="female">
Female (2,000 calories)
</label>
<div>
<input type="radio" name="sex" id="male" value="M" />
<label for="male">
Male (2,500 calories)
</label>
</div>
</div>
</div>
<div class="grid" id="entries">
Breakfast
<input
type="number"
min="0"
class="cal-control"
id="breakfast"
/><br />
Lunch
<input type="number" min="0" class="cal-control" id="lunch" /><br />
Dinner <input type="number" min="0" class="cal-control" id="dinner" />
</div>
<button type="button" class="btn-add" id="add">
Add Entry
</button>
<button type="submit" class="btn-solid" id="calculate">
Calculate
</button>
<button type="button" class="btn-outline" id="clear">
Clear
</button>
</form>
<div id="output"></div>
</div>
</body>
</html>
```
## --after-user-code--
```html
</body>
</html>
```
## --seed-contents--
```html
<script>
document.getElementById('calorie-form').onsubmit = calculate;
--fcc-editable-region--
--fcc-editable-region--
</script>
```
# --solutions--
```html
<script>
document.getElementById('calorie-form').onsubmit = calculate;
function calculate() {}
</script>
```

View File

@@ -1,115 +0,0 @@
---
id: 5ddb965c65d27e1512d44d9e
title: Step 5
challengeType: 0
dashedName: step-5
---
# --description--
By default, `onsubmit` will pass the event object as a parameter to the function it calls. People usually call it `e`, short for event. Update the `calculate()` function to accept `e` as parameter.
Here is an example of an empty function called `square` that takes a `number` as a parameter:
```js
function square(number) {}
```
# --hints--
See description above for instructions.
```js
assert(calculate.toString().match(/function calculate\(\s*e\)\s*\{\s*\}/));
```
# --seed--
## --before-user-code--
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<form id="calorie-form">
<h2 class="center">Calorie Counter</h2>
<div class="grid">
<legend>Sex</legend>
<div>
<input type="radio" name="sex" id="female" value="F" checked />
<label for="female">
Female (2,000 calories)
</label>
<div>
<input type="radio" name="sex" id="male" value="M" />
<label for="male">
Male (2,500 calories)
</label>
</div>
</div>
</div>
<div class="grid" id="entries">
Breakfast
<input
type="number"
min="0"
class="cal-control"
id="breakfast"
/><br />
Lunch
<input type="number" min="0" class="cal-control" id="lunch" /><br />
Dinner <input type="number" min="0" class="cal-control" id="dinner" />
</div>
<button type="button" class="btn-add" id="add">
Add Entry
</button>
<button type="submit" class="btn-solid" id="calculate">
Calculate
</button>
<button type="button" class="btn-outline" id="clear">
Clear
</button>
</form>
<div id="output"></div>
</div>
</body>
</html>
```
## --after-user-code--
```html
</body>
</html>
```
## --seed-contents--
```html
<script>
--fcc-editable-region--
document.getElementById('calorie-form').onsubmit = calculate;
function calculate() {}
--fcc-editable-region--
</script>
```
# --solutions--
```html
<script>
document.getElementById('calorie-form').onsubmit = calculate;
function calculate(e) {}
</script>
```

Some files were not shown because too many files have changed in this diff Show More