ENote
  • ✨Home
    • Відмова від відповідальності
  • Progr
    • Python
      • Модулі
        • pip
        • cgitb
        • datetime
          • Класс datetime() модуля datetime
            • Методы объекта datetime.datetime()
            • datetime.datetime examples
          • Класс timedelta() модуля datetime
            • datetime.timedelta examples
          • Класс date() модуля datetime
            • datetime.date examples
          • Класс time() модуля datetime
            • Формат для функций .strftime() и .strptime(). модуля datetime
        • os.path
        • pathlib
          • pathlib to str
        • subproces
        • os
        • Jinja
          • Синтаксис шаблонів Jinja
          • Клас Environment()
          • Простой пример cgi-скрипта c Jinja-шаблоном
          • Создание переменных
            • Як оновити глобальну змінну зсередини оператора IF / ELSE або циклу FOR
          • Фільтри і методи
          • Число у рядок, slices
          • Вбудовані фільтри Jinja2
        • re
          • re.search - example
          • re.findall - example
        • email / smtplib
          • Как отправлять электронные письма с помощью Python
        • requests
          • Як зберегти та завантажити файли cookie в запитах Python?
          • Извлечение и установка cookies с модулем requests в Python
          • Links
        • http.cookies
          • Всё о работе с cookie в Python — класс http.cookies
        • xlrd
        • xlwt
        • borb
          • ChunkOfText
          • send_usage_statistics
          • borb clear
          • 2.1.3 vs 2.1.15
          • QR-code
          • Залежності borb
        • JSON
          • Кирилиця в JSON
        • matplotlib
        • argparse
        • click
        • configparser
        • traceback
        • sys
          • exit()
        • mysql-connector-python
        • logging
        • icrawler
        • Auto Plates
        • rembg
        • random
      • Strings
        • Built-in methods
        • Форматування виводу
        • Початкові нулі
        • Рядок в число
      • list
        • Об’єднання списків
        • list.sort(), sorted()
        • list.reverse(), reversed()
        • all(), any()
        • sum(), min(), max()
        • map(), filter(), reduce()
        • join(), split()
      • tuple
      • dict
        • Об'єднання / злиття словників
        • Сортування словника Python: значення, ключі тощо
      • set
      • class Enum
      • Середнє арифметичне
      • Virtual environment
        • web-app
      • type(), isinstance()
      • __main__
      • Files & Dirs
        • Try except for exception handling
        • Cписок файлов директории
        • User Home Dir
        • Copy file
      • *args, **qwargs
      • Links
      • Область видимости
      • Handling a File Error
      • assert
      • if
      • Числа
        • Округлення чисел
        • Отримати число з рядка
      • Обработка исключений в Python
      • Файлы и сериализация данных
      • OOP
      • Net and Web
      • Структура проекта на Python
      • Распаковка итерируемых объектов
      • Links
      • Algorithms
      • Python exit commands: quit(), exit(), sys.exit() and os._exit()
      • Цикли for / while
      • uuid
    • JavaScript
      • String
        • replaceAll() polyfill
        • Шаблонные строки
      • Array
        • Все способы перебора массива в JavaScript
      • Object
      • document.location
      • RegExp
      • Examples
        • Вычисление остатка от деления
        • Остаток от деления и деление без остатка
        • Округление числа
      • XMLHttpRequest
      • alert, prompt, confirm
      • onclick
      • hidden, display:none
      • LocalStorage, sessionStorage
      • null, undefined
      • cookies (js)
      • var, let и const
        • var vs let
        • const
      • Модифікація DOM
        • DOM select
      • JSON
        • Try
      • fetch
      • typeof
      • FormData не включає disabled набори полів
      • FormData, fdata
      • Більше одного відео YouTube на одній сторінці
    • HTML, CSS
      • favicon
      • Деякі спецсимволи
      • meta
      • ASCII table
      • lang
      • Псевдоелементи ::after і ::before
      • Cursor
      • Об использовании нестандартных пробелов
      • Картинка фоном
      • Безпечні веб-шрифти
      • Завжди внизу, незалежно від пропорцій екрану
      • напівпрозорий елемент
      • Символи з тінью
      • SVG (bootstrap)
      • rel = canonical
      • link stylesheet: integrity & crossorigin
      • rel = noopener
    • Bootstrap
      • Form Validate
      • Password show/hide
    • Errors
  • Dev
    • Git
      • clone
      • git-scm (book)
      • git config
        • files .git*
        • core.filemode
        • core.sharedRepository
      • .gitignore
      • .gitkeep
      • Видалити з репозиторію
        • Видалений файл з однієї гілки...
      • Пам’ятка
        • Перегляд історії комітів
        • Скасувати git add
        • revert
        • Скасувати внесені зміни у файл
        • Додати до коміту файл
        • Видалити історію попередніх коммітів, та почати "з нуля"
        • Додати файли в останній коміт
      • Робота з гілками
        • Порівняти гілки
      • Git за полчаса
      • Три розділи проєкту Git
      • Merge conflict
      • Pull error
        • Git Error: You have divergent branches...
      • diff
      • Video
      • Merge скасувати
      • .gitignore: Permission denied
    • GitHub
      • SSH-підключення до GitHub
      • Перенести на сервер локальный репозиторий
      • Перенести на сервер репозиторій разом з історією
      • Створення змісту
    • Security
      • robots.txt
      • Cookies
    • Аутентифікація і cookies
      • ChatGPT
  • data
    • MySQL
      • MyISAM vs InnoDB
      • Типи даних
        • NULL (todo)
        • TIMESTAMP
        • YEAR
        • JSON
        • Требования к памяти для символьных типов
        • Поиск записей в таблице, которым нет соответствия в другой
      • Приклад створення БД, та користувача
        • Права для пользователей
      • Переглянути всі індекси таблиці
      • Копіювання, клонування таблиць
      • TEMPORARY TABLE
      • JOIN
      • ALTER TABLE
      • AUTO_INCREMENT
        • AUTO_INCREMENT у складовому індексі
      • LIMIT
        • Использование MySQL LIMIT
      • 10 Примеров входной загрузки данных из текстового файла в таблицы MySQL
      • Рішення
        • Выявление и удаление несвязанных записей
        • Выборка произвольных записей
        • Коректне сортування українських літер
        • Найти записи, которые присутствуют в одной таблице и отсутствуют во второй
        • Как удобно посмотреть данные...
        • Нахождение "дыр" в нумерации
        • Знайти дубликати полів в одній таблиці
        • Дані колонки 1 табл. перенести в 2 табл.
      • Функції
        • LAST_INSERT_ID()
        • GROUP_CONCAT
        • COUNT + DISTINCT
        • Функции для работы с датами и временем
      • Автоматизируйте создание бэкапов
      • mysqldump
        • Time Zone UTC
      • Результат запиту у файл
      • Результат запиту у змінну
      • Пособие по MySQL на Python
      • Змінні
      • Эмуляция функции row_number() в MySQL
      • Изучаем хранимые процедуры MySQL
      • SELECT DISTINCT
      • Dump всієї бази даних
      • Індекси
      • FOREIGN KEY
      • MAX(), MIN()
      • LENGTH, CHAR_LENGTH
      • Встановлення
    • MariaDB
    • PostgreSQL
      • Работа с базой данных PostgreSQL
      • Работаем с PostgreSQL через командную строку в Linux
    • Domains
      • Життєвий цикл доменів
      • Статус домена
    • SQLite, MySQL и PostgreSQL: сравниваем популярные реляционные СУБД
  • Linux
    • DNS
      • Как в DNS прописать 301 редирект
      • mail
        • SPF
          • Mirohost
        • _dmarc _domainkey
        • DKIM
        • Прописати ключі DKIM в exim
        • Листи з неіснуючим адресатом
    • Server
      • Zomro
        • pip
        • SSH-доступ по ключу (zomro)
        • venv
        • UnicodeEncodeError: 'latin-1' codec can't encode character
        • Mail Ports
        • Редірект з SSL-сертификатом на транзитному сайті
        • Редірект з SSL за допомогою .htaccess
      • Створення нового користувача з привілеями sudo в Ubuntu
      • SSH-доступ по ключу
      • Часовий пояс в Ubuntu 20.04
      • SSH-підключення командний рядок
      • Як встановити Python 3.9 (нижчу) на Ubuntu 22.04
      • Автозагрузка сервисов в Ubuntu
      • Підвищення безпеки SSH
      • Ubuntu Server
        • Art 01
    • Commands
      • adduser
      • apt
      • cat
      • ls
      • tar
      • ln
      • find
      • chmod
      • chown
      • mv
      • dig
      • ping
      • passwd
      • htpasswd
      • umask
      • usermode
      • history
      • cmp
      • chattr +i
    • Config
      • Keyboard
      • windows
      • My kbdswtch
      • Затримка при завантаженні системи
      • Files
        • /etc/resolv.conf
        • /boot/grub/grub.cfg
        • .config/user-dir.dirs
        • /etc/fstab
      • Як встановити шрифти
    • Apache
      • Встановлення
      • Подключить виртуальный хост
      • Файл .htaccess
        • Установка индексного файла
        • Фільтр IP-адрес
        • ModRewrite
          • Заборонити доступ за User-Agent
          • Перенаправити на іншу сторінку
          • Додавати слеш до адреси
        • Включити SSI
        • Виконувати скрипти CGI
        • Тимчасовий перехід з одного домену на інший
      • SSI
      • SSL
      • Відключити старт Apache з системою
      • Помилки
        • Скрипт не працює
        • CGI-скрипт не виводить кирилицю
        • Could not reliably determine
        • Permissions are missing on a component of the path
        • Symbolic link not allowed or link target not accessible
      • AddType, AddLanguage, AddCharset
    • Nginx
      • 301 редирект з www. та http: на https://(без www.)domain
    • Soft
      • SublimeText
        • Plugins
      • Firefox
      • Gwenview
      • inkscape
      • Double Commander
      • nano
      • mc
        • Знайти потрібний файл
      • meld / diffuse
      • hexedit
      • Kazam - відео з екрану
      • VeraCrypt
      • XnView MP
      • LibreOffice
      • xdotool
      • System Load Monitor
      • Battery Monitor
      • qBittorrent
    • Перетворення .RPM в .DEB
    • Bash
      • Конкатенация строк в Bash
      • Page
    • Файлові часові позначки в Linux: atime, mtime, ctime
    • Права доступу для файлів і каталогів
    • Зміна паролю root
    • Быстро удалить огромное количество файлов в каталоге
    • Як узнати версію Linux?
    • USB Flash ext4
    • Clear Cache
    • Доступ до спільної папки на Windows
    • Віртуальні консолі TTY1–TTY6
    • APT. Заборона оновлення
  • Різне
    • GitBook
    • Банковское округление
    • Ім’я користувача Youtube
  • Hard
    • Hardware
      • Acer Extensa
      • Таймер Feron TM22
      • WD My Book World Edition 2Tb
        • FTP
        • SSH
          • Проблеми
        • SSHFS
      • Canon PIXMA E3340
      • Термометри
    • Auto
      • Акумулятор
    • Electro
    • USB Flash recovery
