Форма не видит, что input заполнен. Если заполнить все поля, то выдает ошибку "заполните все поля"
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById("form");
form.addEventListener('submit', formSend);
async function formSend(e) {
e.preventDefault();
let error = formValidate(form);
let formData = new FormData(form);
if (error === 0 ) {
form.classList.add('_sending');
let response = await fetch ('sendmail.php', {
method: 'POST',
body: formData
})
if (response.ok) {
let result = await response.json();
alert(result.message);
form.reset ();
} else {
alert ('Кажется что-то пошло не так')
}
} else {
alert ('Если хочешь отправить нам сообщение, то заполни все поля, пожалуйста)');
}
}
function formValidate(form) {
let error = 0;
let formReq = document.querySelectorAll('._req')
for (let index = 0; index < formReq.length; index++){
const input = formReq[index];
formRemoveError(input);
if(input.classList.contains('_email')){
if(emailTest(input)){
formAddError(input);
error++;
}
} else {
if (input.value === ""){
formAddError(input);
error++;
}
}
}
return error;
}
function formAddError(input) {
input.parentElement.classList.add('_error');
input.classList.add('_error')
}
function formRemoveError(input) {
input.parentElement.classList.remove('_error');
input.classList.remove('_error');
}
function emailTest(input) {
return !/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,8})+$/.test(input.value);
}
})
<HTML>
<BODY>
<form id="form" action="#" class="form_body">
<div class="form_item">
<label class="form_label _req" for="formName">Твоё имя</label>
<input type="text" name="name" id="formName" class="form_input">
</div>
<div class="form_item">
<label class="form_label _email _req" for="formEmail">Твоя почта</label>
<input type="text" name="email" id="formEmail" class="form_input">
</div>
<div class="form_item">
<label class="form_message _req" for="formEmail">Твоё сообщение</label>
<textarea name="message" id="formMessage" class="form_label"></textarea>
</div>
<button type="submit" class="form_button">Отправить</button>
</form>
</BODY>
</HTML>
Ответы (1 шт):
Здравствуй, Настя.
Не наговаривай на форму, форма всё видит ?
Давай разберёмся в проблеме с твоим кодом. Рассмотрим что выдаст такой вот javascript:
const label = document.getElementById("form");
let formReq = document.querySelectorAll('._req')
for (let index = 0; index < formReq.length; index++){
const label = formReq[index];
console.log(label)
}
Вывод:
<label class="form_label _req" for="formName"></label>
<label class="form_label _email _req" for="formEmail"></label>
<label class="form_message _req" for="formEmail"></label>
Я намеренно переименовал переменную input из твоего кода в label, т.к. в переменную записывается именно этот тег.
<label> не содержит пользовательского ввода сам по себе, данный тег используется для установки связи между меткой и элементом формы (<input>, <select>, <textarea>).
Подробнее можно почитать тут. Или ещё чуть подробнее на английском про создание связи тут.
У тебя связь выстроена почти правильно, у каждой <label> есть атрибут for который ссылается на ввод. Обрати внимание на <textarea> c id formMessage, там связь неправильная, <label> ссылается на formEmail.
Поправим эту ошибку в html и запустим несколько видоизменённый код:
const form = document.getElementById("form");
let formReq = document.querySelectorAll('._req')
for (let index = 0; index < formReq.length; index++){
const label = formReq[index];
const input = document.getElementById(label.htmlFor);
console.log(input);
}
Вывод:
<input type="text" name="name" id="formName" class="form_input">
<input type="text" name="email" id="formEmail" class="form_input">
<textarea name="message" id="formMessage" class="form_label"></textarea>
Вот и чудесно, теперь обращаемся к <input>, с которого как раз и будем брать значения.
По итогу, что необходимо сделать, чтобы было чудесно:
- Поправить атрибут
forв 3-ем<label>и вписать туда formMessage. - Объявить в цикле переменную
labelи переписать присвоение переменнойinput. - В
if(input.classList.contains('_email')){заменить переменную сinputнаlabel.
Альтернатива
В качестве альтернативы, можешь переместить классы _req и _email с <label> на <input> и <textarea> соответственно, тогда в javascript коде ничего менять не надо будет.
К тому же ранее предложенное решение будет работать только с правильно прописанными атрибутами for, которые у тебя прописаны неправильно. Да и <label> ты нигде не используешь, поэтому есть смысл сразу напрямую обращаться к вводу.
<form id="form" action="#" class="form_body">
<div class="form_item">
<label class="form_label">
Твоё имя
<input type="text" name="name" class="form_input _req">
</label>
</div>
<div class="form_item">
<label class="form_label">
Твоя почта
<input type="text" name="email" class="form_input _email _req">
</label>
</div>
<div class="form_item">
<label class="form_message">
Твоё сообщение
<textarea name="message" class="form_label _req"></textarea>
</label>
</div>
<button type="submit" class="form_button">Отправить</button>
</form>
Здесь я атрибуты id и for убрал, т.к. использую альтернативную связку, подробнее в первой ссылке:
Существует два способа связывания объекта и метки. Первый заключается в использовании идентификатора
idвнутри элемента формы и указании его имени в качестве атрибутаforтега<label>. При втором способе элемент формы помещается внутрь контейнера<label>.
Если атрибут id где-то ещё используется, то можно его оставить.
После переноса классов javascript можно не менять.
Но поменять его всё равно следует, т.к. в текущем состоянии при неправильном вводе почты сообщение будет как при пустом вводе, что совсем не user-friendly. Но это уже выходит за рамки заданного вопроса.