← HTML & CSS/Формы: тег <form>#8 из 383← ПредыдущийСледующий →+15 XP
Полезно по теме:Гайд: старт в frontendПрактика: DOM и событияТермин: DOMМаршрут: старт с нуля

Формы: тег <form>

Ты каждый день заполняешь формы: логин и пароль ВКонтакте, поле поиска на Wildberries, форма регистрации в Telegram. Всё это — HTML-формы. Форма — это основной способ получить данные от пользователя.

Базовая структура формы

<form action="/login" method="POST">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" placeholder="you@example.com" />

  <label for="password">Пароль</label>
  <input type="password" id="password" name="password" />

  <button type="submit">Войти</button>
</form>

Тег <form> и его атрибуты

<form action="/submit" method="POST">
  • action — URL, куда отправляются данные формы
  • method — HTTP-метод: GET или POST
  • GET — данные уходят в URL строкой: /search?q=кроссовки&size=42. Используй для поиска и фильтров — результат можно сохранить в закладки.

    POST — данные идут в теле запроса, не видны в URL. Используй для логина, регистрации, оплаты — секретные данные не должны попасть в адресную строку.

    Тег <input> — поле ввода

    <input type="text" name="username" placeholder="Введи имя" />

    Атрибут name критически важен — именно это имя приходит на сервер как ключ:

    username=Иван&email=ivan@mail.ru

    Тег <label> — подпись к полю

    <label> делает форму удобной и доступной:

    <!-- Способ 1: for + id (рекомендуется) -->
    <label for="email">Email адрес</label>
    <input type="email" id="email" name="email" />
    
    <!-- Способ 2: обёртка (input внутри label) -->
    <label>
      Email адрес
      <input type="email" name="email" />
    </label>

    Когда пользователь кликает на <label>, фокус автоматически переходит на связанный <input>. Это важно для удобства и доступности — незрячие пользователи слышат название поля.

    Связь label и input: атрибут for в label должен совпадать с id в input.

    Тег <button>

    <!-- Кнопка отправки формы -->
    <button type="submit">Отправить</button>
    
    <!-- Кнопка сброса формы -->
    <button type="reset">Очистить</button>
    
    <!-- Просто кнопка (JS управляет действием) -->
    <button type="button">Сохранить черновик</button>

    Кнопка без атрибута type внутри формы работает как type="submit" — это частая причина случайных отправок формы.

    Типичные ошибки

    Ошибка 1: input без name

    <!-- Неверно — данные не уйдут на сервер -->
    <input type="text" placeholder="Имя" />
    
    <!-- Верно -->
    <input type="text" name="username" placeholder="Имя" />

    Ошибка 2: label не связан с input

    <!-- Неверно — for и id не совпадают -->
    <label for="user">Имя:</label>
    <input type="text" id="username" />
    
    <!-- Верно -->
    <label for="username">Имя:</label>
    <input type="text" id="username" />

    Ошибка 3: Пароль через GET

    <!-- Опасно — пароль видно в URL -->
    <form action="/login" method="GET">
      <input type="password" name="password" />
    </form>

    Ошибка 4: button без type внутри формы

    <!-- button без type = submit — форма отправится при клике -->
    <button onclick="saveToLocal()">Сохранить черновик</button>
    
    <!-- Верно — явно указываем type="button" -->
    <button type="button" onclick="saveToLocal()">Сохранить черновик</button>

    В реальных проектах

    Современные React-приложения обрабатывают формы через библиотеки react-hook-form или Formik. Но они генерируют те же самые HTML-элементы: <form>, <input>, <label>, <button>. Понимание нативного HTML форм — основа для работы с любой библиотекой.

    Примеры

    Создание формы авторизации через DOM и анализ полей

    // Создаём форму авторизации
    const form = document.createElement('form')
    form.action = '/login'
    form.method = 'POST'
    
    // Label + Input для email
    const emailLabel = document.createElement('label')
    emailLabel.htmlFor = 'email'  // for — зарезервированное слово в JS, используем htmlFor
    emailLabel.textContent = 'Email'
    
    const emailInput = document.createElement('input')
    emailInput.type = 'email'
    emailInput.id = 'email'
    emailInput.name = 'email'
    emailInput.placeholder = 'you@example.com'
    
    // Label + Input для пароля
    const passLabel = document.createElement('label')
    passLabel.htmlFor = 'password'
    passLabel.textContent = 'Пароль'
    
    const passInput = document.createElement('input')
    passInput.type = 'password'
    passInput.id = 'password'
    passInput.name = 'password'
    
    // Кнопка отправки
    const submitBtn = document.createElement('button')
    submitBtn.type = 'submit'
    submitBtn.textContent = 'Войти'
    
    // Добавляем в форму
    form.append(emailLabel, emailInput, passLabel, passInput, submitBtn)
    
    // Анализируем форму
    console.log('Тег формы:', form.tagName)
    console.log('action:', form.action)
    console.log('method:', form.method)
    console.log('Полей в форме:', form.elements.length)
    console.log('label htmlFor:', emailLabel.htmlFor)
    console.log('input id:', emailInput.id)
    console.log('Связь label-input OK:', emailLabel.htmlFor === emailInput.id)

    Чтение и валидация данных формы

    // Имитируем форму регистрации и валидацию данных
    const formData = {
      username: 'roadtojs',
      email: 'user@example.com',
      password: 'secret123',
      confirmPassword: 'secret123',
    }
    
    function validateForm(data) {
      const errors = []
    
      if (!data.username || data.username.length < 3) {
        errors.push('Имя пользователя слишком короткое (минимум 3 символа)')
      }
    
      if (!data.email.includes('@')) {
        errors.push('Некорректный email — нет символа @')
      }
    
      if (data.password.length < 6) {
        errors.push('Пароль слишком короткий (минимум 6 символов)')
      }
    
      if (data.password !== data.confirmPassword) {
        errors.push('Пароли не совпадают')
      }
    
      return errors
    }
    
    const errors = validateForm(formData)
    
    if (errors.length === 0) {
      console.log('Форма валидна! Отправляем на сервер...')
      console.log('Пользователь:', formData.username)
      console.log('Email:', formData.email)
    } else {
      console.log('Ошибки валидации:')
      errors.forEach(err => console.log('- ' + err))
    }

    Формы: тег <form>

    Ты каждый день заполняешь формы: логин и пароль ВКонтакте, поле поиска на Wildberries, форма регистрации в Telegram. Всё это — HTML-формы. Форма — это основной способ получить данные от пользователя.

    Базовая структура формы

    <form action="/login" method="POST">
      <label for="email">Email</label>
      <input type="email" id="email" name="email" placeholder="you@example.com" />
    
      <label for="password">Пароль</label>
      <input type="password" id="password" name="password" />
    
      <button type="submit">Войти</button>
    </form>

    Тег <form> и его атрибуты

    <form action="/submit" method="POST">
  • action — URL, куда отправляются данные формы
  • method — HTTP-метод: GET или POST
  • GET — данные уходят в URL строкой: /search?q=кроссовки&size=42. Используй для поиска и фильтров — результат можно сохранить в закладки.

    POST — данные идут в теле запроса, не видны в URL. Используй для логина, регистрации, оплаты — секретные данные не должны попасть в адресную строку.

    Тег <input> — поле ввода

    <input type="text" name="username" placeholder="Введи имя" />

    Атрибут name критически важен — именно это имя приходит на сервер как ключ:

    username=Иван&email=ivan@mail.ru

    Тег <label> — подпись к полю

    <label> делает форму удобной и доступной:

    <!-- Способ 1: for + id (рекомендуется) -->
    <label for="email">Email адрес</label>
    <input type="email" id="email" name="email" />
    
    <!-- Способ 2: обёртка (input внутри label) -->
    <label>
      Email адрес
      <input type="email" name="email" />
    </label>

    Когда пользователь кликает на <label>, фокус автоматически переходит на связанный <input>. Это важно для удобства и доступности — незрячие пользователи слышат название поля.

    Связь label и input: атрибут for в label должен совпадать с id в input.

    Тег <button>

    <!-- Кнопка отправки формы -->
    <button type="submit">Отправить</button>
    
    <!-- Кнопка сброса формы -->
    <button type="reset">Очистить</button>
    
    <!-- Просто кнопка (JS управляет действием) -->
    <button type="button">Сохранить черновик</button>

    Кнопка без атрибута type внутри формы работает как type="submit" — это частая причина случайных отправок формы.

    Типичные ошибки

    Ошибка 1: input без name

    <!-- Неверно — данные не уйдут на сервер -->
    <input type="text" placeholder="Имя" />
    
    <!-- Верно -->
    <input type="text" name="username" placeholder="Имя" />

    Ошибка 2: label не связан с input

    <!-- Неверно — for и id не совпадают -->
    <label for="user">Имя:</label>
    <input type="text" id="username" />
    
    <!-- Верно -->
    <label for="username">Имя:</label>
    <input type="text" id="username" />

    Ошибка 3: Пароль через GET

    <!-- Опасно — пароль видно в URL -->
    <form action="/login" method="GET">
      <input type="password" name="password" />
    </form>

    Ошибка 4: button без type внутри формы

    <!-- button без type = submit — форма отправится при клике -->
    <button onclick="saveToLocal()">Сохранить черновик</button>
    
    <!-- Верно — явно указываем type="button" -->
    <button type="button" onclick="saveToLocal()">Сохранить черновик</button>

    В реальных проектах

    Современные React-приложения обрабатывают формы через библиотеки react-hook-form или Formik. Но они генерируют те же самые HTML-элементы: <form>, <input>, <label>, <button>. Понимание нативного HTML форм — основа для работы с любой библиотекой.

    Примеры

    Создание формы авторизации через DOM и анализ полей

    // Создаём форму авторизации
    const form = document.createElement('form')
    form.action = '/login'
    form.method = 'POST'
    
    // Label + Input для email
    const emailLabel = document.createElement('label')
    emailLabel.htmlFor = 'email'  // for — зарезервированное слово в JS, используем htmlFor
    emailLabel.textContent = 'Email'
    
    const emailInput = document.createElement('input')
    emailInput.type = 'email'
    emailInput.id = 'email'
    emailInput.name = 'email'
    emailInput.placeholder = 'you@example.com'
    
    // Label + Input для пароля
    const passLabel = document.createElement('label')
    passLabel.htmlFor = 'password'
    passLabel.textContent = 'Пароль'
    
    const passInput = document.createElement('input')
    passInput.type = 'password'
    passInput.id = 'password'
    passInput.name = 'password'
    
    // Кнопка отправки
    const submitBtn = document.createElement('button')
    submitBtn.type = 'submit'
    submitBtn.textContent = 'Войти'
    
    // Добавляем в форму
    form.append(emailLabel, emailInput, passLabel, passInput, submitBtn)
    
    // Анализируем форму
    console.log('Тег формы:', form.tagName)
    console.log('action:', form.action)
    console.log('method:', form.method)
    console.log('Полей в форме:', form.elements.length)
    console.log('label htmlFor:', emailLabel.htmlFor)
    console.log('input id:', emailInput.id)
    console.log('Связь label-input OK:', emailLabel.htmlFor === emailInput.id)

    Чтение и валидация данных формы

    // Имитируем форму регистрации и валидацию данных
    const formData = {
      username: 'roadtojs',
      email: 'user@example.com',
      password: 'secret123',
      confirmPassword: 'secret123',
    }
    
    function validateForm(data) {
      const errors = []
    
      if (!data.username || data.username.length < 3) {
        errors.push('Имя пользователя слишком короткое (минимум 3 символа)')
      }
    
      if (!data.email.includes('@')) {
        errors.push('Некорректный email — нет символа @')
      }
    
      if (data.password.length < 6) {
        errors.push('Пароль слишком короткий (минимум 6 символов)')
      }
    
      if (data.password !== data.confirmPassword) {
        errors.push('Пароли не совпадают')
      }
    
      return errors
    }
    
    const errors = validateForm(formData)
    
    if (errors.length === 0) {
      console.log('Форма валидна! Отправляем на сервер...')
      console.log('Пользователь:', formData.username)
      console.log('Email:', formData.email)
    } else {
      console.log('Ошибки валидации:')
      errors.forEach(err => console.log('- ' + err))
    }

    Задание

    Напиши HTML-форму обратной связи: action="/contact", method="POST". Добавь три пары label + поле: имя (label "Ваше имя", input type="text", name="name"), email (label "Email", input type="email", name="email"), сообщение (label "Сообщение", textarea name="message"). Для каждой пары атрибут for у label должен совпадать с id поля. Добавь кнопку submit "Отправить".

    Подсказка

    for у label и id у input должны быть одинаковыми — это связывает подпись с полем. textarea — отдельный тег, не input. method="POST" — для форм с личными данными. type="submit" — кнопка отправки формы.

    Загружаем среду выполнения...
    Загружаем AI-помощника...