feat(learn): Update Basic HTML Cat Photo App project descriptions and hints and tests (v7) (#39131)

* feat: added Cat Photo App project

Added new steps

feat: add tests + targetted hints for demo

simplify wording and combine some tests

feat: update text and add tests/hints

fix: changed descriptions and tests

feat: added tests for part 11 - 15

fix: reworded description for steps 2 and 10

fix: changed isBeta to isHidden

fix: temporarily remove fcc-editable strings

fix: added project to challengeTypes.js

fix: added missing parentheses

fix: test text improvements

fix: changes to tests and text discussed in meeting

fix: adjust logic for detecting indentation in part 07

fix: missing regex characters and made last test more permissive for part 04

feat: add steps 25 to 55 and notes

fix: added h1 element back to steps 5-24

fix: h1 and h2 elements from steps 25 to 50

fix: added missing DOCTYPE declaration steps 20-24

fix: miscellaneous text edits

fix: break up part 28, change local paths for images to short s3 cdn URLs

fix: part 01 and 02 descriptions and tests

feat: pull in changes from #39145 and remove solution sections

fix: adjust descriptions and break up steps 33 and 35

fix: break up more steps and adjust text

feat: add tests for parts 25 - 30

* fix: ran reorder-steps.js

* fix: added editable region markers

* fix: standardize opening tag hint text

* fix: remove trailing periods from descriptions and hints and adjust tests

* fix: remove unnecessary instructions sections

* fix: added test to check for only one h1 element

* fix: removed comma

* fix: changed paragraph element to `p` element

* fix: added test for extra h1 element

* fix: test to validate only one img element exists

* fix: replaced code tags with backticks

* fix: reworded description

* fix: reworded step description

* fix: changed tests for first step

* fix: change last two alt values to sentences

* fix: check for spaces in text strings

* fix: removed extra dot before replace method

* fix: moved example before instruction

* fix: rearranged step 6 tests

* fix: capitalized p in paragraph

* fix: rewored step 7's description and a test text

* fix: corrected test for step 8

* fix: improved step 9 tests

* fix: moved example above instruction

* fix: corrected step 9 test wording

* fix: rearrange test order for step 10

* fix: moved example before instructions for step 11

* fix: improved step 12 descripton and tests

* fix: corrected tests for steps 9, 10, 11, 13, 14

* fix: added ERMs to steps 4-14

* fix: minor typos

* fix: reword steps so examples are above instructions

* fix: introduce inline and block elements and use divs instead of br

* fix: add or adjust tests for steps 15 - 27

* fix: moved ERM up one line

* fix: removed unnecessary quotes in tests' text

* fix: added dfn tags for step 45

* fix: removed adding # to href step

* fix: tests 15 - 16

* fix: reword descriptions so they're not as hand holdy

* fix: reorder/reword steps 58 - 60

* feat: simplify radio button steps

* fix: wording and add demo step

* fix: remove doctype and teach in last step

* fix: update part-demo

* fix: added some more step 15 hints

* fix: added step to introduce section elems

* fix: added section elements to project

* fix: update final code

* fix: update tests for 15a and 16

* fix: add section elements to parts 45 to 61

* fix: change p elements to h3, update tests and text

* fix: added new test for step 9

* fix: fixed/added tests for steps 15-30a

* fix: use fieldset elements instead of divs in the form

* fix: added new test to setp 30a

* fix: changed `main` to `section`

* fix: corrected/added tests for step 31

* feat: add tests 32 - 36

* fix: revert change to js rpg game

* fix: simplify tests 32 - 36

* fix: updated submit-cat-form url

fix: changed submit-cat-form url

* fix: added/rearranged tests steps 32-36

* fix: added tests for step 36a

* fix: used hasAttribute where applicable

* fix: misc edits for steps 10 and 35-36a

* fix: add tests to step 37

* fix: reworded step 37

* fix: added more verbiage to steps 35 and 36

* fix: modified step 38 desc and added tests

* fix: added hints/tests for step 40

* fix: added hints/tests for step 41

* fix: added hints/tests for steps 42 and 43

* fix: made attribute values match exactly

* fix: change wording from text input to text field

* fix: rearrange name attribute lessons

* feat: tests for 44 - 44b

* fix: added a step  35a

* fix: added name="catphotourl" to steps 36-61

* fix: reworded steps 41 and 43

* fix: removed intro to for attribute

* fix: rewrite of step 44b's desc and tests

* fix: added step 45 hints/tests

fix

* fix: removed for attribute from steps 45a-61

* fix: removed extra )

* fix: wrapped "section" with backticks

* fix: added test for steps 45a and 45b

* fix: adjust position of label steps 55-61

* fix: removed conole.log statements

* fix: added tests to step 45c

* fix: renamed step 49 to step 46a

* fix: moved label element for steps 48-53

* fix: reworded step 47 description and instructions

* fix: typos in description and test text

* feat: add tests 46-48

* fix: wording

* fix: remove case insensitivity from a couple of tests

* fix: wording and add erms

* fix: add additional test for step 48

* fix: added hints/tests for step 50

* fix: added hints/tests for step 51

* fix: added hints/tests to step 53

* fix: added hints/tests for step 55

* fix: added hints/tests for step 56

* feat: tests for 57-61

* fix: removed duplicate test in step 55

* fix: adjusted 1st test for step 57

* fix: simplified test for title text

* fix: improved tests for step 60-61

* fix: removed demo.md file

* fix: ran reorder-steps.js

* fix: part 10 description

* fix: part 14 description

* fix: part 24 - move ERMs

* fix: part 05 description

* fix: part 54 test text

* fix: part 06 - wording and add test for p and main closing tag order

* fix: part 50 - add test to check for order of fieldset elements

* feat: value attribute for radio buttons step and seed changes

* feat: value attribute for checkboxes step and seed changes

* fix: update part 14 description

* fix: revert ERMs for part 24

* fix: remove last test in part 06

* fix: text and typos for new radio and checkbox lessons

* fix: text and typos for new radio and checkbox lessons

* fix: add test to part 01

* fix: ran reorder-steps.js

Co-authored-by: Kris Koishigawa <scissorsneedfoodtoo@gmail.com>
This commit is contained in:
Randell Dawson
2020-07-24 09:13:46 -07:00
committed by Mrugesh Mohapatra
parent ad83a2e3f4
commit fd6f8b5cd4
72 changed files with 5957 additions and 4 deletions

View File

@ -0,0 +1,9 @@
---
title: Introduction to the Basic HTML Cat Photo App
block: Basic HTML Cat Photo App
superBlock: Responsive Web Design
isBeta: true
---
## Introduction to the Basic HTML Cat Photo App
This is a test for the new project-based curriculum.

View File

