Back to Freecodecamp

Design a Contact Form

curriculum/challenges/english/blocks/lab-contact-form/66f26c32ec6f90df01a44f60.md

latest11.3 KB
Original Source

--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 element.

  3. Within the form element, you should have the following elements and input fields:

    • An 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 element 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 element.

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.exists(el);
assert.isTrue(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 element 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 element 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 element 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 element should have a background color.

js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('.form-container')?.backgroundColor);

The .form-container element should have a border-radius.

js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('.form-container')?.borderRadius);

The .form-container element should have padding.

js
assert.isNotEmpty(new __helpers.CSSHelp(document).getStyle('.form-container')?.padding);

The .form-container element 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;
}