17.09.2019, 11:56
|
Аспирант
|
|
Регистрация: 01.02.2018
Сообщений: 33
|
|
Область видимости, создание переменных с помощью цикла
Есть ряд переменных
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, 17.09.2019 в 11:59.
|
|
17.09.2019, 12:04
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,108
|
|
Mikael86,
в чём проблема?
|
|
17.09.2019, 12:08
|
Аспирант
|
|
Регистрация: 01.02.2018
Сообщений: 33
|
|
Сообщение от рони
|
Mikael86,
в чём проблема?
|
arr_form = ['family', 'name', 'date', 'select', 'email', 'phone', 'text'];
arr_form.forEach(function(element) {
element = document.getElementsByName(element);
console.log(element[0].value);
});
Такое решение не работает с функциями, переменные как я понял существуют только внутри цикла
$(name).change(function(){validname($(name));});
|
|
17.09.2019, 12:16
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,108
|
|
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))});
});
|
|
17.09.2019, 12:20
|
Аспирант
|
|
Регистрация: 01.02.2018
Сообщений: 33
|
|
Немного не то и присвоить разные валидаторы не выйдет и похоже будет работать не онлайн а только в пределах цикла.
validdate, validmail, validtext, validlenght и другие подключаются по ситуации. Извиняюсь вы правы, функция постоянно работает, попробую переформировать массив и формат считывания под значение - опцию. Огромное спасибо, как всегда меня выручаете)
Последний раз редактировалось Mikael86, 17.09.2019 в 12:24.
|
|
17.09.2019, 12:21
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,108
|
|
Mikael86,
|
|
19.09.2019, 02:56
|
Аспирант
|
|
Регистрация: 01.02.2018
Сообщений: 33
|
|
Проблемы со считыванием двухмерного массива обрезает значения
перестроил массив под автоматическую генерацию проверок и вычитку,
попытался прогнать через цикл - не заработало. В консоли при попытке вычитать запросы увидел
интересную картинку - все значения 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');/////////подключение маски телефона
});
Последний раз редактировалось Mikael86, 19.09.2019 в 02:59.
|
|
19.09.2019, 03:11
|
Аспирант
|
|
Регистрация: 01.02.2018
Сообщений: 33
|
|
При удалении наружного цикла функция добавления alert-ов заработала, но функции onchange все так же не пашут.
$(name).change(function(){eval(validator)($(name))});
|
|
19.09.2019, 07:10
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от Mikael86
|
Есть ряд переменных
|
Вы можете взять все элементы вашей формы и с уже ними работать. (Например, const elements = document.querySelector("#form").elements;)
Сообщение от Mikael86
|
функции onchange все так же не пашут.
|
Событие change всплывает при изменении поля, вы можете на него подписаться и проверять, правильно ли заполнено поле при его изменении
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, 19.09.2019 в 08:01.
|
|
19.09.2019, 08:23
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,108
|
|
Malleys,
может строка 129 лишняя?
for(const errorMessage of label.querySelectorAll(".error-message"))
errorMessage.remove();
и её можно заменить на
if(label.querySelector(".error-message")) continue;
|
|
|
|