@ -132,6 +132,7 @@ exports.helpCategory = {
numpy: 'Python',
'data-analysis-with-python-course': 'Python',
'python-for-penetration-testing': 'Python',
'basic-html-cat-photo-app': 'HTML-CSS',
'css-variables-skyline': 'HTML-CSS',
'basic-javascript-rpg-game': 'JavaScript',
'functional-programming-spreadsheet': 'JavaScript',

View File

@ -0,0 +1,283 @@
{
"name": "Basic HTML Cat Photo App",
"dashedName": "basic-html-cat-photo-app",
"order": 9,
"time": "5 hours",
"template": "",
"required": [],
"superBlock": "responsive-web-design",
"superOrder": 1,
"isBeta": true,
"challengeOrder": [
[
"5dc174fcf86c76b9248c6eb2",
"Part 01"
],
[
"5dc1798ff86c76b9248c6eb3",
"Part 02"
],
[
"5dc17d3bf86c76b9248c6eb4",
"Part 03"
],
[
"5dc17dc8f86c76b9248c6eb5",
"Part 04"
],
[
"5dc2385ff86c76b9248c6eb7",
"Part 05"
],
[
"5dc23991f86c76b9248c6eb8",
"Part 06"
],
[
"5dc23f9bf86c76b9248c6eba",
"Part 07"
],
[
"5dc24073f86c76b9248c6ebb",
"Part 08"
],
[
"5dc24165f86c76b9248c6ebc",
"Part 09"
],
[
"5dc24614f86c76b9248c6ebd",
"Part 10"
],
[
"5ddbd81294d8ddc1510a8e56",
"Part 11"
],
[
"5dfa22d1b521be39a3de7be0",
"Part 12"
],
[
"5dfa2407b521be39a3de7be1",
"Part 13"
],
[
"5dfa30b9eacea3f48c6300ad",
"Part 14"
],
[
"5f07be6ef7412fbad0c5626b",
"Part 15"
],
[
"5f07c98cdb9413cbd4b16750",
"Part 16"
],
[
"5dfa3589eacea3f48c6300ae",
"Part 17"
],
[
"5dfa371beacea3f48c6300af",
"Part 18"
],
[
"5dfa37b9eacea3f48c6300b0",
"Part 19"
],
[
"5dfb5ecbeacea3f48c6300b1",
"Part 20"
],
[
"5dfb6250eacea3f48c6300b2",
"Part 21"
],
[
"5dfb655eeacea3f48c6300b3",
"Part 22"
],
[
"5dfb6a35eacea3f48c6300b4",
"Part 23"
],
[
"5ef9b03c81a63668521804d0",
"Part 24"
],
[
"5ef9b03c81a63668521804d1",
"Part 25"
],
[
"5ef9b03c81a63668521804d2",
"Part 26"
],
[
"5ef9b03c81a63668521804d3",
"Part 27"
],
[
"5efada803cbd2bbdab94e332",
"Part 28"
],
[
"5efae0543cbd2bbdab94e333",
"Part 29"
],
[
"5efae16e3cbd2bbdab94e334",
"Part 30"
],
[
"5ef9b03c81a63668521804d4",
"Part 31"
],
[
"5f07fb1579dc934717801375",
"Part 32"
],
[
"5ef9b03c81a63668521804d5",
"Part 33"
],
[
"5ef9b03c81a63668521804d6",
"Part 34"
],
[
"5ef9b03c81a63668521804d7",
"Part 35"
],
[
"5ef9b03c81a63668521804d8",
"Part 36"
],
[
"5efb23e70dc218d6c85f89b1",
"Part 37"
],
[
"7cf9b03d81a65668421804c3",
"Part 38"
],
[
"5ef9b03c81a63668521804d9",
"Part 39"
],
[
"5ef9b03c81a63668521804db",
"Part 40"
],
[
"5ef9b03c81a63668521804da",
"Part 41"
],
[
"5efb2c990dc218d6c85f89b2",
"Part 42"
],
[
"5ef9b03c81a63668521804dc",
"Part 43"
],
[
"5ef9b03c81a63668521804dd",
"Part 44"
],
[
"5ef9b03c81a63668521804df",
"Part 45"
],
[
"5f05a1d8e233dff4a68508d8",
"Part 46"
],
[
"5ef9b03c81a63668521804de",
"Part 47"
],
[
"5f1a80975fc4bcae0edb3497",
"Part 48"
],
[
"5ef9b03c81a63668521804e1",
"Part 49"
],
[
"5f0d48e7b435f13ab6550051",
"Part 50"
],
[
"5f0d4ab1b435f13ab6550052",
"Part 51"
],
[
"5f0d4d04b435f13ab6550053",
"Part 52"
],
[
"5ef9b03c81a63668521804e2",
"Part 53"
],
[
"5efc54138d6a74d05e68af76",
"Part 54"
],
[
"5efc4f528d6a74d05e68af74",
"Part 55"
],
[
"5efc518e8d6a74d05e68af75",
"Part 56"
],
[
"5ef9b03c81a63668521804e3",
"Part 57"
],
[
"5efc575c8d6a74d05e68af77",
"Part 58"
],
[
"5f1a89f1190aff21ae42105a",
"Part 59"
],
[
"5ef9b03c81a63668521804e5",
"Part 60"
],
[
"5ef9b03c81a63668521804e7",
"Part 61"
],
[
"5ef9b03c81a63668521804e8",
"Part 62"
],
[
"5ef9b03c81a63668521804e9",
"Part 63"
],
[
"5ef9b03c81a63668521804ea",
"Part 64"
],
[
"5ef9b03c81a63668521804eb",
"Part 65"
],
[
"5ef9b03c81a63668521804ec",
"Part 66"
],
[
"5ef9b03c81a63668521804ee",
"Part 67"
]
],
"helpRoom": "Help",
"fileName": "01-responsive-web-design/basic-html-cat-photo-app.json"
}

View File

@ -0,0 +1,53 @@
---
id: 5dc174fcf86c76b9248c6eb2
title: Part 01
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
HTML elements have opening tags like `<h1>` and closing tags like `</h1>`.
Find the `h1` element and change the text between its opening and closing tags to say `CatPhotoApp`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: The text `CatPhotoApp` should be present in the code. You may want to check your spelling.
testString: assert( code.match(/catphotoapp/i) );
- text: 'Your `h1` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('h1') );
- text: Your `h1` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/h1\>/) );
- text: You have more than one `h1` element. Remove the extra `h1` element.
testString: assert( document.querySelectorAll('h1').length === 1 );
- text: Your `h1` element's text should be `CatPhotoApp`. You have either omitted the text, have a typo, or it is not between the `h1` element's opening and closing tags.
testString: assert( document.querySelector('h1').innerText.toLowerCase() === 'catphotoapp' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
--fcc-editable-region--
<h1>Hello World</h1>
--fcc-editable-region--
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,59 @@
---
id: 5dc1798ff86c76b9248c6eb3
title: Part 02
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `h1` to `h6` heading elements are used to signify the importance of content below them. The lower the number, the higher the importance, so `h2` elements have less importance than `h1` elements. Only use one `h1` element per page and place lower importance headings below higher importance headings.
Add an `h2` element below the `h1` element that says `Cat Photos`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `h1` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('h1') );
- text: Your `h1` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/h1\>/) );
- text: You should only have one `h1` element. Remove the extra.
testString: assert( document.querySelector('h1') && document.querySelectorAll('h1').length === 1 );
- text: Your `h1` element's text should be 'CatPhotoApp'. You have either omitted the text or have a typo.
testString: assert( document.querySelector('h1').innerText.toLowerCase() === 'catphotoapp' );
- text: "Your `h2` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelector('h2') );
- text: Your `h2` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/h2\>/) );
- text: Your `h2` element's text should be 'Cat Photos'. Only place the text `Cat Photos` between the opening and closing `h2` tags.
testString: assert( document.querySelector('h2').innerText.toLowerCase() === 'cat photos' );
- text: "Your `h2` element should be below the `h1` element. The `h1` element has greater importance and must be above the `h2` element."
testString: const collection = [...document.querySelectorAll('h1,h2')].map(node => node.nodeName); assert( collection.indexOf('H1') < collection.indexOf('H2') );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
--fcc-editable-region--
<h1>CatPhotoApp</h1>
--fcc-editable-region--
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,52 @@
---
id: 5dc17d3bf86c76b9248c6eb4
title: Part 03
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Paragraph (`p`) elements are used to create paragraph text on websites.
Create a paragraph (`p`) element below your `h2` element, and give it the text `Click here to view more cat photos.`
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `p` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelector('p') );
- text: Your `p` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/p\>/) );
- text: Your `p` element's text should be `Click here to view more cat photos.` You have either omitted the text or have a typo.
testString: const extraSpacesRemoved = document.querySelector('p').innerText.replace(/\s+/g, ' '); assert( extraSpacesRemoved.match(/click here to view more cat photos\.?$/i) );
- text: Your `p` element should be below the `h2` element. You have them in the wrong order.
testString: const collection = [...document.querySelectorAll('h2,p')].map(node => node.nodeName); assert( collection.indexOf('H2') < collection.indexOf('P') );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
--fcc-editable-region--
<h2>Cat Photos</h2>
--fcc-editable-region--
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,57 @@
---
id: 5dc17dc8f86c76b9248c6eb5
title: Part 04
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Commenting allows you to leave messages without affecting the browser display. It also allows you to make code inactive. A comment in HTML starts with `<!--`, contains any number of lines of text, and ends with `-->`. For example, the comment `<!-- TODO: Remove h1 -->` contains the text `TODO: Remove h1`.
Add a comment above the `p` element with the text `TODO: Add link to cat photos`. \
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your comment should start with `<!--`. You are missing one or more of the characters that define the start of a comment.
testString: assert( code.match(/<!--/) );
- text: Your comment should end with `-->`. You are missing one or more of the characters that define the end of a comment.
testString: assert( code.match(/-->/) );
- text: Your code should not have extra opening/closing comment characters. You have an extra `<!--` or `-->` displaying in the browser.
testString: |
const noSpaces = code.replace(/\s/g, '');
assert (noSpaces.match(/<!--/g).length < 2 && noSpaces.match(/-->/g).length < 2 );
- text: 'Your comment should contain the text `TODO: Add link to cat photos`.'
testString: assert( code.match(/<!--\s*todo:\s+add\s+link\s+to\s+cat\s+photos\s*-->/i) );
- text: Your comment should be above the `p` element. You have them in the wrong order.
testString: assert( code.replace(/\s/g, '').match(/<!--todo:addlinktocatphotos--><p>clickheretoviewmorecatphotos\.?<\/p>/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<h2>Cat Photos</h2>
--fcc-editable-region--
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,56 @@
---
id: 5dc2385ff86c76b9248c6eb7
title: Part 05
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
HTML5 has some elements that identify different content areas. These elements make your HTML easier to read and help with Search Engine Optimization (SEO) and accessibility.
Identify the main section of this page by adding a `<main>` opening tag after the `h1` element, and a `</main>` closing tag after the `p` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `main` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelector('main') );
- text: Your `main` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/main\>/) );
- text: Your `main` element's opening tag should be below the `h1` element. You have them in the wrong order.
testString: const collection = [...document.querySelectorAll('main,h1')].map(node => node.nodeName); assert( collection.indexOf('H1') < collection.indexOf('MAIN') );
- text: Your `main` element's opening tag should be above the `h2` element. You have them in the wrong order.
testString: const collection = [...document.querySelectorAll('main,h2')].map(node => node.nodeName); assert( collection.indexOf('MAIN') < collection.indexOf('H2') );
- text: Your `main` element's closing tag should be below the `p` element. You have them in the wrong order.
testString: const mainNode = document.querySelector('main'); const pNode = document.querySelector('p'); assert( mainNode.contains(pNode) && pNode.textContent.toLowerCase().match(/click here to view more cat photos/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
--fcc-editable-region--
<h1>CatPhotoApp</h1>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,64 @@
---
id: 5dc23991f86c76b9248c6eb8
title: Part 06
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
HTML elements are often nested within other HTML elements. In the previous step you nested the `h2` element, comment and `p` element within the `main` element. A nested element is a child of its parent element.
To make HTML easier to read, indent the `h2` element, the comment, and `p` element exactly two spaces to indicate they are children of the `main` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your should have an `h2` element with text `Cat Photos`. You may have accidentally deleted it, it is missing both opening and closing tags, or the text has changed.
testString: assert( document.querySelector('h2') && code.match(/<\/h2\>/) && document.querySelector('h2').innerText.toLowerCase() === 'cat photos' );
- text: Your `h2` element should below the `main` element's opening tag and its opening tag should start 6 spaces over from the start of the line.
testString: assert( code.toLowerCase().match(/<main\>\n\s{6}<h2>/) );
- text: Your code should have a comment. You removed the comment from an earlier step.
testString: assert( code.match(/<!--.*-->/) );
- text: "The comment's text should be `TODO: Add link to cat photos`. Do not change the text or spacing of the comment."
testString: 'assert( code.match(/<!--\s*todo:\s+add\s+link\s+to\s+cat\s+photos\.?\s*-->/i) );'
- text: Your comment should be below the `h2` element and start 6 spaces over from the start of the line.
testString: 'assert( code.toLowerCase().match(/<\/h2>\n\s{6}<!--\s*todo:\s+add\s+link\s+to\s+cat\s+photos\s*-->/) );'
- text: Your code should have a `p` element. You have removed the `p` element from an earlier step.
testString: assert( document.querySelector('p') );
- text: The text of the `p` element should be `Click here to view more cat photos.` Do not change the text, spacing, or punctuation of the `p` element.
testString: assert( document.querySelector('p').innerText.toLowerCase().match(/click\s+here\s+to\s+view\s+more\s+cat\s+photos\.?$/) );
- text: Your `p` element should be below the comment and its opening tag should start 6 spaces over from the start of the line.
testString: assert( code.toLowerCase().match(/-->\n\s{6}<p>/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
--fcc-editable-region--
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,56 @@
---
id: 5dc23f9bf86c76b9248c6eba
title: Part 07
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
You can add images to your website by using the `img` element. `img` elements have an opening tag without a closing tag. A tag for an element without a closing tag is known as a <dfn>self-closing tag</dfn>.
Add an `img` element below the `p` element. At this point, no image will show up in the browser.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `img` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelector('img') );
- text: Your `img` element should not have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( !code.match(/<\/img\>/) );
- text: You should only have one `img` element. Remove any extras.
testString: assert( document.querySelectorAll('img').length === 1 );
- text: Your `img` element should be below the `p` element. You have them in the wrong order.
testString: const collection = [...document.querySelectorAll('p,img')].map(node => node.nodeName); assert( collection.indexOf('P') < collection.indexOf('IMG') );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
--fcc-editable-region--
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,57 @@
---
id: 5dc24073f86c76b9248c6ebb
title: Part 08
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
HTML <dfn>attributes</dfn> are special words used inside the opening tag of an element to control the element's behavior. The `src` attribute in an `img` element specifies the image's URL (where the image is located). An example of an `img` element using an `src` attribute: `<img src="https://www.your-image-source.com/your-image.jpg">`.
Add an `src` attribute to the existing `img` element that is set to the following URL: `https://bit.ly/fcc-relaxing-cat`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your code should have an `img` element. You may have removed the `img` element or you have not surrounded the `src` attribute's value with quotes.
testString: assert( document.querySelector('img') );
- text: Your `img` element should have an `src` attribute. You have either omitted the attribute or have a typo. Make sure there is a space between the element name and the attribute name.
testString: assert( document.querySelector('img').src );
- text: Your `img` element's `src` attribute should be set to 'https://bit.ly/fcc-relaxing-cat'. You have either omitted the URL or have a typo. The case of the URL is important.
testString: assert( document.querySelector('img').src === 'https://bit.ly/fcc-relaxing-cat' );
- text: Although you have set the `img` element's `src` to the correct URL, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<img\s+src\s*=\s*https:\/\/bit\.ly\/fcc-relaxing-cat/.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
<img>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,56 @@
---
id: 5dc24165f86c76b9248c6ebc
title: Part 09
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
All `img` elements should have an `alt` attribute. The `alt` attribute's text is used for screen readers to improve accessibility and is displayed if the image fails to load. For example, `<img src="cat.jpg" alt="A cat">` has an `alt` attribute with the text `A cat`.
Add an `alt` attribute to the `img` element with the text `A cute orange cat lying on its back`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your code should have an `img` element. You removed the `img` element from an earlier step.
testString: assert( document.querySelector('img') );
- text: Your `img` element does not have an `alt` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( document.querySelector('img').hasAttribute('alt') );
- text: Your `img` element's `alt` attribute value is set to something other than 'A cute orange cat lying on its back'. Make sure the `alt` attribute's value is surrounded with quotation marks.
testString: const altText = document.querySelector('img').alt.toLowerCase().replace(/\s+/g, ' '); assert( altText.match(/A cute orange cat lying on its back\.?$/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
<img src="https://bit.ly/fcc-relaxing-cat">
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,61 @@
---
id: 5dc24614f86c76b9248c6ebd
title: Part 10
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
You can link to another page with the anchor (`a`) element. For example, <a href="https://www.freecodecamp.org"></a> would link to `freecodecamp.org`.
Add an anchor element after the paragraph that links to `https://www.freecodecamp.org/cat-photos`. At this point, the link wont show up in the preview.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your anchor (`a`) element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelector('a') );
- text: "Your anchor (`a`) element should have a closing tag. Closing tags have a `/` just after the `<` character."
testString: assert( code.match(/<\/a\>/) );
- text: "Your anchor (`a`) element should be below the `p` element. You have them in the wrong order."
testString: const collection = [...document.querySelectorAll('a, p')].map(node => node.nodeName); assert( collection.indexOf('P') < collection.indexOf('A') );
- text: Your anchor (`a`) element does not have an `href` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( document.querySelector('a').hasAttribute('href') );
- text: "Your anchor (`a`) element should link to `https://www.freecodecamp.org/cat-photos`. You have either omitted the URL or have a typo."
testString: assert( document.querySelector('a').getAttribute('href') === 'https://www.freecodecamp.org/cat-photos' );
- text: Although you have set the anchor ('a') element's `href` attribute to the correct link, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<a\s+href\s*=\s*https:\/\/www.freecodecamp.org\/cat-photos/.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
--fcc-editable-region--
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
<img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back.">
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,56 @@
---
id: 5ddbd81294d8ddc1510a8e56
title: Part 11
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
A link's text must be placed between the opening and closing tags of an anchor (`a`) element. For example, `<a href="https://www.freecodecamp.org">click here to go to freeCodeCamp.org</a>` is a link with the text `click here to go to freeCodeCamp.org`.
Add the anchor text `cat photos` to the anchor element. This will become the link's text.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your anchor (`a`) element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelector('a') );
- text: "Your anchor (`a`) element should have a closing tag. Closing tags have a `/` just after the `<` character."
testString: assert( code.match(/<\/a\>/) );
- text: Your anchor (`a`) element's text should be `cat photos`. Make sure to put the link text between the anchor (`a`) element's opening tag and closing tag.
testString: assert( document.querySelector('a').innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more cat photos.</p>
--fcc-editable-region--
<a href="https://www.freecodecamp.org/cat-photos"></a>
--fcc-editable-region--
<img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back.">
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,62 @@
---
id: 5dfa22d1b521be39a3de7be0
title: Part 12
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Turn the words `cat photos` located inside `p` element into a link by replacing the words with the anchor element added previously. The `p` element should show the same text in the browser, but the words `cat photos` should now be a link. There should only be one link showing in the app.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your code should only contain one anchor (`a`) element. Remove any extra anchor elements.
testString: assert( document.querySelectorAll('a').length === 1 );
- text: Your anchor (`a`) element should be nested within the `p` element.
testString: assert( $('p > a').length);
- text: The link's text should be `cat photos`. You have either omitted the text or have a typo.
testString: const nestedAnchor = $('p > a')[0];
assert(
nestedAnchor.getAttribute('href') === 'https://www.freecodecamp.org/cat-photos' &&
nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos'
);
- text: After nesting the anchor (`a`) element, the only `p` element content visible in the browser should be `Click here to view more cat photos.` Double check the text, spacing, or punctuation of both the `p` and nested anchor element.
testString: |
const pText = document.querySelector('p').innerText.toLowerCase().replace(/\s+/g, ' ');
assert( pText.match(/click here to view more cat photos\.?$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
--fcc-editable-region--
<p>Click here to view more cat photos.</p>
<a href="https://www.freecodecamp.org/cat-photos">cat photos</a>
--fcc-editable-region--
<img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back.">
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,55 @@
---
id: 5dfa2407b521be39a3de7be1
title: Part 13
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Add a `target` attribute with the value `_blank` to the anchor (`a`) element's opening tag, so that the link opens in a new tab.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your `p` element should have a nested anchor (`a`) element with the text `cat photos`. You may have deleted it or have a typo.
testString: |
const anchor = $('p > a');
assert(anchor.length && anchor[0].innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat photos');
- text: Your anchor (`a`) element does not have a `target` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( document.querySelector('a').hasAttribute('target') );
- text: The value of the `target` attribute should '_blank'. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( document.querySelector('a').getAttribute('target') === '_blank' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
--fcc-editable-region--
<p>Click here to view more <a href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
--fcc-editable-region--
<img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back.">
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,63 @@
---
id: 5dfa30b9eacea3f48c6300ad
title: Part 14
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Turn the image into a link by surrounding it with necessary element tags. Use `https://www.freecodecamp.org/cat-photos` as the anchor's `href` attribute value.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You should have an `img` element with an `src` value of `https://bit.ly/fcc-relaxing-cat`. You may have accidentally deleted it.
testString: assert( document.querySelector('img') && document.querySelector('img').getAttribute('src') === 'https://bit.ly/fcc-relaxing-cat' );
- text: "Your anchor (`a`) element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelectorAll('a').length >= 2 );
- text: You should only add one opening anchor (`a`) tag. Please remove any extras.
testString: assert( document.querySelectorAll('a').length === 2 );
- text: Your anchor (`a`) element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/a>/g).length >= 2 );
- text: You should only add one closing anchor (`a`) tag. Please remove any extras.
testString: assert( code.match(/<\/a>/g).length === 2 );
- text: Your anchor (`a`) element does not have an `href` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( document.querySelector('a').hasAttribute('href') );
- text: Your anchor (`a`) element should link to `https://www.freecodecamp.org/cat-photos`. You have either omitted the URL or have a typo.
testString: assert( document.querySelectorAll('a')[1].getAttribute('href') === 'https://www.freecodecamp.org/cat-photos' );
- text: Your `img` element should be nested within the anchor (`a`) element. The entire `img` element should be inside the opening and closing tags of the anchor (`a`) element.
testString: assert( document.querySelector('img').parentNode.nodeName === "A" );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
--fcc-editable-region--
<img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back.">
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,62 @@
---
id: 5f07be6ef7412fbad0c5626b
title: Part 15
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Before adding any new content, you should make use of a `section` element to separate the cat photos content from the future content.
Take all the elements currently located within the `main` element and nest them in a `section` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `section` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelector('section') );
- text: Your `section` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/section\>/) );
- text: The entire `section` element should be between the opening and closing tags of the `main` element.
testString: assert( document.querySelector('section').parentNode.nodeName === "MAIN" );
- text: The existing `h2`, comment, `p` element, and anchor (`a`) element should be between the opening and closing tags of the `section` element.
testString: |
const childrenOfSection = [ ...document.querySelector('section').childNodes ];
const foundElems = childrenOfSection.filter(child => {
return ['H2', 'A', 'P'].includes(child.nodeName);
});
assert( foundElems.length === 3 );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
--fcc-editable-region--
<main>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</main>
--fcc-editable-region--
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,71 @@
---
id: 5f07c98cdb9413cbd4b16750
title: Part 16
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
It is time to add a new section. Add a second `section` element below the existing `section` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `section` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelectorAll('section').length >= 2 );
- text: You should only add one opening `section` tag. Please remove any extras.
testString: assert( document.querySelectorAll('section').length === 2 );
- text: Your `section` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/section>/g).length >= 2 );
- text: You should only add one closing `section` tag. Please remove any extras.
testString: assert( code.match(/<\/section>/g).length === 2 );
- text: The second `section` element should not be nested in the first `section` element.
testString: |
const childrenOf1stSection = [ ...document.querySelector('main > section').children ];
const foundElems = childrenOf1stSection.filter(child => {
return child.nodeName === 'SECTION';
});
assert( foundElems.length === 0 );
- text: Both `section` elements should be between the opening and closing tags of the `main` element.
testString: |
const childrenOfMain = [ ...document.querySelector('main').children ];
const foundElems = childrenOfMain.filter(child => {
return child.nodeName === 'SECTION';
});
assert( foundElems.length === 2 );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
--fcc-editable-region--
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,67 @@
---
id: 5dfa3589eacea3f48c6300ae
title: Part 17
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Within the second `section` element, add a new `h2` element with the text `Cat Lists`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `section` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: |
assert(
document.querySelectorAll('section').length === 2 &&
code.match(/<\/section>/g).length === 2
);
- text: "Your `h2` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelectorAll('h2').length === 2 );
- text: "Your `h2` element should have a closing tag. Closing tags have a `/` just after the `<` character."
testString: assert( code.match(/<\/h2\>/g).length === 2 );
- text: Your second `h2` element should be right above the second `section` element's closing tag. It is not in the correct position.
testString: |
const secondSection = document.querySelectorAll('section')[1];
assert( secondSection.lastElementChild.nodeName === 'H2' );
- text: The second `h2` element should have the text `Cat Lists`. You have either omitted the text or have a typo.
testString: assert( document.querySelectorAll('main > section')[1].lastElementChild.innerText.toLowerCase() === 'cat lists');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
--fcc-editable-region--
<section>
</section>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,66 @@
---
id: 5dfa371beacea3f48c6300af
title: Part 18
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
When you add a lower rank heading element to the page, it's implied that you're starting a new subsection.
After the last `h2` element of the second `section` element, add an `h3` element with the text `Things cats love:`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: The second `section` element appears to be missing or does not have both an opening and closing tag.
testString: assert( (document.querySelectorAll('main > section')[1] && code.match(/\<\/section>/g).length == 2) );
- text: There should be an `h3` element right above the second `section` element's closing tag.
testString: assert( document.querySelectorAll('main > section')[1].lastElementChild.nodeName === 'H3' );
- text: The `h3` element right above the second `section` element's closing tag should have the text `Things cats love:`. Make sure to include the colon at the end of the text.
testString: assert( document.querySelectorAll('main > section')[1].lastElementChild.innerText.toLowerCase().replace(/\s+/g, ' ') === 'things cats love:' );
- text: There should be an `h2` element with the text `Cat Lists` above the last `h3` element that is nested in the last `section` element'. You may have accidentally deleted the `h2` element.
testString: |
const secondSectionLastElemNode = document.querySelectorAll('main > section')[1].lastElementChild;
assert(
secondSectionLastElemNode.nodeName === 'H3' && secondSectionLastElemNode.previousElementSibling.innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat lists'
);
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
--fcc-editable-region--
<section>
<h2>Cat Lists</h2>
</section>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,61 @@
---
id: 5dfa37b9eacea3f48c6300b0
title: Part 19
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
After the `h3` element with the `Things cats love:` text, add an unordered list (`ul`) element. Note that nothing will be displayed at this point.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `ul` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('ul') );
- text: Your `ul` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/ul>/) );
- text: The `ul` element should be above the second `section` element's closing tag.
testString: |
const secondSectionLastElemNode = $('main > section')[1].lastElementChild;
assert( secondSectionLastElemNode.nodeName === 'UL' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
--fcc-editable-region--
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,70 @@
---
id: 5dfb5ecbeacea3f48c6300b1
title: Part 20
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Use list item (`li`) elements to create items in a list. Here is an example of list items in an unordered list:
```html
<ul>
<li>milk</li>
<li>cheese</li>
</ul>
```
Nest three list items within the `ul` element to display three things cats love: `cat nip`, `laser pointers` and `lasagna`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You should have three `li` elements. Each `li` element should have its own opening and closing tag.
testString: assert( $('li').length === 3 && code.match(/<\/li\>/g).length === 3 );
- text: You should have three `li` elements with the text `cat nip`, `laser pointers` and `lasagna` in any order. You have either omitted some text or have a typo.
testString: assert.deepStrictEqual( [ ...document.querySelectorAll('li') ].map(item => item.innerText.toLowerCase()).sort((a, b) => a.localeCompare(b)), ["cat nip", "lasagna", "laser pointers"] );
- text: The three `li` elements should be located between the `ul` element's opening and closing tags.
testString: assert( [ ...document.querySelectorAll('li') ].filter(item => item.parentNode.nodeName === 'UL').length === 3 );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
--fcc-editable-region--
<ul>
</ul>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,70 @@
---
id: 5dfb6250eacea3f48c6300b2
title: Part 21
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
After the unordered list, add a new image with an `src` attribute value set to `https://bit.ly/fcc-lasagna` and an `alt` attribute value set to `A slice of lasagna on a plate.`
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: There should be an `img` element right above the second `section` element's closing tag.
testString: assert( $('section')[1].lastElementChild.nodeName === 'IMG' );
- text: The new image either does not have an `alt` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert($('section')[1].lastElementChild.hasAttribute('alt') );
- text: The new image should have an `alt` value of `A slice of lasagna on a plate.` Make sure the `alt` attribute's value is surrounded with quotation marks.
testString: assert( $('section')[1].lastElementChild.getAttribute('alt').replace(/\s+/g, ' ').match(/^A slice of lasagna on a plate\.?$/i) );
- text: The new image does not have an `src` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert($('section')[1].lastElementChild.hasAttribute('src') );
- text: The new image should have an `src` value of `https://bit.ly/fcc-lasagna`. Make sure the `src` attribute's value is surrounded with quotation marks.
testString: assert( $('section')[1].lastElementChild.getAttribute('src') === 'https://bit.ly/fcc-lasagna');
- text: Although you have set the new image's `src` to the correct URL, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<img\s+.+\s+src\s*=\s*https:\/\/bit\.ly\/fcc-lasagna/.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
--fcc-editable-region--
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,68 @@
---
id: 5dfb655eeacea3f48c6300b3
title: Part 22
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `figure` element represents self-contained content and will allow you to associate an image with a caption.
Nest the image you just added within a `figure` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `figure` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelector('figure') );
- text: Your `figure` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/figure\>/) );
- text: There should be an `figure` element right above the second `section` element's closing tag.
testString: assert( $('section')[1].lastElementChild.nodeName === 'FIGURE' );
- text: The lasagna `img` element should be nested in the `figure` element.
testString: assert( document.querySelector('figure > img') && document.querySelector('figure > img').getAttribute('src').toLowerCase() === 'https://bit.ly/fcc-lasagna');
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
--fcc-editable-region--
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,76 @@
---
id: 5dfb6a35eacea3f48c6300b4
title: Part 23
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
A figure caption (`figcaption`) element is used to add a caption to describe the image contained withing the `figure` element. For example, `<figcaption>A cute cat</figcaption>` adds the caption `A cute cat`.
After the image nested in the `figure` element, add a `figcaption` element with the text `Cats love lasagna.`
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: The Lasagna `img` element should be nested in the `figure` element.
testString: assert( document.querySelector('figure > img') && document.querySelector('figure > img').getAttribute('src').toLowerCase() === 'https://bit.ly/fcc-lasagna');
- text: "Your `figcaption` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelector('figcaption') );
- text: Your `figcaption` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/figcaption\>/) );
- text: The `figcaption` element should be nested in the `figure` element.
testString: assert( document.querySelector('figure > figcaption') && document.querySelector('figure > figcaption'));
- text: The lasagna `img` element should be nested in the `figure` element.
testString: assert( document.querySelector('figure > img') && document.querySelector('figure > img').getAttribute('src').toLowerCase() === 'https://bit.ly/fcc-lasagna');
- text: The `figcaption` element nested in the `figure` element should be below the `img` element. You have them in the wrong order.
testString: assert( document.querySelector('figcaption').previousElementSibling.nodeName === 'IMG');
- text: Your `figcaption` element's text should be `Cats love lasagna.` You have either omitted the text or have a typo.
testString: assert( document.querySelector('figcaption').innerText.match(/Cats love lasagna.?$/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
--fcc-editable-region--
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
--fcc-editable-region--
</figure>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,71 @@
---
id: 5ef9b03c81a63668521804d0
title: Part 24
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Emphasize the word `love` in the `figcaption` element by wrapping it in an emphasis (`em`) element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your emphasis (`em`) element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('em') );
- text: Your emphasis (`em`) element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/em\>/) );
- text: You have either deleted the `figcaption` element or it is missing an opening or closing tag.
testString: assert( document.querySelector('figcaption') && code.match(/<\/figcaption\>/) );
- text: Your emphasis (`em`) element should surround the text `love`. You have either omitted the text or have a typo.
testString: assert( document.querySelector('figcaption > em').innerText.toLowerCase() === 'love' );
- text: The `figcaption`'s text should be `Cats love lasagna`. Check for typos and that the necessary spaces are present around the `em` element's opening and closing tags.
testString: assert( document.querySelector('figcaption').innerText.replace(/\s+/gi, ' ').match(/cats love lasagna\.?/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
--fcc-editable-region--
<figcaption>Cats love lasagna.</figcaption>
--fcc-editable-region--
</figure>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,71 @@
---
id: 5ef9b03c81a63668521804d1
title: Part 25
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
After the `figure` element, add another `h3` element with the text `Top 3 things cats hate:`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: There should be an `h3` element right above the second `section` element's closing tag. Make it has an opening and closing tag.
testString: assert( document.querySelectorAll('main > section')[1].lastElementChild.nodeName === 'H3' && code.match(/<\/h3\>/g).length === 2);
- text: The new `h3` element should have the text `Top 3 things cats hate:`. Make sure to include the colon at the end of the text.
testString: assert( document.querySelectorAll('main > section')[1].lastElementChild.innerText.toLowerCase().replace(/\s+/g, ' ') === 'top 3 things cats hate:' );
- text: There should be a `figure` above the new `h3` element. You may have accidentally deleted the `figure` element.
testString: |
const secondSectionLastElemNode = document.querySelectorAll('main > section')[1].lastElementChild;
assert(
secondSectionLastElemNode.nodeName === 'H3' && secondSectionLastElemNode.previousElementSibling.nodeName === 'FIGURE'
);
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
--fcc-editable-region--
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,75 @@
---
id: 5ef9b03c81a63668521804d2
title: Part 26
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The code for an ordered list (`ol`) is similar to an unordered list, but list items in an ordered list are numbered when displayed.
After the final second section' last `h3` element, add an ordered list with these three list items: `flea treatment`, `thunder` and `other cats`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `ol` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('ol') );
- text: Your `ol` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/ol>/) );
- text: The `ol` element should be above the second `section` element's closing tag. You have them in the wrong order.
testString: assert( $('main > section')[1].lastElementChild.nodeName === 'OL' );
- text: The three `li` elements should be nested inside the `ol` element.
testString: assert( [ ...document.querySelectorAll('li') ].filter(item => item.parentNode.nodeName === 'OL').length === 3);
- text: You should have three `li` elements with the text `flea treatment`, `thunder` and `other cats` in any order.
testString: assert.deepStrictEqual( [ ...document.querySelectorAll('li') ].filter(item => item.parentNode.nodeName === 'OL').map(item => item.innerText.toLowerCase()).sort((a, b) => a.localeCompare(b)), ["flea treatment", "other cats", "thunder"] );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
--fcc-editable-region--
<h3>Top 3 things cats hate:</h3>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,73 @@
---
id: 5ef9b03c81a63668521804d3
title: Part 27
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
After the ordered list, add another `figure` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `figure` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelectorAll('figure').length === 2 );
- text: Your `figure` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/figure>/g).length === 2 );
- text: There should be a `figure` element right above the second `section` element's closing tag.
testString: assert( $('main > section')[1].lastElementChild.nodeName === 'FIGURE' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
--fcc-editable-region--
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,83 @@
---
id: 5efada803cbd2bbdab94e332
title: Part 28
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Inside the `figure` element you just added, nest an `img` element with a `src` attribute set to `https://bit.ly/fcc-cats`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your second `figure` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelectorAll('figure').length === 2 );
- text: Your second `figure` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/figure>/g).length === 2 );
- text: There should be a second `figure` element right above the second `section` element's closing tag. You have them in the wrong order.
testString: assert( $('main > section')[1].lastElementChild.nodeName === 'FIGURE' );
- text: You should have a third `img` element nested in the `figure` element.
testString: const catsImg = document.querySelectorAll('figure > img')[1]; assert( catsImg && catsImg.getAttribute('src').toLowerCase() === 'https://bit.ly/fcc-cats');
- text: The third image should have an `src` attribute set to `https://bit.ly/fcc-cats`.
testString: |
const catsImg = document.querySelectorAll('figure > img')[1];
assert( catsImg && catsImg.getAttribute('src').toLowerCase() === 'https://bit.ly/fcc-cats');
- text: Although you have set the new image's `src` to the correct URL, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<img\s+.+\s+src\s*=\s*https:\/\/bit\.ly\/fcc-cats/.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
--fcc-editable-region--
<figure>
</figure>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,80 @@
---
id: 5efae0543cbd2bbdab94e333
title: Part 29
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
To improve accessibility of the image you just added, add an `alt` attribute with the text `Five cats looking around a field.`
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `figure` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelectorAll('figure').length === 2 );
- text: Your `ol` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/figure>/g).length === 2 );
- text: There should be a `figure` element right above the last `section` element's closing tag.
testString: assert( $('main > section')[1].lastElementChild.nodeName === 'FIGURE' );
- text: The Cats `img` element should be nested in the `figure` element.
testString: const catsImg = document.querySelectorAll('figure > img')[1]; assert( catsImg && catsImg.getAttribute('src').toLowerCase() === 'https://bit.ly/fcc-cats');
- text: The Cats `img` element should have an `alt` attribute with the value `Five cats looking around a field.`
testString: const catsImg = document.querySelectorAll('figure > img')[1]; assert( catsImg.getAttribute('alt').replace(/\s+/g, ' ').match(/^Five cats looking around a field\.?$/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
--fcc-editable-region--
<img src="https://bit.ly/fcc-cats">
--fcc-editable-region--
</figure>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,88 @@
---
id: 5efae16e3cbd2bbdab94e334
title: Part 30
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
After the last `img` element, add a `figcaption` element with the text `Cats hate other cats.`
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `figcaption` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelectorAll('figcaption').length === 2 );
- text: Your `figcaption` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/figcaption\>/g).length === 2 );
- text: There should be a `figure` element right above the second `section` element's closing tag.
testString: assert( $('main > section')[1].lastElementChild.nodeName === 'FIGURE' );
- text: The last `img` element should be nested in the `figure` element.
testString: const catsImg = document.querySelectorAll('figure > img')[1]; assert( catsImg && catsImg.getAttribute('src').toLowerCase() === 'https://bit.ly/fcc-cats');
- text: "Your `figure` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelectorAll('figure').length === 2 );
- text: Your `figure` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/figure\>/g).length === 2 );
- text: The `figcaption` element should be nested in the `figure` element.
testString: assert( document.querySelectorAll('figure > figcaption').length === 2);
- text: The `figcaption` element nested in the `figure` element should be below the `img` element. You have the `img` element and the `figcaption` element in the wrong order.
testString: assert( document.querySelectorAll('figcaption')[1].previousElementSibling.nodeName === 'IMG');
- text: The `figcaption` element should have the text `Cats hate other cats.` You have omitted a word or have a typo.
testString: assert( document.querySelectorAll('figcaption')[1].innerText.toLowerCase().match(/Cats hate other cats\.?$/i));
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
--fcc-editable-region--
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
--fcc-editable-region--
</figure>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,81 @@
---
id: 5ef9b03c81a63668521804d4
title: Part 31
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `strong` element is used to indicate that some text is of strong importance or urgent.
In the `figcaption` you just added, indicate that `hate` is of strong importance by wrapping it in a `strong` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `strong` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('strong') );
- text: Your strong element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/strong\>/) );
- text: Your strong element should surround the word `hate` in the text `Cats hate other cats.` You have either omitted the text or have a typo.
testString: assert( document.querySelectorAll('figcaption')[1].querySelector('strong').innerText.toLowerCase() === 'hate' );
- text: The `figcaption`'s text should be `Cats hate other cats.` Check for typos and that the necessary spaces are present around the `strong` element's opening and closing tags.
testString: const secondFigCaption = document.querySelectorAll('figcaption')[1]; assert( secondFigCaption && secondFigCaption.innerText.replace(/\s+/gi, ' ').trim().match(/cats hate other cats\.?/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
--fcc-editable-region--
<figcaption>Cats hate other cats.</figcaption>
--fcc-editable-region--
</figure>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,88 @@
---
id: 5f07fb1579dc934717801375
title: Part 32
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
It is time to add a new section. Add a third `section` element below the second `section` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `section` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelectorAll('section').length >= 3 );
- text: You should only add one opening `section` tag. Please remove any extras.
testString: assert( document.querySelectorAll('section').length === 3 );
- text: Your `section` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/section>/g).length >= 3 );
- text: You should only add one closing `section` tag. Please remove any extras.
testString: assert( code.match(/<\/section>/g).length === 3 );
- text: All of the `section` elements should be between the opening and closing tags of the `main` element.
testString: |
const childrenOfMain = [ ...document.querySelector('main').children ];
const sectionElemsFound = childrenOfMain.filter(child => {
return child.nodeName === 'SECTION';
});
assert( sectionElemsFound.length === 3 );
- text: The last `section` element should have no content. Remove any HTML elements or text within the `section` element.
testString: assert( $('main > section')[2].children.length === 0 );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
--fcc-editable-region--
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,95 @@
---
id: 5ef9b03c81a63668521804d5
title: Part 33
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Inside the third `section` element add an `h2` tag with the text `Cat Form`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Unable to find the third `section` element. You may have accidentally deleted it or the opening tag or closing tag."
testString: |
assert(
document.querySelectorAll('section').length === 3 &&
code.match(/<\/section>/g).length === 3
);
- text: Your `h2` element should have an opening tag and closing tag. You may be missing one or both of the required tags.
testString: |
assert(
document.querySelectorAll('h2').length >= 3 &&
code.match(/<\/h2>/g).length >= 3
);
- text: You should only add one `h2` element. Please remove any extras.
testString: assert( document.querySelectorAll('h2').length === 3 );
- text: The new `h2` element should be located right above the third `section` element's closing tag.
testString: |
const thirdSection = document.querySelectorAll('section')[2];
assert( thirdSection.lastElementChild.nodeName === 'H2' );
- text: Your `h2` element's text should be `Cat Form`.
testString: |
const thirdSection = document.querySelectorAll('section')[2];
assert( thirdSection.querySelector('h2').innerText.toLowerCase().replace(/\s+/g, ' ') === 'cat form' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
--fcc-editable-region--
<section>
</section>
--fcc-editable-region--
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,90 @@
---
id: 5ef9b03c81a63668521804d6
title: Part 34
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Now you will add a web form to collect information from users.
After the `Cat Form` heading, add a `form` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your `form` element should have an opening tag and closing tag. You may be missing one or both of the required tags, or have them in the wrong order.
testString: |
assert(
document.querySelector('form') &&
code.match(/<\/form>/g)
);
- text: Your `form` element tags are not in the correct order.
testString: |
const noSpaces = code.replace(/\s/g, '');
assert( noSpaces.indexOf('<form>') < noSpaces.indexOf('</form>') );
- text: The `form` element nested in the last `section` element should be below the `h2` element. You have the `h2` element and the `form` element in the wrong order.
testString: assert( document.querySelector('form').previousElementSibling.nodeName === 'H2');
- text: The `form` element should have no content. Remove any HTML elements or text between the `form` element's tags.
testString: assert( $('form')[0].innerHTML.trim().length === 0 );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
--fcc-editable-region--
<h2>Cat Form</h2>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,96 @@
---
id: 5ef9b03c81a63668521804d7
title: Part 35
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `action` attribute indicates where form data should be sent. For example, `<form action="/submit-url"></form>` tells the browser that the form data should be sent to the path `/submit-url`.
Add an `action` attribute with the value `https://freecatphotoapp.com/submit-cat-photo` to the `form` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your `form` element should have an opening tag and closing tag in the correct order. You may be missing one or both of the required tags, or have them in the wrong order.
testString: |
const noSpaces = code.replace(/\s/g, '');
assert(
document.querySelector('form') &&
code.match(/<\/form>/g) &&
noSpaces.indexOf('<form') < noSpaces.indexOf('</form>')
);
- text: Your `form` element nested in the last `section` element should be below the `h2` element. You have the `h2` element and the `form` element in the wrong order.
testString: assert( document.querySelector('form').previousElementSibling.nodeName === 'H2');
- text: Your `form` element should have no content. Remove any HTML elements or text between the `form` element's tags.
testString: assert( $('form')[0].innerHTML.trim().length === 0 );
- text: Your `form` element does not have an `action` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: const form = document.querySelector('form'); assert( form.hasAttribute('action') );
- text: Your `form` element should have an `action` attribute with the value `https://freecatphotoapp.com/submit-cat-photo`.
testString: const form = document.querySelector('form'); assert( form.getAttribute('action').match(/^https:\/\/freecatphotoapp\.com\/submit-cat-photo$/) );
- text: Although you have set the `action` attribute to the correct URL, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<form\s+action\s*=\s*https:\/\/freecatphotoapp\.com\/submit-cat-photo/.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
--fcc-editable-region--
<form>
</form>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,96 @@
---
id: 5ef9b03c81a63668521804d8
title: Part 36
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `input` element is allows you several ways to collect data from a web form. Like anchor (`a`) elements, `input` elements are <dfn>self-closing</dfn> and do not need closing tags.
Nest an `input` element in the `form` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your `form` element should have an opening tag and closing tag in the correct order. You may be missing one or both of the required tags, or have them in the wrong order.
testString: |
const noSpaces = code.replace(/\s/g, '');
assert(
document.querySelector('form') &&
code.match(/<\/form>/g) &&
noSpaces.indexOf('<form') < noSpaces.indexOf('</form>')
);
- text: Your `form` element's opening tag should only have an `action` attribute. Remove anything else you may have typed in it.
testString: assert( [...document.querySelector('form').attributes].length < 2 );
- text: You should create an input element. Check the syntax.
testString: assert( document.querySelector('input') );
- text: Your `input` element should have an opening tag, but not a closing tag.
testString: assert( document.querySelector('input') && !code.match(/<\/input\>/g) );
- text: Your `input` element should be nested within the `form` element.
testString: assert( document.querySelector('form > input') );
- text: Your `form` should only contain the `input` element. Remove any HTML elements or text between the `form` element's tags.
testString: assert( $('form')[0].children.length === 1 && $('form')[0].innerText.trim().length === 0 );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
--fcc-editable-region--
<form action="https://freecatphotoapp.com/submit-cat-photo">
</form>
--fcc-editable-region--
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,89 @@
---
id: 5efb23e70dc218d6c85f89b1
title: Part 37
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
There are many kinds of inputs you can create using the `type` attribute. You can easily create a password field, reset button, or a control to let users select a file from their computer.
Create a text field to get text input from a user by adding the `type` attribute with the value `text` to the `input` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted your `input` element or it has invalid syntax. If you have added an attributes, make sure their values are surrounded by quotation marks.
testString: assert( $('input').length );
- text: Your `form` element should only contain the `input` element. Remove any extra HTML elements or text between the `form` element's tags.
testString: assert( $('form')[0].children.length === 1 && $('form')[0].innerText.trim().length === 0 );
- text: Your `input` element does not have a `type` attribute. with the value `text`. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( $('input')[0].hasAttribute('type') );
- text: Your `input` element should have a `type` attribute with the value `text`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input')[0].getAttribute('type').replace(/\s+/g, ' ').match(/^text$/i) );
- text: Although you have set the `input` element's `type` attribute to the `text`, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<input\s+type\s*=\s*text/.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<input>
--fcc-editable-region--
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,89 @@
---
id: 7cf9b03d81a65668421804c3
title: Part 38
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
In order for a form's data to be accessed by the locaton specified in the `action` attribute, you must give the text field a `name` attribute and assign it a value to represent the data being submitted. For example, you could use the following syntax for an email address text field: `<input type="text" name="email">`.
Add the `name` attribute with the value `catphoto ` to your text field.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted your `input` element or it has invalid syntax. All attributes' values should be surrounded by quotation marks.
testString: assert( $('input').length );
- text: Your `form` should only contain the `input` element. Remove any HTML additional elements or text within the `form` element.
testString: assert( $('form')[0].children.length === 1 && $('form')[0].innerText.trim().length === 0 );
- text: Your `input` element does not have a `name` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( $('input')[0].hasAttribute('name') );
- text: Your `input` element should have a `name` attribute with the value `catphotourl`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input')[0].getAttribute('name').match(/^catphotourl$/i) );
- text: Although you have set the `input` element's `name` attribute to `catphotourl`, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<\s*input\s+.*\s*=\s*catphotourl/.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<input type="text">
--fcc-editable-region--
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,89 @@
---
id: 5ef9b03c81a63668521804d9
title: Part 39
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Placeholder text is used to give people a hint about what kind of information to enter into an input. For example, `<input type="text" placeholder="Email address">`.
Add the placeholder text `cat photo URL` to your `input` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted your `input` element or it has invalid syntax. All attributes' values should be surrounded by quotation marks.
testString: assert( $('input').length );
- text: Your `form` should only contain the `input` element. Remove any HTML additional elements or text within the `form` element.
testString: assert( $('form')[0].children.length === 1 && $('form')[0].innerText.trim().length === 0 );
- text: Your `input` element does not have a `placeholder` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( $('input')[0].hasAttribute('placeholder') );
- text: Your `input` element should have a `placeholder` attribute with the value `cat photo URL`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input')[0].getAttribute('placeholder').replace(/\s+/g, ' ').match(/^cat photo URL$/i) );
- text: Although you have set the `input` element's `placeholder` attribute to `cat photo URL`, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<\s*input\s+placeholder\s*=\s*cat\s+photo\s+url/i.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<input type="text" name="catphotourl">
--fcc-editable-region--
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,83 @@
---
id: 5ef9b03c81a63668521804db
title: Part 40
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
To prevent a user from submitting your form when required information is missing, you need to add the `required` attribute to an `input` element. There's no need to set a value to the `required` attribute. Instead, just add the word `required` to the `input` element, making sure there is space between it and other attributes.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted your `input` element or it has invalid syntax. All attributes' values should be surrounded by quotation marks.
testString: assert( $('input').length );
- text: Your `form` should only contain the `input` element. Remove any HTML additional elements or text within the `form` element.
testString: assert( $('form')[0].children.length === 1 && $('form')[0].innerText.trim().length === 0 );
- text: Your `input` element should have a `required` attribute`. Remember, you just add the word `required` inside the `input` element's tag.
testString: assert( $('input')[0].hasAttribute('required') );
- text: A value should not be given to the `required` attribute`.
testString: assert( $('input')[0].getAttribute('required') === '' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<input type="text" name="catphotourl" placeholder="cat photo URL">
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,87 @@
---
id: 5ef9b03c81a63668521804da
title: Part 41
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Use the `button` element to create a clickable button. For example, `<button>Click Here</button>` creates a button with the text `Click Here`.
Add a `button` element with the text `Submit` below the `input` element. Note the default behavior of clicking a form button with any attributes submits the form to the location specified in the form's `action` attribute.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `button` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('button') );
- text: Your `button` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/button\>/) );
- text: Your `button` element's text should be 'Submit'. You have either omitted the text or have a typo.
testString: assert( document.querySelector('button').innerText.toLowerCase() === 'submit' );
- text: Your `button` element should be below the `input` element. You have them in the wrong order.
testString: const collection = [...document.querySelectorAll('input, button')].map(node => node.nodeName); assert( collection.indexOf('INPUT') < collection.indexOf('BUTTON') );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
--fcc-editable-region--
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,90 @@
---
id: 5efb2c990dc218d6c85f89b2
title: Part 42
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Even through you added your button below the text input, they appear next to each other on the page. That's because both `input` and `button` elements are <dfn>inline elements</dfn>, which don't appear on new lines.
You learned previously that the button submits the form by default, but you can explicitly add the `type` attribute with the value `submit` to it to make it clearer. Go ahead and do this to specify this button should submit the form.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Your `button` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('button') );
- text: Your `button` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/button\>/) );
- text: Your `button` element does not have a `type` attribute. Check that there is a space after the opening tag's name.
testString: assert( $('button')[0].hasAttribute('type') );
- text: Your `button` element should have a `type` attribute with the value `submit`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('button')[0].getAttribute('type').match(/^submit$/i) );
- text: Although you have set the `button` element's `type` attribute to `submit`, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<\s*button\s+type\s*=\s*submit/i.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
--fcc-editable-region--
<button>Submit</button>
--fcc-editable-region--
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,108 @@
---
id: 5ef9b03c81a63668521804dc
title: Part 43
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
You can use radio buttons for questions where you want only one answer out of multiple options.
Here is an example of a radio button with the option of `cat`: `<input type="radio"> cat`. Remember that `input` elements are <dfn>self-closing</dfn>.
Before the text input, add a radio button with the option `Indoor`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You should create an input element for your radio button. Check the syntax.
testString: assert( $('form > input').length >= 2 );
- text: Your `input` element should have an opening tag, but not a closing tag.
testString: assert( $('form > input') && !code.match(/<\/input\>/g) );
- text: You should only have added one input element for your radio button. Remove any extras.
testString: assert( $('form > input').length === 2 );
- text: Your new `input` element should be above the existing `input` with `type` attribute set to `text`. You have them in the wrong order.
testString: |
const existingInputElem = document.querySelector('form > input[type="text"]');
assert(
existingInputElem && existingInputElem.previousElementSibling.nodeName === 'INPUT'
);
- text: Your new `input` element does not have a `type` attribute. Check that there is a space after the opening tag's name.
testString: assert( $('input')[0].hasAttribute('type') );
- text: Your new `input` element should have a `type` attribute with the value `radio`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input')[0].getAttribute('type').match(/^radio$/i) );
- text: Although you have set the new `input` element's `type` attribute to `radio`, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<\s*input\s+type\s*=\s*radio/i.test(code) );
- text: The `radio` button's ` Indoor` text should be located after it instead of before it.
testString: |
const radioInputElem = $('input')[0];
assert( !radioInputElem.previousSibling.nodeValue.match(/Indoor/i) );
- text: The text ` Indoor` should be located directly to the right of your `radio` button. Make sure there is a space between the element and the text. You have either omitted the text or have a typo.
testString: |
const radioInputElem = $('input')[0];
assert( radioInputElem.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Indoor/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
--fcc-editable-region--
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,95 @@
---
id: 5ef9b03c81a63668521804dd
title: Part 44
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
`label` elements are used to help associate the text for an `input` element with the input element itself (especially for assistive technologies like screen readers). For example, `<label><input type="radio"> cat</label>` makes it so clicking the word `cat` also selects the corresponding radio button.
Nest your `radio` button inside a `label` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You should make sure the radio button is still present.
testString: assert( $('input[type="radio"]')[0] );
- text: The text ` Indoor` should be located directly to the right of your `radio` button. Make sure there is a space between the element and the text. You have either omitted the text or have a typo.
testString: |
const radioInputElem = $('input')[0];
assert( radioInputElem.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Indoor/i) );
- text: 'Your `label` element should have an opening tag. Opening tags have this syntax: `<elementName>`.'
testString: assert( document.querySelector('label') );
- text: Your `label` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/label\>/) );
- text: Your radio button and its text should all be located between the opening and closing tags of the `label` element.
testString: |
const labelChildNodes = [ ...$('form > label')[0].childNodes ];
assert( labelChildNodes.filter(childNode => childNode.nodeName === "INPUT").length );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<input type="radio"> Indoor
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,89 @@
---
id: 5ef9b03c81a63668521804df
title: Part 45
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `id` attribute is used to identify specific HTML elements. Each `id` attribute's value must be unique all other `id` values for the entire page.
Add an `id` attribute with the value `indoor` to the radio button. When elements have multiple attributes, the order of the attributes doesn't matter.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your radio button should still be located between the opening and closing tags of the `label` element.
testString: |
const labelChildNodes = [ ...$('form > label')[0].childNodes ];
assert( labelChildNodes.filter(childNode => childNode.nodeName === "INPUT").length );
- text: Your radio button should have an `id` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( $('input')[0].hasAttribute('id') );
- text: Your radio element should have an `id` attribute with the value `indoor`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input')[0].id.match(/^indoor$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<label><input type="radio"> Indoor</label>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,93 @@
---
id: 5f05a1d8e233dff4a68508d8
title: Part 46
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Nest a another radio button with the option `Outdoor` in a new `label` element. The new radio button should be placed after the first one. Also, set its `id` attribute value to `outdoor`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You will need to add a new `label` element in which to nest your new radio button. Make sure it has both an opening and closing tag.
testString: assert( document.querySelectorAll('label').length === 2 && code.match(/<\/label\>/g).length === 2 );
- text: The text ` Outdoor` should be located directly to the right of your new `radio` button. Make sure there is a space between the element and the text. You have either omitted the text or have a typo.
testString: |
const radioButtons = [ ...$('input')];
assert( radioButtons.filter(btn => btn.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Outdoor/i)).length );
- text: Your new radio button and associated label should be below the first one. You have them in the wrong order.
testString: |
const collection = [...document.querySelectorAll('input[type="radio"]')].map(node => node.nextSibling.nodeValue.replace(/\s+/g, ''));
assert( collection.indexOf('Indoor') < collection.indexOf('Outdoor') );
- text: Your new radio button should have an `id` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( $('input')[1].hasAttribute('id') );
- text: Your new radio element should have an `id` attribute with the value `outdoor`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input')[1].id.match(/^outdoor$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<label><input id="indoor" type="radio"> Indoor</label>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,93 @@
---
id: 5ef9b03c81a63668521804de
title: Part 47
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Notice that both radio buttons can be selected at the same time. To make it so selecting one radio button automatically deselects the other, both buttons must have a `name` attribute with the same value.
Add the `name` attribute with the value `indoor-outdoor` to both radio buttons.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Both radio buttons should still be located between opening and closing `label` element tags.
testString: |
const labelChildNodes = [ ...document.querySelectorAll('form > label') ].map(node => node.childNodes);
assert( labelChildNodes.filter(childNode => childNode[0].nodeName === "INPUT").length === 2 );
- text: Both radio buttons should have a `name` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: |
const radioButtons = [...document.querySelectorAll('input[type="radio"]')];
assert( radioButtons.every(btn => btn.hasAttribute('name')) );
- text: Both radio buttons should have a `name` attribute with the value `indoor-outdoor`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: |
const radioButtons = [ ...$('input[type="radio"]') ];
assert( radioButtons.every(btn => btn.getAttribute('name').match(/^indoor-outdoor$/)) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<label><input id="indoor" type="radio"> Indoor</label>
<label><input id="outdoor" type="radio"> Outdoor</label>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,97 @@
---
id: 5f1a80975fc4bcae0edb3497
title: Part 48
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
If you select the `Indoor` radio button and submit the form, the form data for the button is based on its `name` and `value` attributes. Since your radio buttons do not have a `value` attribute, the form data will include `indoor-outdoor=on`, which is not useful when you have multiple buttons.
Add a `value` attribute to both radio buttons. For convenience, set the button's `value` attribute to the same value as its `id` attribute.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Both radio buttons should still be located between opening and closing `label` element tags.
testString: |
const labelChildNodes = [ ...document.querySelectorAll('form > label') ].map(node => node.childNodes);
assert( labelChildNodes.filter(childNode => childNode[0].nodeName === "INPUT").length === 2 );
- text: Both radio buttons should have a `value` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: |
const radioButtons = [...document.querySelectorAll('input[type="radio"]')];
assert( radioButtons.every(btn => btn.hasAttribute('value')) );
- text: The `Indoor` radio button's `value` attribute should be set to `indoor`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: |
const indoorRadioButton = document.querySelector('#indoor');
assert( indoorRadioButton.getAttribute('value').match(/^indoor$/) );
- text: The `Outdoor` radio button's `value` attribute should be set to `outdoor`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: |
const outdoorRadioButton = document.querySelector('#outdoor');
assert( outdoorRadioButton.getAttribute('value').match(/^outdoor$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<label><input id="indoor" type="radio" name="indoor-outdoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor"> Outdoor</label>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,94 @@
---
id: 5ef9b03c81a63668521804e1
title: Part 49
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `fieldset` element is used to group related inputs and labels together in a web form. `fieldset` elements are <dfn>block-level elements</dfn>, meaning that they appear on a new line.
Nest the `Indoor` and `Outdoor` radio buttons within a `fieldset` element, and don't forget to indent the buttons.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Both radio buttons should still be located between opening and closing `label` element tags.
testString: |
const labelChildNodes = [ ...$('label') ].map(node => [ ...node.childNodes ]);
assert( labelChildNodes.filter(childNode => childNode[0].nodeName === "INPUT").length === 2 );
- text: "Your `fieldset` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelector('fieldset') );
- text: Your `fieldset` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/fieldset\>/) );
- text: Both radio button and associated labels should be between the opening and closing tags of the `fieldset` element.
testString: |
const radioButtons = [ ...$('input[type="radio"]') ];
assert( radioButtons.every(btn => btn.parentNode.parentNode.nodeName === "FIELDSET") );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,102 @@
---
id: 5f0d48e7b435f13ab6550051
title: Part 50
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `legend` element acts as a caption for the content in the `fieldset` element. It gives users context about what they should enter into that part of the form.
Add a `legend` element with the text `Is your cat an indoor or outdoor cat?` above both of the radio buttons.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your `legend` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelector('legend') );
- text: Your `legend` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/legend\>/) );
- text: Your `legend` element should be the first element right below `fieldset` element's opening tag and before the first radio button's opening `label` tag. It is not in the correct position.
testString: |
const fieldsetElem = document.querySelector('fieldset');
const fieldsetElemChildren = fieldsetElem.children;
assert(
fieldsetElem.firstElementChild.nodeName === 'LEGEND' &&
fieldsetElemChildren[1].nodeName === 'LABEL' &&
fieldsetElemChildren[1].children[0].nodeName === 'INPUT' &&
fieldsetElemChildren[1].children[0].id === 'indoor'
);
- text: "Your `legend` element's text should be `Is your cat an indoor or outdoor cat?`. You have either omitted the text, have a typo, or it is not between the `legend` element's opening and closing tags."
testString: |
const extraSpacesRemoved = document.querySelector('legend').innerText.replace(/\s+/g, ' ');
assert( extraSpacesRemoved.match(/Is your cat an indoor or outdoor cat\??$/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
--fcc-editable-region--
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
--fcc-editable-region--
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,112 @@
---
id: 5f0d4ab1b435f13ab6550052
title: Part 51
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Next, you are going to add some new form `input` elements, so add another `fieldset` element directly below the current `fieldset` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: "Your new `fieldset` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: assert( document.querySelectorAll('fieldset').length >= 2 );
- text: You should only add one opening `fieldset` tag. Please remove any extras.
testString: assert( document.querySelectorAll('fieldset').length === 2 );
- text: Your new `fieldset` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/fieldset>/g).length >= 2 );
- text: You should only add one closing `fieldset` tag. Please remove any extras.
testString: assert( code.match(/<\/fieldset>/g).length === 2 );
- text: The second `fieldset` element should not be nested in the first `fieldset` element.
testString: |
const childrenOf1stFieldset = [ ...document.querySelector('form > fieldset').children ];
const foundElems = childrenOf1stFieldset.filter(child => {
return child.nodeName === 'FIELDSET';
});
assert( foundElems.length === 0 );
- text: Both `fieldset` elements should be above the text field and its associated `label` element. They are out of order.
testString: |
const formChildren = $('form')[0].children;
assert(
formChildren[0].nodeName === 'FIELDSET' &&
formChildren[1].nodeName === 'FIELDSET' &&
formChildren[2] && formChildren[2].nodeName === 'INPUT' &&
formChildren[2].getAttribute('type') === 'text'
);
- text: Your new `fieldset` element should be below the existing `fieldset` element. You have them in the wrong order.
testString: |
const fieldsetChildren = [...document.querySelectorAll('fieldset')].map(elem => elem.children);
assert( fieldsetChildren[0].length > fieldsetChildren
[1].length );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
--fcc-editable-region--
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,105 @@
---
id: 5f0d4d04b435f13ab6550053
title: Part 52
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Add a `legend` element with the text `What's your cat's personality?` inside the second `fieldset` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted the second `fieldset` element or it is missing an opening tag or closing tag."
testString: |
assert(
document.querySelectorAll('fieldset').length === 2 &&
code.match(/<\/fieldset>/g).length === 2
);
- text: "Your `legend` element should have an opening tag. Opening tags have this syntax: `<elementName>`."
testString: |
const secondFieldset = $('fieldset')[1];
assert( secondFieldset && [ ...secondFieldset.children ].filter(child => child.nodeName === 'LEGEND').length );
- text: "Your `legend` element should have a closing tag. Closing tags have a `/` just after the `<` character."
testString: assert( code.match(/<\/legend\>/g).length === 2 );
- text: The `legend` element should have the text `What's your cat's personality?`. You have either omitted the text or have a typo.
testString: |
const secondFieldset = $('fieldset')[1];
assert(
secondFieldset && [ ...secondFieldset.children ].filter(child => {
const extraSpacesRemoved = child.innerText.replace(/\s+/g, ' ');
return child.nodeName === 'LEGEND' && extraSpacesRemoved.match(/What's your cat's personality\??$/i) ;
}).length
);
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
--fcc-editable-region--
<fieldset>
</fieldset>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,108 @@
---
id: 5ef9b03c81a63668521804e2
title: Part 53
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Forms commonly use checkboxes for questions that may have more than one answer. For example, here's a checkbox with the option of `tacos`: `<input type="checkbox"> tacos`.
Under the `legend` element you just added, add an `input` with its `type` attribute set to `checkbox` and give it the option of `Loving`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: The `input` element for your checkbox should have an opening tag, but not a closing tag.
testString: assert( $('fieldset > input') && !code.match(/<\/input\>/g) );
- text: You should only have added one input element for your checkbox. Remove any extras.
testString: assert( $('fieldset > input').length === 1 );
- text: Your new `input` element should be below the `legend` element with the text `What's your cat's personality?`. You have them in the wrong order.
testString: |
const existingLegendElem = $('fieldset > legend')[1];
assert(
existingLegendElem && existingLegendElem.nextElementSibling.nodeName === 'INPUT'
);
- text: Your new `input` element does not have a `type` attribute. Check that there is a space after the opening tag's name.
testString: assert( $('fieldset > input')[0].hasAttribute('type') );
- text: Your new `input` element should have a `type` attribute with the value `checkbox`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('fieldset > input')[0].getAttribute('type').match(/^checkbox$/i) );
- text: Although you have set the new `input` element's `type` attribute to `checkbox`, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<\s*input\s+type\s*=\s*checkbox/i.test(code) );
- text: The text ` Loving` should be located directly to the right of your checkbox. Make sure there is a space between the element and the text. You have either omitted the text or have a typo.
testString: |
const checkboxInputElem = $('input[type="checkbox"]')[0];
assert( checkboxInputElem.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Loving/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
--fcc-editable-region--
<legend>What's your cat's personality?</legend>
--fcc-editable-region--
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,90 @@
---
id: 5efc54138d6a74d05e68af76
title: Part 54
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Add an `id` attribute with the value `loving` to the checkbox input.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your checkbox should have an `id` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: assert( $('input[type="checkbox"]')[0].hasAttribute('id') );
- text: Your checkbox should have an `id` attribute with the value `loving`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input[type="checkbox"]')[0].id.match(/^loving$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
--fcc-editable-region--
<input type="checkbox"> Loving
--fcc-editable-region--
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,115 @@
---
id: 5efc4f528d6a74d05e68af74
title: Part 55
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
There's another way to associate an `input` element's text with the element itself. You can nest the text within a `label` element and add a `for` attribute with the same value as the `input` element's `id` attribute.
Associate the text `Loving` with the checkbox by only nesting the text `Loving` in a `label` element and place it to the right side of the checkbox `input` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You should make sure the checkbox is still present.
testString: assert( $('input[type="checkbox"]')[0] );
- text: Your checkbox should still have an `id` attribute with the value `loving`. You may have removed the attribute or changed its value.
testString: assert( $('input[type="checkbox"]')[0].id === 'loving' );
- text: The text ` Loving` should no longer be located directly to the right of your checkbox. It should be wrapped in a `label` element.
testString: |
const checkboxInputElem = $('input[type="checkbox"]')[0];
assert( !checkboxInputElem.nextSibling.nodeValue.replace(/\s+/g, ' ').match(/ Loving/i) );
- text: You will need to add a new `label` element in which to nest the text `Loving`. Make sure it has both an opening and closing tag.
testString: assert( document.querySelectorAll('label').length === 3 && code.match(/<\/label\>/g).length === 3 );
- text: The new `label` element should be located directly to the right of your checkbox. Make sure there is a space between the two elements.
testString: |
const checkboxInputElem = $('input[type="checkbox"]')[0];
assert( checkboxInputElem.nextElementSibling.nodeName === 'LABEL' );
- text: The new `label` element does not have a `for` attribute. Check that there is a space after the opening tag's name.
testString: |
const labelElem = $('input[type="checkbox"]')[0].nextElementSibling;
assert( labelElem.hasAttribute('for') );
- text: The new `label` element should have a `for` attribute with the value `loving`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: |
const labelElem = $('input[type="checkbox"]')[0].nextElementSibling;
assert( labelElem.getAttribute('for').match(/^loving$/) );
- text: The text `Loving` should be nested within the new `label` element. You have either omitted the text or have a typo.
testString: |
const labelElem = document.querySelector('label[for="loving"]');
assert( labelElem.textContent.replace(/\s/g, '').match(/Loving/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
--fcc-editable-region--
<input id="loving" type="checkbox"> Loving
--fcc-editable-region--
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,95 @@
---
id: 5efc518e8d6a74d05e68af75
title: Part 56
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Add the `name` attribute with the value `personality` to the checkbox `input` element.
While you won't notice this in the browser, doing this makes it easier for a server to process your web form, especially when there are multiple checkboxes.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You should make sure the checkbox is still present.
testString: assert( $('input[type="checkbox"]')[0] );
- text: The checkbox `input` element does not have a `name` attribute. Check that there is a space after the opening tag's name.
testString: assert( $('input[type="checkbox"]')[0].hasAttribute('name') );
- text: The checkbox `input` element should have a `name` attribute with the value `personality`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: assert( $('input[type="checkbox"]')[0].getAttribute('name').match(/^personality$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
--fcc-editable-region--
<input id="loving" type="checkbox"> <label for="loving">Loving</label>
--fcc-editable-region--
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,105 @@
---
id: 5ef9b03c81a63668521804e3
title: Part 57
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Add another checkbox after the one you just added. The `id` attribute value should be `lazy` and the `name` attribute value should be the same as the last checkbox.
Also add a `label` element to the right of the new checkbox with the text `Lazy`. Make sure to associate the `label` element with the new checkbox using the `for` attribute.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You need to add a new checkbox.
testString: assert( $('input[type="checkbox"]').length === 2 );
- text: Your new checkbox should have an `id` attribute with the value `lazy` and a `name` attribute with the value `personality`. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: |
const checkboxes = [ ...$('input[type="checkbox"]') ];
assert( checkboxes.some(checkbox => checkbox.id === 'lazy' && checkbox.getAttribute('name') === 'personality') );
- text: Your new checkbox should be after the first one. You have them in the wrong order.
testString: |
const checkboxes = [...$('input[type="checkbox"]')].map(checkbox => checkbox.id);
assert( checkboxes.indexOf('loving') < checkboxes.indexOf('lazy') );
- text: On the right side of your new checkbox, there should be `label` element with the text `Lazy`.
testString: |
const nextElementSibling = $('input[type="checkbox"]')[1].nextElementSibling;
assert( nextElementSibling.nodeName === 'LABEL' && nextElementSibling.innerText.replace(/\s+/g, '').match(/^Lazy$/i) );
- text: The new `label` should have a `for` attribute with the same value as the `id` attribute of the new checkbox. You have either omitted the value or have a typo.
testString: assert( $('input[type="checkbox"]')[1].nextElementSibling.getAttribute('for') === 'lazy' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
--fcc-editable-region--
<input id="loving" type="checkbox" name="personality"> <label for="loving">Loving</label>
--fcc-editable-region--
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,106 @@
---
id: 5efc575c8d6a74d05e68af77
title: Part 58
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Add a final checkbox after the previous one with an `id` attribute value of `energetic`. The `name` and attribute should be the same as the last checkbox.
Also add a `label` element to the right of the new checkbox with text `Energetic`. Make sure to associate the `label` element with the new checkbox.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You need to add a new checkbox.
testString: assert( $('input[type="checkbox"]').length === 3 );
- text: Your new checkbox should have an `id` attribute with the value `energetic` and a `name` attribute with the value `personality`. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: |
const checkboxes = [ ...$('input[type="checkbox"]') ];
assert( checkboxes.some(checkbox => checkbox.id === 'energetic' && checkbox.getAttribute('name') === 'personality') );
- text: Your new checkbox should be after the first one. You have them in the wrong order.
testString: |
const checkboxes = [...$('input[type="checkbox"]')].map(checkbox => checkbox.id);
assert( checkboxes.indexOf('lazy') < checkboxes.indexOf('energetic') );
- text: On the right side of your new checkbox, there should be `label` element with the text `Energetic`.
testString: |
const nextElementSibling = $('input[type="checkbox"]')[2].nextElementSibling;
assert( nextElementSibling.nodeName === 'LABEL' && nextElementSibling.innerText.replace(/\s+/g, '').match(/^Energetic$/i) );
- text: The new `label` should have a `for` attribute with the same value as the `id` attribute of the new checkbox. You have either omitted the value or have a typo.
testString: assert( $('input[type="checkbox"]')[2].nextElementSibling.getAttribute('for') === 'energetic' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
--fcc-editable-region--
<input id="loving" type="checkbox" name="personality"> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality"> <label for="lazy">Lazy</label>
--fcc-editable-region--
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,107 @@
---
id: 5f1a89f1190aff21ae42105a
title: Part 59
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Like radio buttons, form data for selected checkboxes are `name` / `value` attribute pairs. While the `value` attribute is optional, it's best practice to include it with any checkboxes or radio buttons on the page.
Add a `value` attribute to each checkbox. For convenience, set each checkbox's `value` attribute to the same value as its `id` attribute.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: All three checkboxes should have a `value` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names.
testString: |
const checkboxes = [...document.querySelectorAll('input[type="checkbox"]')];
assert( checkboxes.every(checkbox => checkbox.hasAttribute('value')) );
- text: The `value` attribute of the `Loving` checkbox should be set to `loving`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: |
const lovingCheckbox = document.querySelector('#loving');
assert( lovingCheckbox.getAttribute('value').match(/^loving$/) );
- text: The `value` attribute of the `Lazy` checkbox should be set to `lazy`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: |
const lazyCheckbox = document.querySelector('#lazy');
assert( lazyCheckbox.getAttribute('value').match(/^lazy$/) );
- text: The `value` attribute of the `Energetic` checkbox should be set to `energetic`. You have either omitted the value or have a typo. Remember that attribute values should be surrounded with quotation marks.
testString: |
const energeticCheckbox = document.querySelector('#energetic');
assert( energeticCheckbox.getAttribute('value').match(/^energetic$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality"> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality"> <label for="energetic"> Energetic</label>
</fieldset>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,103 @@
---
id: 5ef9b03c81a63668521804e5
title: Part 60
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
In order to make a checkbox checked or radio button selected by default, you need to add the `checked` attribute to it. There's no need to set a value to the `checked` attribute. Instead, just add the word `checked` to the `input` element, making sure there is space between it and other attributes.
Make the first radio button and the first checkbox selected by default.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Make sure there still are two radio buttons and three checkboxes nested in their respective `fieldset` elements.
testString: assert( $('input[type="radio"]').length === 2 && $('fieldset > input[type="checkbox"]').length === 3 );
- text: The first radio button is missing the `checked` attribute.
testString: assert( $('input[type="radio"]')[0].hasAttribute('checked') );
- text: The second radio button should not have the `checked` attribute.
testString: assert( !$('input[type="radio"]')[1].hasAttribute('checked') );
- text: The first checkbox is missing the `checked` attribute.
testString: assert( $('input[type="checkbox"]')[0].hasAttribute('checked') );
- text: The second checkbox should not have the `checked` attribute.
testString: assert( !$('input[type="checkbox"]')[1].hasAttribute('checked') );
- text: The third checkbox should not have the `checked` attribute.
testString: assert( !$('input[type="checkbox"]')[2].hasAttribute('checked') );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
--fcc-editable-region--
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving"> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic"> Energetic</label>
</fieldset>
--fcc-editable-region--
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,99 @@
---
id: 5ef9b03c81a63668521804e7
title: Part 61
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Now you will add a footer section to the page.
After the `main` element, add a `footer` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted the `main` element or it is missing an opening tag or closing tag."
testString: assert( document.querySelector('main') && code.match(/<\/main>/) );
- text: "Your `footer` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( document.querySelector('footer') );
- text: Your `footer` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/<\/footer\>/) );
- text: Your `footer` element should the below the closing `main` element tag. You have it put it somewhere else.
testString: assert( document.querySelector('main').nextElementSibling.nodeName === 'FOOTER' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
--fcc-editable-region--
</main>
</body>
</html>
--fcc-editable-region--
```
</div>
</section>

View File

@ -0,0 +1,102 @@
---
id: 5ef9b03c81a63668521804e8
title: Part 62
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Nest a `p` element with the text `No Copyright - freeCodeCamp.org` within the `footer` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted the `footer` element or it is missing an opening tag or closing tag."
testString: assert( document.querySelector('footer') && code.match(/<\/footer>/) );
- text: Your `footer` element should have a `p` element. Make sure to added an opening tag and closing tag for the `p` element.
testString: assert( document.querySelector('footer > p') );
- text: Your `footer` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: |
const pElemClosingTags = code.match(/<\/p\>/g);
assert( pElemClosingTags && pElemClosingTags.length === 2);
- text: "Your `p` element's text should be `No Copyright - freeCodeCamp.org`. You have either omitted the text, have a typo, or it is not between the `legend` element's opening and closing tags."
testString: |
const extraSpacesRemoved = $('footer > p')[0].innerText.replace(/\s+/g, ' ');
assert( extraSpacesRemoved.match(/No Copyright - freeCodeCamp\.org$/i) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
--fcc-editable-region--
<footer>
</footer>
--fcc-editable-region--
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,112 @@
---
id: 5ef9b03c81a63668521804e9
title: Part 63
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Make the text `freeCodeCamp.org` into a link by enclosing it in an anchor (`a`) element. The `href` attribute should be set to `https://www.freecodecamp.org`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your anchor (`a`) element should be nested within the `footer` element. Make sure to added an opening tag and closing tag for the anchor (`a`) element.
testString: assert( $('footer > p > a').length );
- text: Your anchor (`a`) element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: |
const aElemClosingTags = code.match(/<\/a\>/g);
assert( aElemClosingTags && aElemClosingTags.length === 3);
- text: Your anchor (`a`) element should have an `href` attribute with the value `https://www.freecodecamp.org`. You may have omitted the attribute/value, or have a typo.
testString: |
const nestedAnchor = $('footer > p > a')[0];
assert( nestedAnchor.getAttribute('href') === 'https://www.freecodecamp.org' );
- text: The link's text should be `freeCodeCamp.org`. You have either omitted the text or have a typo.
testString: |
const nestedAnchor = $('footer > p > a')[0];
assert( nestedAnchor.innerText.toLowerCase().replace(/\s+/g, ' ') === 'freecodecamp.org');
- text: After nesting the anchor (`a`) element, the only `p` element content visible in the browser should be `No Copyright - freeCodeCamp.org`. Double check the text, spacing, or punctuation of both the `p` and nested anchor element.
testString: |
const pText = $('footer > p')[0].innerText.toLowerCase().replace(/\s+/g, ' ');
assert( pText.match(/^no copyright - freecodecamp.org$/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
<footer>
<p>
--fcc-editable-region--
No Copyright - freeCodeCamp.org
--fcc-editable-region--
</p>
</footer>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,106 @@
---
id: 5ef9b03c81a63668521804ea
title: Part 64
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Notice that everything you've added to the page so far is inside the `body` element. All page content elements that should be rendered to the page go inside the `body` element. However, other important information goes inside the `head` element.
Add a `head` element just above the `body` element.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted the `body` element or it is missing an opening tag or closing tag.
testString: assert( document.querySelector('body') && code.match(/<\/body>/) );
- text: "Your `head` element should have an opening tag. Opening tags have the following syntax: `<elementName>`."
testString: assert( code.match(/\<head\>/) );
- text: Your `head` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: assert( code.match(/\<\/head\>/) );
- text: Your `head` element should be above the opening `body` element tag. You have it put it somewhere else.
testString: |
const noSpaces = code.replace(/\s/g, '');
assert( noSpaces.match(/\<\/head\>\<body\>/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
--fcc-editable-region--
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
<footer>
<p>
No Copyright - <a href="https://www.freecodecamp.org">freeCodeCamp.org</a>
</p>
</footer>
</body>
--fcc-editable-region--
</html>
```
</div>
</section>

View File

@ -0,0 +1,109 @@
---
id: 5ef9b03c81a63668521804eb
title: Part 65
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
The `title` element determines what browsers show in the title bar or tab for the page.
Add a `title` element within the `head` element. Its text should be `CatPhotoApp`.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted the `head` element or it is missing an opening tag or closing tag.
testString: assert( code.match(/\<head\>/) && code.match(/\<\/head\>/) );
- text: Your `title` element should be nested in the `head` element. Make sure to added an opening tag and closing tag for the `title` element.
testString: |
const noSpaces = code.replace(/\s/g, '');
assert( noSpaces.match(/\<head\>\<title\>.*\<\/title\>\<\/head\>/) );
- text: Your `title` element should have a closing tag. Closing tags have a `/` just after the `<` character.
testString: |
assert( code.match(/\<\/title\>/) );
- text: Your `title` element's text should be `CatPhotoApp`. You have either omitted the text or have a typo.
testString: assert( document.title && document.title.toLowerCase() === 'catphotoapp' );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
<html>
--fcc-editable-region--
<head>
</head>
--fcc-editable-region--
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
<footer>
<p>
No Copyright - <a href="https://www.freecodecamp.org">freeCodeCamp.org</a>
</p>
</footer>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,107 @@
---
id: 5ef9b03c81a63668521804ec
title: Part 66
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
Notice that the entire contents of the page are nested within an `html` element. All other elements must be descendants of this `html` element.
Add the `lang` attribute with the value `en` to the opening `html` tag to specify that the language of the page is English.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: You have either deleted the `html` element or it is missing an opening tag or closing tag.
testString: assert( code.match(/\<html.*?\>/) && code.match(/\<\/html\>/) );
- text: Your `html` element should have a `lang` attribute with the value `en`. You may have omitted the attribute/value, or have a typo.
testString: |
const extraSpacesRemoved = code.replace(/\s+/g, ' ');
assert( extraSpacesRemoved.match(/\<html lang\=("|')([a-z]+)\1\>/) );
- text: Although you have set the `html` element's `lang` attribute to `en`, it is recommended to always surround the value of an attribute with quotation marks.
testString: assert( !/\<\s*html\s+lang\s*=en/i.test(code) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
--fcc-editable-region--
<html>
--fcc-editable-region--
<head>
<title>CatPhotoApp</title>
</head>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
<footer>
<p>
No Copyright - <a href="https://www.freecodecamp.org">freeCodeCamp.org</a>
</p>
</footer>
</body>
</html>
```
</div>
</section>

View File

@ -0,0 +1,176 @@
---
id: 5ef9b03c81a63668521804ee
title: Part 67
challengeType: 0
isHidden: true
---
## Description
<section id='description'>
All pages should begin with `<!DOCTYPE html>`. This special string is known as a <dfn>declaration</dfn> and ensures the browser tries to meet industry-wide specifications.
To complete this project, add this declaration as the first line of the code.
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: Your code should begin with the declaration `<!DOCTYPE html>`. You may have omitted the declaration, have a typo, or it is not the first line of code.
testString: assert( code.match(/\<\s*!DOCTYPE\s+html\s*\>/) );
- text: Your `<!DOCTYPE html>` must be located at the top of the document.
testString: |
const noSpaces = code.replace(/\s/g, '');
assert( noSpaces.match(/^\<\!DOCTYPEhtml\>\<html/) );
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```html
--fcc-editable-region--
<html lang="en">
<head>
<title>CatPhotoApp</title>
</head>
--fcc-editable-region--
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked> <label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy"> <label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic"> <label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
<footer>
<p>
No Copyright - <a href="https://www.freecodecamp.org">freeCodeCamp.org</a>
</p>
</footer>
</body>
</html>
```
</div>
</section>
## Solution
<section id='solution'>
```html
<!DOCTYPE html>
<html lang="en">
<head>
<title>CatPhotoApp</title>
</head>
<body>
<h1>CatPhotoApp</h1>
<main>
<section>
<h2>Cat Photos</h2>
<!-- TODO: Add link to cat photos -->
<p>Click here to view more <a target="_blank" href="https://www.freecodecamp.org/cat-photos">cat photos</a>.</p>
<a href="https://www.freecodecamp.org/cat-photos"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying on its back."></a>
</section>
<section>
<h2>Cat Lists</h2>
<h3>Things cats love:</h3>
<ul>
<li>cat nip</li>
<li>laser pointers</li>
<li>lasagna</li>
</ul>
<figure>
<img src="https://bit.ly/fcc-lasagna" alt="A slice of lasagna on a plate.">
<figcaption>Cats <em>love</em> lasagna.</figcaption>
</figure>
<h3>Top 3 things cats hate:</h3>
<ol>
<li>flea treatment</li>
<li>thunder</li>
<li>other cats</li>
</ol>
<figure>
<img src="https://bit.ly/fcc-cats" alt="Five cats looking around a field.">
<figcaption>Cats <strong>hate</strong> other cats.</figcaption>
</figure>
</section>
<section>
<h2>Cat Form</h2>
<form action="https://freecatphotoapp.com/submit-cat-photo">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
<label><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<label for="loving"><input id="loving" type="checkbox" name="personality" value="loving" checked> Loving</label>
<label for="lazy"><input id="lazy" type="checkbox" name="personality" value="lazy"> Lazy</label>
<label for="energetic"><input id="energetic" type="checkbox" name="personality" value="energetic"> Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
</section>
</main>
<footer>
<p>
No Copyright - <a href="https://www.freecodecamp.org">freeCodeCamp.org</a>
</p>
</footer>
</body>
</html>
```
</section>

View File

@ -19,10 +19,9 @@ class ChallengeTitles {
const isKnown = this.knownTitles.includes(titleToCheck);
if (isKnown) {
throw new Error(`
All current curriculum challenges must have a unique title.
The title ${title} (at ${pathAndTitle}) is already assigned
`);
All current curriculum challenges must have a unique title.
The title ${title} (at ${pathAndTitle}) is already assigned
`);
}
this.knownTitles = [...this.knownTitles, titleToCheck];
}

View File

@ -18,6 +18,7 @@ const preFormattedBlockNames = {
'machine-learning-with-python': 'Machine Learning with Python',
tensorflow: 'TensorFlow',
'basic-javascript-rpg-game': 'Basic JavaScript RPG Game',
'basic-html-cat-photo-app': 'HTML Cat Photo App',
'css-variables-skyline': 'CSS Variables Skyline',
'javascript-spreadsheet': 'JavaScript Spreadsheet',
'intermediate-javascript-calorie-counter':