Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Валидация полей для ввода (https://javascript.ru/forum/events/83470-validaciya-polejj-dlya-vvoda.html)

Paulsw01 17.12.2021 19:59

Валидация полей для ввода
 
Как реализовать что бы при потере фокуса происходила проверка на корректность введённого значения и замена его на корректное при необходимости по следующим правилам:
Из строки значения должны удаляться все символы, кроме допустимых.
Пробелы и дефисы в начале и конце значения должны удаляться.
Несколько идущих подряд пробелов или дефисов должны заменяться на один.
Первая буква должна приводиться к верхнему регистру, а все остальные — к нижнему.

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

<form id="form" onsubmit="return false;">
    <input type="text" class="validation" id='surname' placeholder="Фамилия" />
    <input type="text" class="validation" id='name' placeholder="Имя" />
    <input type="text" class="validation" id='patronymic' placeholder="Отчество" />
    <button id="button" class="btn btn-success" >Отправить</button>
  </form>


let surname = document.getElementById("surname")
let inputName = document.getElementById("name")
let patronymic = document.getElementById("patronymic")
let button = document.getElementById("button")
let form = document.getElementById("form")

let p = document.createElement('p');

let inp = document.querySelector('.validation')

let surnameStr = inp.textContent


function validation(inp) {

inp.addEventListener('input', function () {
  this.value = this.value.replace(/[^А-Яа-яЁё -]/g, '')

  function changeStr(surnameStr) {
    surnameStr.replace(/\s+/g, ' ')
    surnameStr.replace(/^([-=\s]*)([a-zA-Z0-9])/gm, "$2")

    if (!surnameStr) return surnameStr;
    return surnameStr[0].toUpperCase() + surnameStr.slice(1)
  }

  changeStr()
})
}

validation(surname)
validation(inputName)
validation(patronymic)

document.forms[0].addEventListener('change', function (e) {
  if (e.target.tagName = 'INPUT') e.target.value = e.target.value.charAt(0).toUpperCase() + e.target.value.slice(1)
})

button.onclick = function() {
  let text = surname.value + ' ' + inputName.value + ' ' +  patronymic.value;
  p.innerHTML = text;
  form.append(p)
};

ksa 17.12.2021 20:58

Цитата:

Сообщение от Paulsw01
Пробелы и дефисы в начале и конце значения должны удаляться.

Как вариант...
const val = '  -пример ---'
const re = /^[\s-]*|[\s-]*$/g
alert(val.replace(re, ''))

ksa 17.12.2021 21:11

Цитата:

Сообщение от Paulsw01
Несколько идущих подряд пробелов или дефисов должны заменяться на один.

Как вариант...
const val = '> -  - пример ---'
let re = /(\s){2,}/g
alert(val.replace(re, '$1'))
re = /(-){2,}/g
alert(val.replace(re, '$1'))

voraa 17.12.2021 21:12

replace не меняет исходную строку, а возвращает новую с заменами
Строки 20 - 21 должны быть так
surnameStr = surnameStr
      .replace(/\s+/g, ' ')
      .replace(/^([-=\s]*)([a-zA-Z0-9])/gm, "$2")

Для удаления пробелов вначале и конце trim()

ksa 17.12.2021 21:13

Цитата:

Сообщение от Paulsw01
Из строки значения должны удаляться все символы, кроме допустимых.

Как вариант...
const val = '> -  - пример 123 NG ---'
const re = /[123NG]/g
alert(val.replace(re, ''))

рони 17.12.2021 21:21

валидация формы
 
Paulsw01,

<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const form = document.getElementById("form");
            function validation(input) {
                let txt = input.value.trim();
                let reg = /(^[^А-Яа-яЁё]+)|([^А-Яа-яЁё]+$)/g;
                txt = txt.replace(reg, '');
                reg = /[-\s]+/g;
                txt = txt.replace(reg, ([a, ...b]) => a);
                reg = /[^А-Яа-яЁё\s-]/g;
                txt = txt.replace(reg, '');
                txt = txt.toLowerCase();
                reg = /^./;
                txt = txt.replace(reg, a => a.toUpperCase());
                if (txt !== input.value) input.value = txt;
                return !!txt.length;
            }
            form.addEventListener("focusout", function({
                target
            }) {
                if (target = target.closest(".validation")) validation(target)
            })
            let timer;
            form.addEventListener("submit", function(event) {
                event.preventDefault();
                let inputs = Array.from(this.querySelectorAll(".validation"));
                let validate = inputs.every(validation);
                let txt = "Не все поля заполнены правильно!"
                if (validate) txt = inputs.map(({
                    value
                }) => value).join(" ");
                out.innerHTML = txt;
                window.clearTimeout(timer);
                if (!validate) timer = window.setTimeout(_ => out.innerHTML = "", 10000)
            })
        });
    </script>
