npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

tbody-form

v1.3.0

Published

Модуль для валидации и отправки формы

Downloads

4

Readme

tbody-form

Плагин для валидации и отправки форм. В качестве параметров валидации использует HTML5 атрибуты, плюс дополнительные data - атрибуты. Метод отправки, url и способ кодирования берет из атрибутов формы. Есть включения многошагового режима. Поддерживает загрузку файлов, отображения превью файлов и из валидацию.

Базовый пример

HTML

<form name="myForm" action="handler.php" method="POST">
  <input type="text" id="user-name" name="name" required  minlength="2" maxlength="10">
  <input type="email" id="user-email" name="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" required>
  <input type="password" id="user-password" name="password" required>
  <input type="password" id="iser-password2" name="password2" data-equalto="password">  
  <input type="submit" value="Отправить" name="submit">
</form>

Каждое поля обязательно должно иметь следующие атрибуты: id, type, name. Кнопка вызывающая событие отправки формы должна иметь атрибут name со значением submit

JS

import Tbodyform from 'tbody-form';

const form = document.forms.myForm;

const myForm = new Tbodyform({
  node: form,
  messages: {
    name: {
      required: 'Это поле обязательно',
      minlength: 'Минимум 2 символа',
      maxlength: 'Максимум 10 символов',
    },
    email: {
      required: 'Это поле обязательно',
      pattern: 'Введите корректный email',
    },
    password: {
      required: 'Это поле обязательно',
    },
    password2: {
      equalTo: 'Пароли должны совпадать',
    },
  },
});
myForm.init();

Описание работы

При первом клике на кнопку "Отправить" все поля помечаются как "грязные" и для каждого поля запускается live-режим. Т.е. валидация каждого поля будет запускать при каждом изменении значения этого поля. Статус валидности помечается соответствующим CSS классом.

Вывод ошибок

Сообщение об ошибке валидации поля добавляется после этого поля в виде HTML элемента label которое с помощью атрибута for ссылается на поле к которому относится. По этой причине каждое поле должно иметь атрибут id. Место вывода ошибки можно изменить с пощью CSS класса js-field-container которые необходимо добавить одному из предков поля и тогда сообщение об ошибке добавится внутрь этого элемента. Пример:

<div class="js-field-container">
  <div class="form-group">
    <label for="password">Пароль</label>
    <input class="form-control" id="password" type="password" name="password" required>
  </div>
</div>

Входные параметры

const myForm = Tbodyform({node, messages, isMultistep, dataFn, successCb, errorCb});
  • node - HTML елемент формы, тип - HTMLElement;
  • messages - сообщения об ошибках, тип - Object;
  • isMultistep - флаг для включения многошагового режима, тип Boolean;
  • dataFn - функция которая должна вернуть массив дополнительных данных для отправки формы. Вызывается перед отправкой формы с параметром form который является текущим экземпляром Lhform, тип - Function;
  • successCb - функция которая вызывается после успешной отправки формы. Вызывается с параметром xhr.responseText - результат возврата сервера, тип - String;
  • successCb - функция которая вызывается после неудачной отправки формы. Вызывается с пареметрами xhr.status - статус запроса, тип - String, xhr.statusText - сообщение об ошибке, тип - String;

node:

node: document.forms.myForm

messages:

messages: {
  name: {
    required: 'Это поле обязательно',
    minlength: 'Минимум 2 символа',
    maxlength: 'Максимум 10 символов',
  }
}

isMultistep:

isMultistep: true

dataFn:

dataFn: () => (
  [
    { name: 'jio', value: 13 },
  ]
)

successCb:

successCb: data => console.log(data)

errorCb:

errorCb: (a, b) => console.log(a, b)

Поддерживаемые атрибуты валидации