Powered by GitBook
On this page
  • Прізвище
  • Ім’я
  • По батькові
  • email
  • Перевірити поля по шаблонам і піти на іншу сторінку або скрипт:
  • Перевірити поля по шаблонам (потім виконати AJAX-запит) і залишитися на цій сторінці:
  1. Progr
  2. Bootstrap

Form Validate

regexp | javascript

Прізвище

Може складатися з двох частин (Карпенко-Карий), які пишуться через дефіс

maxlength="30"
placeholder="Іваненко"
pattern="[А-яІіЇїЄєҐґ\-'’]{2,30}"
required

Ім’я

Може складатися з двох слів (Анна Марія), тому тут є пробіл

maxlength="30"
placeholder="Василь"
pattern="[А-яІіЇїЄєҐґ\s'’]{2,30}"
required

По батькові

maxlength="30"
placeholder="Федорович"
pattern="[А-яІіЇїЄєҐґ'’]{2,30}"

email

maxlength="50"
placeholder="name@example.com"
pattern="[0-9A-Z_a-z\.\-]+@[0-9A-Z_a-z\.\-]+?\.[a-z]{2,}"
required

Перевірити поля по шаблонам і піти на іншу сторінку або скрипт:

В form є action і onsubmit.

onsubmit - запускає bootstrap-перевірку полів, і якщо вона проходить - виконується action.

