15-bo‘lim
Formalar va validatsiya
Forma elementlari bilan ishlash, submit hodisasi, FormData, brauzer validatsiyasi va o'z tekshiruvlaringiz.
Ushbu bo‘lim mundarijasi
Forma - foydalanuvchi bilan ilova o'rtasidagi asosiy ko'prik. Uni to'g'ri ishlatish ma'lumot sifatini belgilaydi.
document.body.innerHTML = `
<form id="ariza">
<input type="text" name="ism" id="ism" required minlength="3">
<input type="email" name="email" id="email" required>
<input type="number" name="yosh" id="yosh" min="18" max="100">
<input type="checkbox" name="shartlar" id="shartlar">
<select name="shahar" id="shahar">
<option value="">Tanlang</option>
<option value="nam">Namangan</option>
<option value="tosh">Toshkent</option>
</select>
<textarea name="izoh" id="izoh"></textarea>
<input type="radio" name="jins" value="erkak" id="erkak">
<input type="radio" name="jins" value="ayol" id="ayol">
<button type="submit">Yuborish</button>
</form>`;
Qiymatlarni o'qish #
const ism = document.getElementById("ism");
const shartlar = document.getElementById("shartlar");
const shahar = document.getElementById("shahar");
ism.value = "Husanboy";
shartlar.checked = true;
shahar.value = "nam";
console.log("Matn maydoni :", ism.value);
console.log("Katakcha :", shartlar.checked);
console.log("Tanlangan :", shahar.value);
console.log("Tanlangan matn:", shahar.selectedOptions[0].textContent);
// Radio - guruhdan tanlanganini topish
document.getElementById("ayol").checked = true;
const jins = document.querySelector("input[name='jins']:checked");
console.log("Radio :", jins.value);
// Son maydoni - value HAR DOIM satr
const yosh = document.getElementById("yosh");
yosh.value = "25";
console.log("yosh.value turi :", typeof yosh.value);
console.log("yosh.valueAsNumber :", typeof yosh.valueAsNumber);
Matn maydoni : Husanboy
Katakcha : true
Tanlangan : nam
Tanlangan matn: Namangan
Radio : ayol
yosh.value turi : string
yosh.valueAsNumber : number
input.value har doim satrBu eng ko'p uchraydigan forma xatosi:
const yosh = document.getElementById("yosh").value; // "25" - satr!
if (yosh > 18) { } // ishlaydi - satr songa aylanadi
console.log(yosh + 1); // "251" (!) - satr ulanadi
type="number" bo'lsa ham .value satr qaytaradi.
Uch yechim:
Number(maydon.value) // 25
parseInt(maydon.value, 10) // 25
maydon.valueAsNumber // 25 - eng toza
valueAsNumber afzal: u type="number" va type="date"
uchun maxsus yaratilgan va bo'sh maydonda NaN qaytaradi
(Number("") esa 0 beradi - bu xato manbai).
Number("") // 0 - xavfli!
document.getElementById("yosh").valueAsNumber // NaN - to'g'ri
submit hodisasi #
const forma = document.getElementById("ariza");
let yuborildi = false;
let malumot = null;
forma.addEventListener("submit", (hodisa) => {
hodisa.preventDefault(); // sahifa qayta yuklanmasin
yuborildi = true;
malumot = {
ism: forma.ism.value,
email: forma.email.value
};
});
// Maydonlarni to'ldiramiz
forma.ism.value = "Malika";
forma.email.value = "[email protected]";
forma.dispatchEvent(new Event("submit", { bubbles: true, cancelable: true }));
console.log("Yuborildimi?:", yuborildi);
console.log("Ism :", malumot.ism);
console.log("Email :", malumot.email);
Yuborildimi?: true
Ism : Malika
Email : [email protected]
forma.ism yozuvi ishlaydi - forma o'z maydonlariga name
atributi bo'yicha murojaat qilish imkonini beradi:
forma.ism.value // <input name="ism">
forma.elements.ism // aniqroq yozuv
forma.elements["email"] // nomda chiziqcha bo'lsa
forma.elements ishlatish afzalroq - u faqat maydonlarni
qaytaradi va formaning o'z xossalari bilan chalkashmaydi.
Masalan <input name="id"> bo'lsa, forma.id maydonni emas,
formaning id atributini qaytaradi. forma.elements.id
esa har doim maydonni beradi.
Xavfli nomlar: id, action, method, submit, length.
Ayniqsa name="submit" - u forma.submit() metodini
bosib o'tadi va formani dastur orqali yuborib bo'lmay
qoladi.
FormData - hamma maydonni birdan #
const forma = document.getElementById("ariza");
forma.ism.value = "Nodira";
forma.email.value = "[email protected]";
forma.yosh.value = "23";
forma.izoh.value = "Izoh matni";
document.getElementById("shartlar").checked = true;
document.getElementById("shahar").value = "tosh";
const malumot = new FormData(forma);
console.log("ism :", malumot.get("ism"));
console.log("email :", malumot.get("email"));
console.log("shahar :", malumot.get("shahar"));
console.log("shartlar:", malumot.get("shartlar"));
// Oddiy obyektga aylantirish
const obyekt = Object.fromEntries(malumot);
console.log("Kalitlar:", Object.keys(obyekt).join(", "));
console.log("Obyekt yosh:", obyekt.yosh);
ism : Nodira
email : [email protected]
shahar : tosh
shartlar: on
Kalitlar: ism, email, yosh, shartlar, shahar, izoh
Obyekt yosh: 23
FormData da belgilanmagan katakcha yo'qYuqoridagi natijaga e'tibor bering: shartlar qiymati
"on" - bu HTML ning odatiy qiymati.
Lekin katakcha belgilanmagan bo'lsa, u FormData da
umuman bo'lmaydi:
document.getElementById("shartlar").checked = false;
new FormData(forma).get("shartlar"); // null
Xuddi shunday jins radio guruhi ham - hech biri
tanlanmagan bo'lsa, kalit yo'q. Yuqoridagi kalitlar ro'yxatida
jins yo'qligining sababi shu.
Shuning uchun serverda kalit borligini tekshiring:
const roziligi = malumot.has("shartlar"); // true/false
Aniq qiymat kerak bo'lsa, katakchaga value bering:
<input type="checkbox" name="shartlar" value="ha">
Brauzer validatsiyasi #
const ism = document.getElementById("ism");
const email = document.getElementById("email");
// Bo'sh - required buziladi
ism.value = "";
console.log("Bo'sh ism to'g'rimi?:", ism.checkValidity());
console.log("valueMissing :", ism.validity.valueMissing);
// Juda qisqa - minlength buziladi
ism.value = "ab";
console.log("Qisqa ism to'g'rimi?:", ism.checkValidity());
console.log("tooShort :", ism.validity.tooShort);
// To'g'ri
ism.value = "Husanboy";
console.log("To'g'ri ism :", ism.checkValidity());
// Email formati
email.value = "notogri";
console.log("Noto'g'ri email :", email.checkValidity());
console.log("typeMismatch :", email.validity.typeMismatch);
email.value = "[email protected]";
console.log("To'g'ri email :", email.checkValidity());
Bo'sh ism to'g'rimi?: false
valueMissing : true
Qisqa ism to'g'rimi?: true
tooShort : false
To'g'ri ism : true
Noto'g'ri email : false
typeMismatch : true
To'g'ri email : true
Foydalanuvchi quyidagilarni bemalol qila oladi:
F12bilanrequiredatributini o'chirish;novalidateatributini qo'shish;curlyoki Postman bilan to'g'ridan-to'g'ri so'rov yuborish;- JavaScript ni butunlay o'chirish.
Shuning uchun server tomonida yana tekshiring - istisnosiz.
Brauzer validatsiyasi nima uchun kerak:
- Foydalanuvchi xatoni darhol ko'radi;
- Server yuki kamayadi;
- Tajriba yaxshilanadi.
Lekin u himoya emas, faqat qulaylik.
minlength faqat foydalanuvchi yozganda tekshiriladiYuqoridagi natijaga e'tibor bering: ism.value = "ab" qo'yilgan
bo'lsa ham tooShort false qaytardi.
Bu xato emas - standart shunday talab qiladi. minlength va
maxlength faqat qiymatning "iflos" (dirty) bayrog'i
o'rnatilganda, ya'ni uni foydalanuvchi tahrirlagan bo'lsa
qo'llanadi. Dastur orqali .value berish bu bayroqni
o'rnatmaydi.
required esa har doim ishlaydi - shuning uchun valueMissing
to'g'ri chiqdi.
Amaliy xulosa: uzunlikni o'zingiz tekshiring, minlength
ga tayanmang:
if (maydon.value.length < 3) {
maydon.setCustomValidity("Kamida 3 belgi");
}
Bu ayniqsa formani dastur orqali to'ldirganda muhim - masalan qoralamani tiklaganda yoki avtomatik to'ldirishda.
validity obyekti #
const yosh = document.getElementById("yosh");
const holatlar = [
["", "bo'sh"],
["15", "juda kichik"],
["150", "juda katta"],
["25", "to'g'ri"]
];
for (const [qiymat, izoh] of holatlar) {
yosh.value = qiymat;
const v = yosh.validity;
const muammolar = [];
if (v.valueMissing) { muammolar.push("valueMissing"); }
if (v.rangeUnderflow) { muammolar.push("rangeUnderflow"); }
if (v.rangeOverflow) { muammolar.push("rangeOverflow"); }
const holat = v.valid ? "OK" : muammolar.join(", ");
console.log(`${izoh.padEnd(12)} -> ${holat}`);
}
bo'sh -> OK
juda kichik -> rangeUnderflow
juda katta -> rangeOverflow
to'g'ri -> OK
yosh maydonida required yo'q - shuning uchun bo'sh
qoldirish mumkin. min va max esa faqat qiymat bo'lganda
tekshiriladi.
Bu mantiqiy: "ixtiyoriy maydon, lekin to'ldirilsa 18-100 oralig'ida bo'lsin".
required qo'shsangiz, bo'sh qiymat valueMissing beradi.
validity ning to'liq ro'yxati:
| Xossa | Qachon true |
|---|---|
valueMissing | required, lekin bo'sh |
typeMismatch | type="email" formatiga mos emas |
patternMismatch | pattern regex ga mos emas |
tooShort / tooLong | minlength / maxlength |
rangeUnderflow / rangeOverflow | min / max |
stepMismatch | step ga mos emas |
badInput | Brauzer qiymatni o'qiy olmadi |
customError | setCustomValidity chaqirilgan |
valid | Hammasi joyida |
O'z xato xabarlaringiz #
const parol = document.createElement("input");
parol.type = "password";
parol.required = true;
document.getElementById("ariza").appendChild(parol);
function parolniTekshirish(qiymat) {
if (qiymat.length < 8) {
return "Parol kamida 8 belgi bo'lishi kerak";
}
if (!/[A-Z]/.test(qiymat)) {
return "Kamida bitta katta harf kerak";
}
if (!/\d/.test(qiymat)) {
return "Kamida bitta raqam kerak";
}
return "";
}
const sinovlar = ["qisqa", "uzunlekin", "Uzunlekin", "Uzunlekin1"];
for (const sinov of sinovlar) {
parol.value = sinov;
const xato = parolniTekshirish(sinov);
parol.setCustomValidity(xato);
console.log(`${sinov.padEnd(12)} -> ${parol.checkValidity() ? "OK" : parol.validationMessage}`);
}
qisqa -> Parol kamida 8 belgi bo'lishi kerak
uzunlekin -> Kamida bitta katta harf kerak
Uzunlekin -> Kamida bitta raqam kerak
Uzunlekin1 -> OK
setCustomValidity("") ni chaqirishni unutmangmaydon.setCustomValidity("Xato!");
// keyin foydalanuvchi tuzatdi...
maydon.checkValidity(); // HALI HAM false!
Maxsus xato avtomatik tozalanmaydi. Har tekshiruvda uni qayta o'rnatishingiz kerak:
maydon.setCustomValidity(xatoBormi ? "Xabar" : "");
Bo'sh satr - "xato yo'q" degani.
Yuqoridagi misolda aynan shunday qilingan: parolniTekshirish
to'g'ri qiymatda bo'sh satr qaytaradi.
To'liq validatsiya naqshi #
const forma = document.getElementById("ariza");
function xatoKorsatish(maydon, xabar) {
maydon.classList.toggle("xato", Boolean(xabar));
let element = maydon.nextElementSibling;
if (!element || !element.classList.contains("xato-xabar")) {
element = document.createElement("small");
element.className = "xato-xabar";
maydon.after(element);
}
element.textContent = xabar;
}
function formaniTekshirish() {
const xatolar = [];
for (const maydon of forma.elements) {
if (!maydon.name) {
continue;
}
if (!maydon.checkValidity()) {
xatoKorsatish(maydon, maydon.validationMessage);
xatolar.push(maydon.name);
} else {
xatoKorsatish(maydon, "");
}
}
return xatolar;
}
// Bo'sh forma
forma.ism.value = "";
forma.email.value = "";
console.log("Bo'sh formada xatolar:", formaniTekshirish().join(", "));
// To'ldirilgan forma
forma.ism.value = "Aziza";
forma.email.value = "[email protected]";
console.log("To'ldirilgandan keyin:", formaniTekshirish().length, "ta xato");
console.log("Xato klassi qoldimi? :", forma.ism.classList.contains("xato"));
Bo'sh formada xatolar: ism, email
To'ldirilgandan keyin: 0 ta xato
Xato klassi qoldimi? : false
input va change farqi #
const maydon = document.getElementById("ism");
const hodisalar = [];
maydon.addEventListener("input", () => hodisalar.push("input"));
maydon.addEventListener("change", () => hodisalar.push("change"));
// input - har o'zgarishda
maydon.value = "H";
maydon.dispatchEvent(new Event("input"));
maydon.value = "Hu";
maydon.dispatchEvent(new Event("input"));
// change - fokus yo'qolganda
maydon.dispatchEvent(new Event("change"));
console.log("Hodisalar:", hodisalar.join(" -> "));
Hodisalar: input -> input -> change
| Hodisa | Qachon | Nima uchun |
|---|---|---|
input | Har belgi kiritilganda | Jonli qidiruv, belgi sanash |
change | Fokus yo'qolganda | Yakuniy tekshiruv |
input ni sekinlashtiringmaydon.addEventListener("input", () => {
qidirish(maydon.value); // har belgida server so'rovi!
});
"salom" yozgan foydalanuvchi 5 ta so'rov yuboradi.
Debounce naqshi bu muammoni hal qiladi:
let taymer;
maydon.addEventListener("input", () => {
clearTimeout(taymer);
taymer = setTimeout(() => qidirish(maydon.value), 300);
});
Endi foydalanuvchi 300 ms to'xtaganda bitta so'rov ketadi.
Har harfda javob kerak bo'lsa (masalan belgi sanash) -
debounce shart emas, input to'g'ridan-to'g'ri ishlatiladi.
- Matn, katakcha va tanlov maydonlaridan qiymat o'qing.
- Radio guruhidan tanlanganini
:checkedbilan toping. valuesatr ekanini isbotlab,valueAsNumberbilan tuzating.submitdapreventDefaultchaqirib, ma'lumotni yig'ing.FormDatavaObject.fromEntriesbilan obyekt yasang.- Belgilanmagan katakcha
FormDatada yo'qligini ko'rsating. checkValidityvavalidityxossalarini sinang.setCustomValiditybilan parol qoidalarini yozing.- Xatoni tozalash uchun bo'sh satr berish kerakligini ayting.
inputvachangehodisalarini taqqoslang.
Xulosa #
input.valuehar doim satr -valueAsNumberishlating.Number("")0beradi,valueAsNumberesaNaN.submitdapreventDefaultchaqiring.- Maydonlarga
forma.elements.nomorqali murojaat qiling. FormDatabarcha maydonni bir yo'la yig'adi.- Belgilanmagan katakcha
FormDatada umuman bo'lmaydi. checkValidityvavaliditybrauzer tekshiruvini beradi.- Brauzer validatsiyasi - qulaylik, xavfsizlik emas.
- Serverda albatta qayta tekshiring.
setCustomValidity("")bilan xatoni tozalashni unutmang.inputhar belgida,changefokus yo'qolganda ishlaydi.- Jonli qidiruvda debounce qo'llang.
Keyingi bo'limda asinxron JavaScript va hodisalar siklini o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.