Область видимости, создание переменных с помощью цикла
Есть ряд переменных
var family = document.getElementsByName("family"); var name = document.getElementsByName("name"); var select = document.getElementsByName("select"); var date = document.getElementsByName("date"); var email = document.getElementsByName("email"); var phone = document.getElementsByName("phone"); var text = document.getElementsByName("text"); из них запускаются функции $(family).change(function(){validname($(family));}); $(name).change(function(){validname($(name));}); $(select).change(function(){validtext($(select));}); $(date).change(function(){validdate($(date));}); $(email).change(function(){validname($(email));}); $(phone).change(function(){validphone($(phone));}); $(text).change(function(){validlenght($(text));}); Вопрос, можно ли их генерировать циклом из массива что то вроде такого arr_form = ['family', 'name', 'date', 'select', 'email', 'phone', 'text']; arr_form.forEach(function(element) { element = document.getElementsByName(element); console.log(element[0].value); }); Я так понимаю проблема в области видимости, потому такое решение не взаимодействует с функциями. Пробовал вариант с let но наверное что то не так прописал. В идеале целью было создать массив ключ-опция, где ключ имя переменной, опция - функция. Что то вроде такого // значения по умолчанию let [firstName="Гость", lastName="Анонимный"] = []; alert(firstName); // Гость alert(lastName); // Анонимный |
Mikael86,
:-? в чём проблема? |
Цитата:
arr_form.forEach(function(element) { element = document.getElementsByName(element); console.log(element[0].value); }); Такое решение не работает с функциями, переменные как я понял существуют только внутри цикла $(name).change(function(){validname($(name));}); |
Mikael86,
var arr_form = ['family', 'name', 'date', 'select', 'email', 'phone', 'text']; arr_form.forEach(function(name) { var element = document.getElementsByName(name)[0]; $(element).change(function(){validname($(element))}); }); |
Немного не то и присвоить разные валидаторы не выйдет и похоже будет работать не онлайн а только в пределах цикла.
validdate, validmail, validtext, validlenght и другие подключаются по ситуации. Извиняюсь вы правы, функция постоянно работает, попробую переформировать массив и формат считывания под значение - опцию. Огромное спасибо, как всегда меня выручаете) |
Mikael86,
:-? |
Проблемы со считыванием двухмерного массива обрезает значения
перестроил массив под автоматическую генерацию проверок и вычитку,
попытался прогнать через цикл - не заработало. В консоли при попытке вычитать запросы увидел интересную картинку - все значения key, name, validator, alert обрезаны до 4х символов. Сам массив var json_form = [ ['Фамилия:', 'family', 'validname', 'Ошибка при вводе фамилии!!!'], ['Имя:', 'name', 'validname', 'Ошибка при вводе имени!!!'], ['Телефон:', 'phone', 'validphone', 'Ошибка при вводе телефона!!!'], ['E-mail:', 'mail', 'validmail', 'Ошибка при вводе Email!!!'], ['Дата отправки:', 'date', 'validdate', 'Ошибка при вводе даты!!!'], ['Check статус:', 'check', 'validcheck', 'Не подтверждено!!!'], ['Пол:', 'radio', 'validradio', 'Не выбран ни один элемент!!!'], ['Сообщение:', 'text', 'validlenght','Поле не заполнено или превышено количество символов!!!'], ['Год рождения:', 'select', 'validselect','Не выбрано'] ]; Цикл считывания $('#form').ready(function(){ errorcount = 0; $.each(json_form, function () { $.each(this, function(row, value) { key = value[0]; name = value[1]; validator = value[2]; alert = value[3]; console.log(key + name + validator + alert); alert_block = $("<p class='error_block'>"+alert+"</p>"); var name = document.getElementsByName(name); checklabel(name); function checklabel(text){ if($(text).next().is('label')) { label = $(text).next("label"); $(label).after(alert_block) } else { $(text).after(alert_block) } }; $(name).change(function(){eval(validator)($(name))}); }); }); $("input[name=phone]").mask('+3 (999) 999-99-99');/////////подключение маски телефона }); |
При удалении наружного цикла функция добавления alert-ов заработала, но функции onchange все так же не пашут.
$(name).change(function(){eval(validator)($(name))}); |
Цитата:
Цитата:
addEventListener("change", ({ target }) => { target.checkValidity(); }); Выберите все элементы, которые вас интересуют и подпишитесь на событие invalid, которое происходит при проверке неправильно заполненного поля. Не нужно создавать отдельные массивы с описанием, как должны проверятся поля, для этого есть сами поля. Для этого есть CSS-селекторы :valid, :invalid, методы для проверки, событие invalid. Вот пример, составленный на основе вашего описания... <style> form { max-width: 20em; padding: 1em; margin: auto; font: 1em system-ui; } form > * { display: flex; flex-direction: column; margin-bottom: 1em; } input, button, select, textarea { font: inherit; } textarea { resize: vertical; } fieldset { border: 1px solid #f1f1f1; border-radius: 0.5em; flex-direction: row; } input:not([type]), input[type="tel"], input[type="email"], input[type="date"], input[type="number"], textarea { border: none; border-radius: 0.5em; background: #f1f1f1; padding: 0.5em; } span.error-message { padding: 0.5em; border-radius: 0.5em; color: #F44336; font-size: 80%; font-weight: bold; display: block; } :valid + span.error-message { display: none; } </style> <form> <label> Фамилия <input name="family" required autocomplete="family-name" minlength="1" pattern="\s*\S([\s\S]*\S)?\s*" data-custom-validity="Введите свою фамилию!"> </label> <label> Имя <input name="name" required autocomplete="given-name" minlength="1" pattern="\s*\S([\s\S]*\S)?\s*" data-custom-validity="Введите своё имя!"> </label> <label> Телефон <input name="phone" type="tel" required autocomplete="tel" data-custom-validity="Введите свой номер телефона!"> </label> <label> Э-почта <input name="mail" type="email" required autocomplete="email" data-custom-validity="Введите свой Email!"> </label> <label> Дата отправки <input name="date" type="date" required data-custom-validity="Введите дату!"> </label> <fieldset> <legend>Подтверждение</legend> <label> <input name="check" type="checkbox" required data-custom-validity="Подтвердите!"> Согласен с условиями </label> </fieldset> <fieldset> <legend>Пол</legend> <label> <input name="radio" type="radio" value="male" required autocomplete="sex" data-custom-validity="Выберите свой пол!"> Мужчина </label> <label> <input name="radio" type="radio" value="female" required autocomplete="sex" data-custom-validity="Выберите свой пол!"> Женщина </label> </fieldset> <label> Сообщение <textarea name="text" required minlength="10" maxlength="1500" data-custom-validity="Заполните поле (от 10 до 1500 символов)!"></textarea> </label> <label> Год рождения <input name="select" type="number" min="1880" max="2001" step="1" required autocomplete="bday-year" size="4" data-custom-validity="Введите год рождения (18+)"> </label> <button>Отправить</button> </form> <script> addEventListener("change", ({ target }) => { target.checkValidity(); }); for(const element of document.querySelector("form").elements) { element.addEventListener("invalid", event => { event.preventDefault(); for(const label of event.target.labels) { for(const errorMessage of label.querySelectorAll(".error-message")) errorMessage.remove(); const errorMessage = document.createElement("span"); errorMessage.className = "error-message"; errorMessage.textContent = event.target.dataset.customValidity || event.target.validationMessage; label.append(errorMessage); } }); } </script> |
Malleys,
может строка 129 лишняя? for(const errorMessage of label.querySelectorAll(".error-message")) errorMessage.remove(); и её можно заменить на if(label.querySelector(".error-message")) continue; |
Часовой пояс GMT +3, время: 17:15. |