Поля з pattert - перевіряються по цьому шаблону, якщо у поля є тільки required - поле перевіряєтся на не порожність. Якщо нема ні того, ні іншого - поле не перевіряється.

HTML
<form id="mainform" action="user_login.py" method="POST" class="row g-3 needs-validation" novalidate onsubmit="is_valid();">
    <div class="col-md-4">
        <label for="login" class="form-label">{{ TX_LOGIN }}</label>
        <input type="text" class="form-control" id="login" name="login" aria-describedby="loginHelpBlock" pattern="^[\.@\d\-\A-Za-z]+$" required>
        <div id="loginHelpBlock" class="form-text">{{ TX_HELP_LOGIN }}</div>
        <div class="invalid-feedback">{{ TX_INVALID_INPUT }}</div>
    </div>
    <div class="col-md-8">
    </div>

    <div class="col-md-4">
        <label for="password" class="form-label">{{ TX_PASSWORD }}</label>
        <input type="password" class="form-control" id="password" name="password" aria-describedby="passwordHelpBlock" required>
        <div id="passwordHelpBlock" class="form-text">{{ TX_HELP_PASSWORD }}</div>
        <div class="invalid-feedback">{{ TX_INVALID_INPUT }}</div>
    </div>
    <div class="col-md-8">
    </div>

    <div class="col-12 py-2" id="alertPlace"></div>
    <div class="col-12 text-center">
        <button type="submit" id="bSave" class="btn btn-primary w-50" >{{ TX_ENTER }}</button>
    </div>