| Атрибут | Тип значения | Поля | Пример | Описание | | --------- | -------------- | ------ | -------- | ---------- | | required | --- | все | required | Обазятельность заполения поля | | minlenght | string/number | text, email, password | minlength="2" | Минимальную длина значения | | maxlength | string/number | text, email, password | maxlength="100" | Максимальная длина значения | | min | string/number | number | min="56" | Минимальное значением | | max | string/number | number | min="78" | Максимальным значением | | accept | string | file | accept="image/jpeg" | Разрешенный тип файлов. См. тут | | data-equalto | string | все |  data-equalto="password" | Сравнивает текущее значение со значением поля указанным в этом атрибуте | | data-minlength | string/number | checkbox, select, file | data-minlength="2" | Минимальное количество файлов | | data-maxlength | string/number | file | data-maxlength="2" | Максимальное количество файлов | | data-minfilesize | string/number | file | data-minfilesize="14603" | Минимальный размер файлов в байтах | | data-maxfilesize | string/number | file | data-minfilesize="204500" | Максимальный размер файлов в байтах |

Валидация input[type="file"]

HTML

<form name="myForm" action="handler.php" method="POST" enctype="multipart/form-data">
  <input
    type="file"
    name="file[]"
    data-accept="image/jpeg,image/png,image/gif"
    data-minlength="2"
    data-maxlength="4"
    data-minfilesize="100000"
    data-maxfilesize="200000"
    data-filezone="#filezone"
    multiple
    required
  >
  <input class="btn btn-primary" type="submit" value="Submit" name="submit">
</form>
<div id="filezone"></div>

Для отправки файлов необходимо форме укзать атрибут enctype со значением multipart/form-data Для отображения превью файлов у поля необходимо указать атрибут data-filezone со значением CSS селектора HTML элемента внутрь которого будут добавлять превью файлов.

JS

import Tbodyform from 'tbody-form';

const form = document.forms.myForm;
const myForm = new Tbodyform({
  node: form,
  messages: {
    'file[]': {
      required: 'Это поле обязательно',
      accept: 'Выберите изображение',
      minlength: 'Выберите больше 1 файла',
      maxlength: 'Выберите меньше 5 файлов',
      minfilesize: 'Слишком маленький файл',
      maxfilesize: 'Слишком большой файл',
    },
  },
});
myForm.init();

Валидация input[type="radio"]

HTML

<form name="myForm" action="handler.php" method="POST">
  <div class="js-field-container">
    <div>Выберите язык</div>
    <div class="form-check">
      <input class="form" id="language1" type="radio" name="language" value="russian" required>
      <label class="form-check-label" for="language1">Русский</label>
    </div>
    <div class="form-check">
      <input class="form" id="language2" type="radio" name="language" value="english">
      <label class="form-check-label" for="language2">English</label>
    </div>
  </div>
  <input class="btn btn-primary" type="submit" value="Submit" name="submit">
</form>
<div id="filezone"></div>

JS

import Tbodyform from 'tbody-form';

const form = document.forms.myForm;
const myForm = new Tbodyform({
  node: form,
  messages: {
    language: {
      required: 'Это поле обязательно',
    },
  },
});
myForm.init();

Поле radio поддерживает только тип валидации required. Атрибут required необходимо указать только первому элементу.

Валидация input[type="checkbox"]

HTML

<form name="myForm" action="handler.php" method="POST">
  <div>Выберите цвета</div>
  <div class="form-check">
    <input
      class="form"
      id="color1"
      type="checkbox"
      name="color[]"
      value="red" required
      data-minlength="2"
      data-maxlength="3"
    >
    <label class="form-check-label" for="color1">Красный</label>
  </div>
  <div class="form-check">
    <input class="form" id="color2" type="checkbox" name="color[]" value="green">
    <label class="form-check-label" for="color2">Зеленый</label>
  </div>
  <div class="form-check">
    <input class="form" id="color3" type="checkbox" name="color[]" value="blue">
    <label class="form-check-label" for="color3">Синий</label>
  </div>
  <div class="form-check">
    <input class="form" id="color4" type="checkbox" name="color[]" value="pink">
    <label class="form-check-label" for="color4">Розовый</label>
  </div>
  <input class="btn btn-primary" type="submit" value="Submit" name="submit">
</form>
<div id="filezone"></div>

JS

import Tbodyform from 'tbody-form';

