Область видимости, создание переменных с помощью цикла
Есть ряд переменных
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; |
Решил задачу в 3 массива, мб кому пригодится, в итоге довольно удобно вышло
вынес в отдельный файл все функции и обработчики
$(document).ready(function(){ $('input[type=checkbox]').val('Нет'); $('input[type=checkbox]:checked').val('Да'); $('input[type=checkbox]').change(function () { if (this.checked) { this.value = 'Да'; } else { this.value = 'Нет'; } }); }); $(document).ready(function(){ $('input[type=radio]').val('Не выбрано'); $('input[type=radio]').click(function () { name = $(this).attr("name") label= $(this).next("label"); radio = document.getElementsByName(name); $.each(radio, function( key, value ) { value.value = label.text() }); }); }); //////////////////////////////////////////////////////// ////////////Функции проверки формы начало/////////////// //////////////////////////////////////////////////////// function validnot(text) {return true} ///////////Проверка заполнения телефона///////// function validphone(text) { text_val = text.val(); var pattern1 = /^\+[\d]{1}\ \([\d]{2,3}\)\ [\d]{2,3}-[\d]{2,3}-[\d]{2,3}$/; var pattern2 = /^\d[\d\(\)\ -]{4,14}\d$/; var pattern3 = /^[\d]{10,11}$/; if (pattern1.test(text_val) == true) { $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else if (pattern2.test(text_val) == true) { $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else if (pattern3.test(text_val) == true) { $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else { $(text).removeClass("accept"); $(text).addClass("error"); $(text).next(".error_block").css("display","block"); errorcount++; } } ///////////Проверка заполнения radio///////// function validradio(text) { countradio = 0; $.each( text, function( key, value ) { if ($(value).is(':checked')) { countradio++; } else {} }); if (countradio > 0){ $.each( text, function( key, value ) { label = $(value).next("label"); $(label).next(".error_block").css("display","none"); }); } else { $.each( text, function( key, value ) { label = $(value).next("label"); $(label).next(".error_block").css("display","block"); }); errorcount++; } } ///////////Проверка Select///////// function validselect(text) { text_val = text.val(); if (text_val == "" || text_val == " "){ errorcount++; } else {} } ///////////Проверка checkbox///////// function validcheck(text){ text_val = text.val(); label = $(text).next("label"); if (text.is(':checked')){ $(label).next(".error_block").css("display","none"); } else { $(label).next(".error_block").css("display","block"); errorcount++; } } ///////////////////// Проверка длинны текста//////////////////// function validlenght(text) { text_val = text.val(); var limit = 5; //////Максимальная длинна текста///////// var text_length = text_val.length; if (text_val == "" || text_val == " "){ $(text).removeClass("accept"); $(text).addClass("error"); $(text).next(".error_block").css("display","block"); errorcount++; } else if (text_length > limit){ $(text).removeClass("accept"); $(text).addClass("error"); $(text).next(".error_block").css("display","block"); errorcount++; } else { $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } } ///////////Проверка наличия текста///////// function validtext(text) { text_val = text.val(); if (text_val == "" || text_val == " "){ $(text).removeClass("accept"); $(text).addClass("error"); $(text).next(".error_block").css("display","block"); errorcount++; } else { $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } } ///////////Проверка наличия текста (только буквы)///////// function validname(text) { text_val = text.val(); var pattern = /^[a-zа-яё]+$/i; if (pattern.test(text_val) == true) { $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else { $(text).removeClass("accept"); $(text).addClass("error"); $(text).next(".error_block").css("display","block"); errorcount++; } } ///////////Проверка заполнения E-mail///////// function validmail(text) { text_val = text.val(); var pattern = /^[\w\.\d-_]+@[\w\.\d-_]+\.\w{2,4}$/i; if (pattern.test(text_val) == true) { $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else { $(text).removeClass("accept"); $(text).addClass("error"); $(text).next(".error_block").css("display","block"); errorcount++; } } /////////Проверка заполнения даты///////// function validdate(text) { text_val = text.val(); var pattern1 = /^[\d]{1,2}\/[\d]{1,2}\/[\d]{4}$/; var pattern2 = /^[\d]{1,2}\.[\d]{1,2}\.[\d]{4}$/; var pattern3 = /^[\d]{1,2}\,[\d]{1,2}\,[\d]{4}$/; var pattern4 = /^[\d]{1,2}\-[\d]{1,2}\-[\d]{4}$/; var pattern5 = /^[\d]{1,2}\\[\d]{1,2}\\[\d]{4}$/; if (pattern1.test(text_val) == true){ $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else if (pattern2.test(text_val) == true){ $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else if (pattern3.test(text_val) == true){ $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else if (pattern4.test(text_val) == true){ $(text).removeClass("error"); $(text).addClass("accept"); $(text).next(".error_block").css("display","none"); } else { $(text).removeClass("accept"); $(text).addClass("error"); $(text).next(".error_block").css("display","block"); errorcount++; } } ///////////////////////////////////////////////////////// //////////////Функции проверки формы конец/////////////// ///////////////////////////////////////////////////////// function set_alerts_forms(text){ $.each(text, function () { $.each(this, function (name, value) { var name = document.getElementsByName(name); alert_block = $("<p class='error_block'>"+value+"</p>"); checklabel(name); function checklabel(text){ if($(text).next().is('label')) { label = $(text).next("label"); $(label).after(alert_block) } else { $(text).after(alert_block) } }; }); }); } function set_valids_forms(text){ $.each(text, function () { $.each(this, function (name, value) { var name = document.getElementsByName(name); $(name).change(function(){eval(value)($(name))}); }); }); } function set_valids_onsend_forms(text){ $.each(text, function () { $.each(this, function (name, value) { var name = document.getElementsByName(name); eval(value)($(name)); }); }); } function set_messege_forms(text){ $.each(text, function () { $.each(this, function (name, value) { var name = document.getElementsByName(name); text_val = $(name).val(); key = value; message += key +' '+ text_val +'\r\n'; }); }); } function sendform(key, validator, form_block){ errorcount = 0; set_valids_onsend_forms(validator); if (errorcount == 0){ message = ''; set_messege_forms(key); alert('Ваше сообщение успешно отправлено'); alert(message); clearform(form_block); } else { return false; } } function clearform (text){ $(text).each(function(){ elem = $(this).find('input[type=text],textarea'); $.each(elem, function (name, value){ value.value = ''; }); }); } function MyMailer(nameform, validators, alerts, keys){ var this_form = document.getElementById(nameform); var Submit = $(this_form).find("button"); errorcount = 0; set_valids_forms(validators); set_alerts_forms(alerts); $(Submit).click(function(){ sendform(keys, validators, alerts) }) } |
и массив + активация формы
///////////////////////////////////////////////////////////////////////////////// ///////////////////////Массивы блоков формы ///////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// var json_form1_validator = [ {'family': 'validname'}, {'name': 'validname'}, {'phone': 'validphone'}, {'mail': 'validmail'}, {'date': 'validdate'}, {'check': 'validcheck'}, {'radio': 'validradio'}, {'text': 'validlenght'}, {'select': 'validselect'} ]; var json_form1_alerts = [ {'family': 'Ошибка при вводе фамилии!!!'}, {'name': 'Ошибка при вводе имени!!!'}, {'phone': 'Ошибка при вводе телефона!!!'}, {'mail': 'Ошибка при вводе Email!!!'}, {'date': 'Ошибка при вводе даты!!!'}, {'check': 'Не подтверждено!!!'}, {'radio': 'Не выбран элемент!!!'}, {'text': 'Поле не заполнено!!!'}, {'select': ''} ]; var json_form1_keys = [ {'family': 'Фамилия:'}, {'name': 'Имя:'}, {'phone': 'Телефон:'}, {'mail': 'E-mail:'}, {'date': 'Дата отправки:'}, {'check': 'Check статус:'}, {'radio': 'Пол:'}, {'text': 'Сообщение:'}, {'select': 'Год рождения:'} ]; $("input[name=phone]").mask('+3 (999) 999-99-99');/////////подключение маски телефона /////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////SEND MAIL + ONLINE VALIDATION//////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////Имя формы/////Массив валидации/////Массив алертов////Массив ключей//////////////// MyMailer(form1, json_form1_validator, json_form1_alerts, json_form1_keys);///////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// |
Цитата:
Цитата:
Цитата:
А ваши clearform, функция отправки по нажатию на кнопку. Зачем заново изобретать функционал? Зачем ограничение по нажатию? Неужели нельзя просто отравлять форму любым способом? А если автозаполнение? А если голосовой ввод? Ещё есть у нативной формы такая вещь, что если нажать на Enter у правильно заполненной формы, то форма отправится. Вы это зачем-то выключили? И зачем на каждом изменении полей вызывать eval? Это можно сделать без eval! Очень грязное, неочевидное решение, которое всё-таки отправит форму (а это вообще форма? Если нет то это очень плохое решение!) на сервер, если JavaScript отвалится. Цитата:
|
Спасибо за то что указали на ошибки, но я учу javascript по сути неделю после основной работы, так что ошибки естественны. В данный момент это решение удовлетворяет мои потребности, в дальнейшем я наверняка перепишу всё. Но на текущем уровне развития меня хватило только на это. В любом случае ещё раз спасибо что указали на проблемы с этим кодом, и спасибо всем кто давал подсказки.
|
Цитата:
|
Цитата:
Нет предела совершенству, вырасту по навыкам - сделаю лучше |
Часовой пояс GMT +3, время: 15:17. |