</form>
JS
function is_valid()
{
    if (!mainform.checkValidity())
    {
        // "custom Bootstrap form validation" (перевірка за шаблонами)
        event.preventDefault();
        event.stopPropagation();
        // для того, щоб показати які поля не пройшли провірку:
        mainform.classList.add('was-validated');
    }
    else
    {
        // якщо пройшло, щоб не залишалися "зелені" поля з галочками
        mainform.classList.remove('was-validated');
    }
}

Перевірити поля по шаблонам (потім виконати AJAX-запит) і залишитися на цій сторінці:

В цьому прикладі, крім bootstrap-перевірки полів за шаблонами mainform.checkValidity(), ще відбувається перевірка за значеннями: check_param(), потім вже виконується AJAX-запит save_param().

<form id="mainform" class="row g-3 needs-validation" novalidate onsubmit="return false;">

    <div class="col-md-4">
        <label for="tTemp" class="form-label">{{ TX_TEMPERATURE }}, °С</label>
        <input type="text" class="form-control" id="tTemp" name="t_temp" value="{{ TEMPERATURE }}" aria-describedby="tempHelpBlock" autocomplete="off" pattern="^-*\d{1,2}(?:[\.,]\d{0,2})?$">
        <div id="tempHelpBlock" class="form-text">{{ TX_AVERAGE_VALUE }}: <b id="avTemp">{% if AV_TEMP %}{{ AV_TEMP }}{% endif %}</b> °С</div>
        <div class="invalid-feedback">{{ TX_INCORRECT_VALUE }} (-25°С ... 45°С)</div>
    </div>
    <div class="col-md-4">
        <label for="nHumd" class="form-label text-end">{{ TX_HUMIDITY }}, %</label>
        <input type="number" class="form-control" id="nHumd" name="n_humd" value="{{ HUMIDITY }}" aria-describedby="humdHelpBlock" min="10" max="90" step="1">
        <div id="humdHelpBlock" class="form-text">{{ TX_AVERAGE_VALUE }}: <b id="avHumd">{% if AV_HUMD %}{{ AV_HUMD }}{% endif %}</b> %</div>
        <div class="invalid-feedback">{{ TX_INCORRECT_VALUE }} (10% ... 90%)</div>
    </div>
    <div class="col-md-4">
        <label for="tPres" class="form-label text-end">{{ TX_PRESSURE }}, гПа</label>
        <input type="text" class="form-control" id="tPres" value="{{ PRESSURE }}" name="t_pres" aria-describedby="presHelpBlock" autocomplete="off" pattern="^\d{3,4}(?:[\.,]\d{0,2})?$">
        <div id="presHelpBlock" class="form-text">{{ TX_AVERAGE_VALUE }}: <b id="avPres">{% if AV_PRES %}{{ AV_PRES }}{% endif %}</b> гПа</div>
        <div class="invalid-feedback">{{ TX_INCORRECT_VALUE }} (950 - 1050 гПа)</div>
    </div>

    <button type="submit" id="bSave" class="btn btn-primary w-50">{{ TX_SAVE }}</button>