</head>
<body>
    <p id="out"></p>
    <form id="form" >
        <input type="text" class="validation" id='surname' placeholder="Фамилия" />
        <input type="text" class="validation" id='name' placeholder="Имя" />
        <input type="text" class="validation" id='patronymic' placeholder="Отчество" />
        <button id="button" class="btn btn-success">Отправить</button>
    </form>
</body>
</html>

voraa 17.12.2021 21:36

Ну нельзя же так!

рони, не учи плохому.

Показывать сообщение на 2 сек!
А что, человек не имеет права отвернуться? глаза прикрыть после тяжкого ввода?
Моргнул, не увидел сообщения и довольный сидишь ждешь до посинения.

рони 17.12.2021 21:39

voraa,
что мешает время показа увеличить(строка 41 параметр 2000) или отменить(закомментируйте строки 40-41), сделав свой вывод ошибок. )))

voraa 17.12.2021 21:44

рони, Ничего не мешает.
Просто, имея больший опыт, не надо показывать такие примеры.
Вообще грамотным интерфейсам надо учить и учить.
А то столько кошмара приходится видеть.

рони 17.12.2021 21:47

voraa,
не понимаю, увеличил время показа до 10 секунд.

voraa 17.12.2021 22:34

Двух секунд может быть мало, а 10 слишком много... Не в секундах дело.
Ну как тебе объяснить...
Сообщения не должны посылаться в пустоту. Особенно сообщения об ошибках.
Они не должны самопроизвольно пропадать. Система должна убедиться, что юзверь их хотя бы увидел. Т.е они должны пропадать только после действий этого юзверя. Например он нажмет кнопку ОК на сообщении или закроет его крестиком или начнет редактировать поле в котором встретилась ошибка.

рони 17.12.2021 22:57

voraa,
в данном случае делать полноценный вывод, считаю излишним, задание видимо тестовое, но и совсем оставлять без вывода ошибок тоже решил не корректно, считай что это "заглушка" типа console.log.
с выводами твоими согласен, но тут до продакшен ой как далеко.

рони 17.12.2021 23:25

voraa,
а так? )))
<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const form = document.getElementById("form");
            const inputs = Array.from(form.querySelectorAll(".validation"));
            const err = "Не все поля заполнены правильно!";
            function validation(input) {
                let txt = input.value.trim();
                let reg = /(^[^А-Яа-яЁё]+)|([^А-Яа-яЁё]+$)/g;
                txt = txt.replace(reg, '');
                reg = /[-\s]+/g;
                txt = txt.replace(reg, ([a, ...b]) => a);
                reg = /[^А-Яа-яЁё\s-]/g;
                txt = txt.replace(reg, '');
                txt = txt.toLowerCase();
                reg = /^./;
                txt = txt.replace(reg, a => a.toUpperCase());
                if (txt !== input.value) input.value = txt;
                return !!txt.length;
            }
            form.addEventListener("focusout", function({target}) {
                if (target = target.closest(".validation")) validation(target)
            })
            function validateAll()
            {
               let validate = inputs.every(validation);
               return validate
            }
            function personality()
            {
               let txt = inputs.map(({ value }) => value).join(" ");
               return txt
            }
            form.addEventListener("submit", function(event) {
                event.preventDefault();
                let validate = validateAll();
                if(validate) {
                let txt = personality();
                out.insertAdjacentHTML('beforeend', `<li>${txt}</li>`);
                form.reset();
                }
                else attention.innerHTML = err;
            })
            form.addEventListener("input", function({target}) {
            if (target = target.closest(".validation")  && attention.innerHTML === err) attention.innerHTML = "";
            })
        });
    </script>
</head>
<body>
    <form id="form">
        <input type="text" class="validation" id='surname' placeholder="Фамилия" />
        <input type="text" class="validation" id='name' placeholder="Имя" />
        <input type="text" class="validation" id='patronymic' placeholder="Отчество" />
        <button id="button" class="btn btn-success">Отправить</button>
    </form>
    <div id="attention"></div>
    <ul id="out"></ul>
</body>
</html>

Paulsw01 18.12.2021 06:43

Как сделать чтобы после правильной оправки формы форма очищалась, и каждый новый ввод не перезаписывал, а добавлял новый параграф?

рони 18.12.2021 08:45

Цитата:

Сообщение от Paulsw01
Как сделать

а самому ...?
добавлено, пост #13


Часовой пояс GMT +3, время: 00:19.