feat(curriculum): add contact form lab (#56270)

Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>
Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
This commit is contained in:
Zaira
2024-10-02 08:10:31 -07:00
committed by GitHub
co-authored by Tom Ilenia
parent 587fa0c1d7
commit 3d9ffa5cff
4 changed files with 481 additions and 1 deletions
+6 -1
View File
@@ -1893,7 +1893,12 @@
},
"jnqt": { "title": "68", "intro": [] },
"vkei": { "title": "69", "intro": [] },
"jows": { "title": "70", "intro": [] },
"lab-contact-form": {
"title": "Design a Contact Form",
"intro": [
"In this lab, you will design a contact form in HTML and style it using CSS."
]
},
"ipmw": { "title": "71", "intro": [] },
"quiz-styling-forms": {
"title": "Styling Forms Quiz",
@@ -0,0 +1,9 @@
---
title: Introduction to the Design a Contact Form
block: lab-contact-form
superBlock: front-end-development
---
## Introduction to the Design a Contact Form
In this lab, you will design a contact form in HTML and style it using CSS.
@@ -0,0 +1,11 @@
{
"name": "Design a Contact Form",
"isUpcomingChange": true,
"usesMultifileEditor": true,
"dashedName": "lab-contact-form",
"order": 70,
"superBlock": "front-end-development",
"challengeOrder": [{ "id": "66f26c32ec6f90df01a44f60", "title": "Design a Contact Form" }],
"helpCategory": "HTML-CSS",
"blockType": "lab"
}
@@ -0,0 +1,455 @@
---
id: 66f26c32ec6f90df01a44f60
title: Design a Contact Form
challengeType: 14
dashedName: design-a-contact-form
demoType: onClick
---
# --description--
**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
**User Stories:**
1. You should have a `div` with a class of `form-container` to hold your form.
2. You should have a `form` element within the `.form-container` `div`.
3. Within the `form` element, you should have the following elements and input fields:
- A `h2` element with some text.
- A text input field for the name with the `type` set to `text` and `id`, `name`, `required` attributes.
- An email input field with the `type` set to `email` and `id`, `name`, `required` attributes.
- A textarea for the message with `id`, `name`, and the `required` attribute.
- A `button` element with the text `"Submit"` and a `type` attribute of `submit`.
4. Each `input` and `textarea` elements should have their corresponding `label` element with a `for` attribute set to the element's `id`.
5. The `.form-container` `div` should have a background color, and have values for `border-radius`, `padding`, and `width`.
6. The `label` elements should have a margin and a font color.
7. The `input` and `textarea` elements should have values for:
- `width`.
- `padding`.
- Margin on the bottom.
8. The `button` element should have a:
- Background color
- Font size apart from the default.
9. The button should have a hover effect that changes the background color.
**Note:** Be sure to link your stylesheet in your HTML and apply your CSS.
# --hints--
You should have a `div` with a class of `form-container`.
```js
const el = document.querySelector('div.form-container');
assert.isNotNull(el);
```
You should have a `form` element within the `.form-container` `div`.
```js
const el = document.querySelector('.form-container form');
assert.isNotNull(el);
```
Within the `form`, you should have an `h2` element with some text.
```js
const el = document.querySelector('.form-container form h2');
assert.isNotEmpty(el.innerText);
// assert.isAtLeast(document.querySelector('h1').innerText.length, 1);
```
Within the `form`, you should have a text input field with the type set to `text`.
```js
const el = document.querySelector('.form-container form input[type="text"]');
assert.isNotNull(el);
```
Your `type=text` input field should have an `id`, a `name`, and a `required` attribute.
```js
const el = document.querySelector('.form-container form input[type="text"]');
assert(!!el && el.required);
assert.isNotEmpty(el?.getAttribute('id'));
assert.isNotEmpty(el?.getAttribute('name'));
```
Within the `form`, you should have an email input field with the `type` set to `email`.
```js
const el = document.querySelector('.form-container form input[type="email"]');
assert.isNotNull(el);
```
Your `type=email` input field should have an `id`, a `name`, and a `required` attribute.
```js
const el = document.querySelector('.form-container form input[type="email"]');
assert.isTrue(el?.required);
assert.isNotEmpty(el?.getAttribute('id'));
assert.isNotEmpty(el?.getAttribute('name'));
```
Within the `form`, you should have a `textarea` with an `id`, `name`, and a `required` attribute.
```js
const el = document.querySelector('.form-container form textarea');
assert.isNotNull(el);
assert.isNotNull(document.querySelector('.form-container form textarea[required]'));
assert.isNotEmpty(el?.getAttribute('id'));
assert.isNotEmpty(el?.getAttribute('name'));
```
Within the `form`, you should have a `button` element with a `type` attribute of `submit`.
```js
const el = document.querySelector('.form-container form button');
assert.strictEqual(el?.getAttribute('type'), 'submit');
```
Your button should have a text of `"Submit"`.
```js
const el = document.querySelector('.form-container form button');
assert.strictEqual(document.querySelector('.form-container form button').textContent, 'Submit');
```
You should have a `label` element for the `#name` `input` with a `for` attribute matching the `id` value on the corresponding `input`.
```js
const nameInput = document.querySelector('.form-container form input[type="text"]')?.getAttribute('id');
const labels = document.querySelectorAll('.form-container form label');
assert.isAbove(labels.length, 0);
// check if id has a value
assert.isNotEmpty(nameInput);
let found = false;
for (let label of labels) {
if (label.getAttribute('for') === nameInput) {
found = true;
break;
}
}
assert.isTrue(found);
```
You should have a `label` element for the `#email` `input` with a `for` attribute matching the `id` value on the corresponding `input`.
```js
const emailInput = document.querySelector('.form-container form input[type="email"]')?.getAttribute('id');
const labels = document.querySelectorAll('.form-container form label');
assert.isAbove(labels.length, 0);
// check if id has a value
assert.isNotEmpty(emailInput);
let found = false;
for (let label of labels) {
if (label.getAttribute('for') === emailInput) {
found = true;
break;
}
}
assert.isTrue(found);
```
You should have a `label` element for the `#message` `textarea` with a `for` attribute matching the `id` value on the `textarea`.
```js
const messageInput = document.querySelector('.form-container form textarea')?.getAttribute('id');
const labels = document.querySelectorAll('.form-container form label');
assert.isAbove(labels.length, 0);
// check if id has a value
assert.isNotEmpty(messageInput);
assert.exists(document.querySelector(`label[for="${messageInput}"]`));
```
The labels shouldn't be empty.
```js
const labels = document.querySelectorAll('.form-container form label');
assert.isAbove(labels.length, 0);
for (let label of labels) {
const labelText = label.textContent.trim();
assert.isNotEmpty(labelText);
}
```
The `form-container` `div` should have a background color.
```js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('.form-container')?.backgroundColor);
```
The `form-container` `div` should have a `border-radius`.
```js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('.form-container')?.borderRadius);
```
The `form-container` `div` should have padding.
```js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('.form-container')?.padding);
```
The `form-container` `div` should have a width.
```js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('.form-container')?.width);
```
Your labels should have a margin and font color.
```js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('label')?.margin);
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('label')?.color);
```
Your `input` elements should have a width, padding, and a margin on the bottom.
```js
// Helper function to extract properties from multiple selectors
function getStyleProperties(selectors, properties) {
const result = {};
properties.forEach((property) => {
result[property] = selectors.map((selector) => selector?.[property]).find(Boolean);
});
return result;
}
// Initializing selectors
const selectors = [
new __helpers.CSSHelp(document).getStyle('input'),
new __helpers.CSSHelp(document).getStyle('input, textarea'),
new __helpers.CSSHelp(document).getStyle('textarea, input')
];
// Extract width, padding, and margin properties
const { width } = getStyleProperties(selectors, ['width']);
assert.isNotEmpty(width);
const {
padding,
paddingTop,
paddingBottom,
paddingLeft,
paddingRight
} = getStyleProperties(selectors, ['padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight']);
// Assert padding properties
assert.isOk(
padding ||
(paddingTop && paddingBottom && paddingLeft && paddingRight)
);
const { marginBottom } = getStyleProperties(selectors, ['marginBottom']);
assert.isNotEmpty(marginBottom);
```
Your `textarea` element should have a width, padding, margin on the bottom.
```js
// Helper function to extract properties from multiple selectors
function getStyleProperties(selectors, properties) {
const result = {};
properties.forEach((property) => {
result[property] = selectors.map((selector) => selector?.[property]).find(Boolean);
});
return result;
}
// Initializing selectors
const selectors = [
new __helpers.CSSHelp(document).getStyle('textarea'),
new __helpers.CSSHelp(document).getStyle('input, textarea'),
new __helpers.CSSHelp(document).getStyle('textarea, input')
];
// Extract width, padding, and margin properties
const { width } = getStyleProperties(selectors, ['width']);
assert.isNotEmpty(width);
const {
padding,
paddingTop,
paddingBottom,
paddingLeft,
paddingRight
} = getStyleProperties(selectors, ['padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight']);
// Assert padding properties
assert.isOk(
padding ||
(paddingTop && paddingBottom && paddingLeft && paddingRight)
);
const { marginBottom } = getStyleProperties(selectors, ['marginBottom']);
assert.isNotEmpty(marginBottom);
```
Your `button` element should have a background color.
```js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('button')?.backgroundColor);
```
Your `button` element should have a font size.
```js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('button')?.fontSize);
```
Your `button` element should have a hover effect that changes the background color.
```js
const gs = (s) => new __helpers.CSSHelp(document).getStyle(s);
const btn_hover = gs('button:hover')?.backgroundColor;
assert.isNotEmpty(btn_hover);
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Contact Form</title>
</head>
<body>
</body>
</html>
```
```css
```
# --solutions--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Styled Form Project</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="form-container">
<form>
<h2>Contact Us</h2>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
```
```css
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background: linear-gradient(45deg, #83a4d4, #b6fbff);
font-family: Arial, sans-serif;
}
.form-container {
background-color: white;
border-radius: 10px;
padding: 20px;
width: 300px;
text-align: center;
}
form h2 {
margin-bottom: 20px;
color: #333;
}
label {
display: block;
margin: 10px 0 5px;
color: #555;
}
input{
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 5px;
box-sizing: border-box;
resize: vertical;
}
textarea {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 5px;
box-sizing: border-box;
resize: vertical;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 1em;
}
button:hover {
background-color: #45a049;
}
```