</form>
// --------------------------------------------------------------
mainform.addEventListener('submit', event =>
{
    if (!mainform.checkValidity())
    {
        // спочатку "custom Bootstrap form validation" (перевірка за шаблонами)
        event.preventDefault();
        event.stopPropagation();
        // для того, щоб показати які поля не пройшли провірку
        mainform.classList.add('was-validated');
    }
    else
    {
        // потім - перевірка за значеннями, вимикаємо дію псевдо-класів :invalid та :valid
        mainform.classList.remove('was-validated');
        // і будемо використовувати класи .is-valid та .is-invalid для
        // позначення полів, що не пройшли перевірку
        // https://getbootstrap.com/docs/5.2/forms/validation/
        if (check_param())
        {
            bSave.disabled = true;
            save_param();
        }
        else
        {
            return false;
        }
    }
}, false)


/* --------------------------------------------------------------------- */
function check_param()
{
    if ((tTemp.value + nHumd.value + tPres.value).trim() == '')
    {
        if (!confirm(TX_EMPTY_CONFIRM))
        {
            get_param();
            bSave.disabled = false;
            return false;
        }
    }
    else
    {
        let err = 0;

        if (tTemp.value.trim() != '' && (tTemp.value * 1 < -25 || tTemp.value * 1 > 45))
        {
            valid(tTemp, false);
            err = 1;
        } else {
            valid(tTemp, true);
        }

        if (nHumd.value.trim() != '' && (nHumd.value * 1 < 10 || nHumd.value * 1 > 90))
        {
            valid(nHumd, false);
            err = 1;
        } else {
            valid(nHumd, true);
        }

        if (tPres.value.trim() != '' && (tPres.value * 1 < 950 || tPres.value * 1 > 1050))
        {
            valid(tPres, false);
            err = 1;
        } else {
            valid(tPres, true);
        }

        if (err == 1) return false;
    }
    return true;
}

/* --------------------------------------------------------------------- */
function valid(elem, bl)
{
    if (bl == true)  // set valid
    {
        elem.classList.remove('is-invalid');
        elem.classList.add('is-valid');
    }
    else if (bl == false)  // set invalid
    {
        elem.classList.remove('is-valid');
        elem.classList.add('is-invalid');
    }
    else  // clear all
    {
        elem.classList.remove('is-valid');
        elem.classList.remove('is-invalid');
    }
}

/* --------------------------------------------------------------------- */
function input_disabled(bool)
{
    tTemp.disabled = bool;
    nHumd.disabled = bool;
    tPres.disabled = bool;
    bSave.disabled = bool;
}

/* --------------------------------------------------------------------- */
function save_param_success(resp) {

    const json_obj = resp;
    if (resp && 'res' in resp)
    {
        if (resp.res === 'err')  // error
        {
            errmess = ERROR;
            num_errors = resp.err.length;
            for (let i = 1; i <= num_errors; i++)
            {
                errmess += '<br>' + i +'. '+ resp.err[i-1]
            }
            valid(tTemp);
            valid(nHumd);
            valid(tPres);
            alert('danger', errmess);
        }
        else if (resp.res === 'sux')
        {
            alert('hide');
            // message('sux', resp.sux); // not winXP!
            alert('success', resp.sux);
        }
    }
    else
        alert('danger', SRV_UNKNOWN_RESPONSE);
}

/* --------------------------------------------------------------------- */
function save_param_error(err) {
    console.dir(err);
    alert('danger', SRV_ERR);
}

/* --------------------------------------------------------------------- */
function save_param() {

    let fdata = new FormData(document.forms.mainform);

    fetch("/atmo/save/", { method: "POST", body: fdata })

    .then(resp => {
        if (resp.status != 200) {
            alert('danger', SRV_REFUSED_REQUEST +` Status: ${resp.status}`);
        }
        return resp.json();  // return server response as json
    })
    .then(resp => save_param_success(resp))
    .catch(err => save_param_error(err));
    // return false;  // prevent form submit
}
PreviousBootstrapNextPassword show/hide

Last updated 1 year ago