const form = document.forms.myForm;
const myForm = new Tbodyform({
  node: form,
  messages: {
    'color[]': {
      required: 'Выберите цвета',
      minlength: 'Минимум 2 цвета',
      maxlength: 'Максимум 3 цвета',
    },
  },
});
myForm.init();

Все атрибуты валидации необходимо указать только первому элементу.

Валидация select

HTML

<form name="myForm" action="handler.php" method="POST">
  <label for="theme">Тема</label>
  <select
    class="form-control"
    id="theme"
    name="theme[]"
    multiple    required
    data-minlength="2"
    data-maxlength="3"
  >
    <option>---</option>
    <option value="sport">Спорт</option>
    <option value="porno">Кино</option>
    <option value="money">Деньги</option>
    <option value="humor">Юмор</option>
  </select>
  <input class="btn btn-primary" type="submit" value="Submit" name="submit">
</form>
<div id="filezone"></div>

JS

import Tbodyform from 'tbody-form';

const form = document.forms.myForm;
const myForm = new Tbodyform({
  node: form,
  messages: {
    'theme[]': {
      required: 'Это поле обязательно',
      minlength: 'Минимум 2 темы',
      maxlength: 'Максимум 3 темы',
    },
  },
});
myForm.init();

Элемент option который выступает в роли placeholder должен быть без атрибута value. Все остальные option должны иметь атрибут value по котору будет происходить валидация и отправляться будет именно значения из атрибута value.

Многошаговый режим

Этот режим позволяет разделить большие формы на несколько шагов. Разделение формы на шаги осуществалсяется с помощью HTML-тегов fieldset, переход к следующему шагу осуществляется по клику на кнопку с CSS-классом js-next-fieldset, переход к предыдущему - js-prev-fieldset. Обе кнопки должны распологаться внутри HTML-тега fieldset. Первый шаг не может содержать кнопку js-prev-fieldset, последний - js-next-fieldset. В последнем шаге добавляется кнопка отправки формы. При клике на кнопку js-next-fieldset запускается валидация полей которые находятся на данном шаге, после прохождения валидации соответствующий статус устанавливается для текущего шага. Если хоть одно поле на данном шаге невалидно, то переход к следующему шагу не возможен. Клик по кнопке js-prev-fieldset не запускает валидацию полей и поэтому можно возвращаться к предущему шагу, даже если поля на текущем шаге не валидны.

<form name="myForm" action="demo/handler.php" method="POST">
  <fieldset>
    <legend>Группа полей 1</legend>
    <div class="js-field-container form-group">
      <label for="name">Имя</label>
      <input
        class="form-control"
        id="name"
        type="text"
        name="name"
        minlength="2"
        maxlength="10"
        required
      />
    </div>
    <button class="js-next-fieldset btn btn-success">Следующее</button>
  </fieldset>

  <fieldset>
    <legend>Группа полей 2</legend>
    <div class="js-field-container form-group">
      <label for="password">Пароль</label>
      <input class="form-control" id="password" type="password" name="password" required>
    </div>
    <button class="js-prev-fieldset btn btn-success">Предыдущее</button>
    <button class="js-next-fieldset btn btn-success">Следующее</button>
  </fieldset>
  <fieldset>
    <legend>Группа полей 3</legend>
    <div class="js-field-container form-group">
      <label for="comment">Комментарий</label>
      <textarea class="form-control" id="comment" name="comment" required minlength="10" maxlength="50"></textarea>
    </div>
    <button class="js-prev-fieldset btn btn-success">Предыдущее</button>
    <input class="btn btn-primary" type="submit" value="Отправить" name="submit">
  </fieldset>
</form>
import Tbodyform from 'tbody-form';

const form = document.forms.myForm;
const myForm = new Tbodyform({
  node: form,
  messages: {
    name: {
      required: 'Это поле обязательно',
      minlength: 'Минимум 2 символа',
      maxlength: 'Максимум 10 символов',
    },
    password: {
      required: 'Это поле обязательно',
    },
    comment: {
      required: 'Это поле обязательно',
      minlength: 'Минимум 10 символов',
      maxlength: 'Максимум 50 символов',
    },
  },
  isMultistep: true,
});
myForm.init();