IlmHamroh
JavaScript Full-stack/9-qism. JavaScript brauzerda va debugging22/29-dars20 daqiqa
Mundarija (36)

JavaScript'da forma: qiymatlarni o'qish va submit hodisasi

Qisqacha: Forma yuborilishini ushlash uchun formaning o'ziga submit hodisasini tinglang va event.preventDefault() bilan sahifa almashishini to'xtating. Maydonlarni forma.elements.ism kabi name bo'yicha oling: matn uchun value (har doim satr), checkbox uchun checked, radio guruhi uchun forma.elements.joy.value, select uchun value yoki selectedOptions.

Bu darsda

  • submit hodisasini tinglab, forma yuborilishini preventDefault bilan to'xtata olasiz.
  • Nega tugmaning click i emas, formaning submit i tinglanishini tushuntira olasiz.
  • form.elements va name bo'yicha istalgan maydonni topasiz.
  • Matn, son, checkbox, radio, select va textarea qiymatini to'g'ri o'qiysiz.
  • Portfolio'ngizdagi aloqa formasini JavaScript bilan ushlab, rahmat xabarini chiqarasiz.

Oldin bilishingiz kerak: Event obyekti va standart harakatlar, Forma qanday ishlaydi, Tanlash maydonlari, Turlarni aniq o'zgartirish.

1. Nega bu kerak?

«Bahor» choyxonasining bron formasini eslang. Ali ismini, telefonini va necha kishi kelishini yozib, «Bron qilish» ni bosadi. Brauzer ma'lumotni https://example.com/bron ga jo'natadi va butun sahifani almashtiradi. Forma qanday ishlaydi darsida aynan shunday bo'lgan.

Bu ishlaydi, lekin ko'p narsani xohlaymiz:

  • Ali tugmani bosganda sahifa o'chib ketmasin, shu yerning o'zida "Rahmat, Ali!" chiqsin.
  • Yuborishdan oldin ma'lumotni JavaScript tekshirsin: kishi soni son bo'lsinmi, ism probellardan iborat emasmi.
  • Ma'lumot orqa fonda serverga ketsin, sahifa esa joyida tursin.

Uchalasi ham bitta qadamdan boshlanadi: forma yuborilayotgan lahzani ushlash va maydonlardagi qiymatni o'qish. Bugun shu ikkalasini o'rganamiz. Orqa fonda jo'natish — fetch darsida.

Hayotdan o'xshatish: pochta bo'limi. Ali xatni qutiga tashlamoqchi. Siz qutining oldida turibsiz: xatni ushlab, ichini o'qiysiz va o'zingiz qaror qilasiz — qutiga tashlaysizmi, egasiga qaytarasizmi yoki boshqa yo'l bilan yuborasizmi.

2. submit hodisasi

2.1 Birinchi ushlash

Event obyekti va standart harakatlar darsida havolaning standart harakatini preventDefault() bilan to'xtatgan edingiz. Forma ham xuddi shunday: uning standart harakati — ma'lumotni action manziliga jo'natib, sahifani almashtirish. Bu harakat submit (yuborish) hodisasidan keyin bajariladi.

html
<form action="https://example.com/bron" method="post">
  <label for="ism">Ismingiz</label>
  <input id="ism" name="ism" required>
  <button type="submit">Bron qilish</button>
</form>
<p id="javob"></p>
<script>
  const forma = document.querySelector("form");
  const javob = document.querySelector("#javob");

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const ism = forma.elements.ism.value;
    javob.textContent = `Rahmat, ${ism}! So'rovingiz qabul qilindi.`;
    console.log("submit:", ism);
  });
</script>

Maydonga "Ali" deb yozing va «Bron qilish» ni bosing. Forma ostida "Rahmat, Ali! So'rovingiz qabul qilindi." chiqadi, konsol panelida esa submit: Ali qatori paydo bo'ladi. Sahifa joyida qoldi.

Kodni qatorma-qator o'qiymiz:

  • forma.addEventListener("submit", ...) — tinglovchi formaga qo'yilgan, tugmaga emas. Nega — keyingi bo'limda.
  • event.preventDefault() — "standart harakatni qilma": brauzer example.com ga ketmaydi.
  • forma.elements.ism.value — formaning name="ism" li maydoni va uning ichidagi matn. Bu ikki narsani shu darsda batafsil ko'ramiz.
  • textContent — natijani sahifaga xavfsiz yozish (Kontentni o'zgartirish va XSS xavfi).

2.2 Natija oynasidagi yashil yozuv

Natija oynasining o'z yordamchisi bor — uni siz yozmaysiz. Forma yuborilsa-yu, sizning kodingiz uni to'xtatmasa, haqiqiy saytda brauzer action manziliga o'tib ketardi. Oyna esa begona saytga ketmaydi. U bunday yuborishni eng oxirgi lahzada o'zi to'xtatadi va pastda bir lahzaga yashil yozuv ko'rsatadi: " Forma tekshiruvdan o'tdi (namuna — hech qayerga yuborilmadi)".

Yuqoridagi misolda siz preventDefault() chaqirdingiz — shuning uchun yashil yozuv chiqmadi. Yordamchi tinglovchingizga xalaqit bermaydi: event.defaultPrevented haqiqiy brauzerdagidek false turadi, o'zingiz preventDefault() chaqirmaguncha.

Sinab ko'ring: «Tahrirlab ko'rish» bilan event.preventDefault(); qatorini o'chiring va yana "Ali" bilan bosing. "Rahmat" va submit: Ali baribir chiqadi, endi pastda yashil yozuv ham paydo bo'ladi (tekshirdik).

Sizning kodingiz Natija oynasida Haqiqiy saytda
preventDefault() bor Yashil yozuv yo'q Sahifa joyida qoladi
preventDefault() yo'q Yashil yozuv chiqadi Sahifa action ga o'tib ketadi

Demak yashil yozuv — "haqiqiy saytda sahifa almashib ketardi" degan ishora. Haqiqiy saytda preventDefault() majburiy — uni unutsangiz nima bo'lishini «Ko'p uchraydigan xatolar» bo'limida ko'ramiz.

Maydonni bo'sh qoldirib bosing-chi. Konsol jim. Brauzer required ni tekshirdi va formani umuman yubormadi — submit hodisasi bo'lmadi.

2.3 Hodisa qachon keladi

Forma yuborilguncha bo'ladigan butun yo'l:

flowchart TD
  A["Tugma bosildi yoki maydonda Enter"] --> B{"Brauzer tekshiruvi o'tdimi?"}
  B -->|"Yo'q"| C["Xato pufagi. submit yo'q"]
  B -->|"Ha"| D["submit hodisasi: tinglovchingiz ishlaydi"]
  D --> E{"preventDefault chaqirildimi?"}
  E -->|"Ha"| F["Sahifa joyida. Ishni JS davom ettiradi"]
  E -->|"Yo'q"| G["Brauzer action manziliga jo'natadi"]

Nimaga qarang: tinglovchingiz brauzer tekshiruvidan keyin ishlaydi. required, pattern, min/max qoidalari (Brauzer validatsiyasi) bajarilmasa, kodingiz chaqirilmaydi ham. Bu qulay: oddiy tekshiruvni HTML qiladi, JavaScript esa tayyor, to'g'ri ma'lumot bilan ishlaydi.

Tekshirib ko'ring: Yuqoridagi misolda maydonga faqat uchta probel yozib bosilsa, sahifada nima chiqadi?

Javob

"Rahmat, ! So'rovingiz qabul qilindi." — ism o'rnida probellar. Brauzer validatsiyasi darsidan eslang: faqat probellardan iborat matn required dan o'tadi. Shuning uchun JavaScript'da qiymat trim() bilan tozalanadi va keyin tekshiriladi — buni pastdagi to'liq misolda qilamiz.

3. Nega click emas, submit?

Ko'p boshlovchi birinchi bo'lib tugmaning click ini tinglaydi. Ikkalasini yonma-yon qo'yib solishtiramiz:

html
<form action="https://example.com/bron" method="post">
  <label for="ism">Ismingiz</label>
  <input id="ism" name="ism" required>
  <button type="submit">Bron qilish</button>
</form>
<script>
  const forma = document.querySelector("form");
  const tugma = document.querySelector("button");

  tugma.addEventListener("click", () => {
    console.log("click");
  });
  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    console.log("submit");
  });
</script>

Ikki tajriba qiling:

  1. Maydonni bo'sh qoldirib, tugmani bosing. Konsolda faqat click chiqadi — forma tekshiruvdan o'tmadi, lekin click baribir ishladi.
  2. Ism yozib, tugmani bosmasdan maydonning ichida Enter ni bosing. Konsolda click va submit chiqadi.

Birinchi tajriba eng muhimi. click tinglovchisi bo'sh, noto'g'ri formada ham ishlaydi — brauzer tekshiruvini chetlab o'tadi. Ikkinchi tajribada Enter "yashirin yuborish" qildi (Forma qanday ishlaydi): brauzer formaning birinchi yuborish tugmasini o'zi "bosdi".

Xulosa uch bandda:

  • submit — "forma yuborilmoqda" degan ma'no. U tugma, Enter yoki boshqa yo'l bilan kelganidan qat'i nazar, bitta joyda ushlanadi.
  • submit faqat tekshiruvdan o'tgan formada keladi.
  • Formada ikkita yuborish tugmasi bo'lsa ham, tinglovchi bitta. Qaysi tugma bosilganini FormData darsida aniqlaymiz.

Maslahat: Tugmaning type ini doim yozing. Formadagi type siz button — yuborish tugmasi. Faqat JavaScript ishini qiladigan tugma (masalan, "Tozalash" yoki "Parolni ko'rsatish") type="button" bo'lsin, aks holda u formani yuborib yuboradi.

4. value — maydon ichidagi qiymat

4.1 Har doim satr

input ning value xususiyati — maydonda hozir turgan matn. Bitta muhim qoida bor, uni Turlarni aniq o'zgartirish darsida oldindan aytgan edik: value har doim satr, hatto type="number" maydonda ham.

html
<label for="odam">Necha kishi</label>
<input id="odam" name="odam" type="number" value="4">
<script>
  const odam = document.querySelector("#odam");
  console.log(odam.value, typeof odam.value);
  console.log(odam.value + 1);
  console.log(Number(odam.value) + 1);
  console.log(odam.valueAsNumber + 1);
</script>

Konsolda:

text
4 string
41
5
5

"4" + 1 — satrga son qo'shildi, natija "41". Bron tizimi 41 kishilik stol qidirib qoladi! Hisob-kitobdan oldin qiymat songa aylantiriladi. Ikki yo'l bor:

  • Number(odam.value) — 08-qismdan tanish usul.
  • odam.valueAsNumber — faqat number, range va sana-vaqt maydonlarida bor xususiyat. U tayyor son beradi.

4.2 Bo'sh maydon tuzog'i

Ikki usul bo'sh maydonda turlicha ishlaydi:

html
<label for="odam">Necha kishi</label>
<input id="odam" name="odam" type="number">
<script>
  const odam = document.querySelector("#odam");
  console.log(JSON.stringify(odam.value));
  console.log(Number(odam.value));
  console.log(odam.valueAsNumber);
</script>

Konsolda:

text
""
0
NaN

Number("") — 0. Mehmon kishi sonini yozmagan, lekin kod "0 kishi" deb o'ylaydi. valueAsNumber esa halol NaN beradi — "son yo'q". Shuning uchun bo'sh qiymatni avval alohida tekshiring yoki Number.isNaN(odam.valueAsNumber) dan foydalaning (Matn, son va sonni tekshirish).

4.3 Atribut va xususiyat

HTML'dagi value="4" atributi — faqat boshlang'ich qiymat. Mehmon yozgan sari value xususiyati o'zgaradi, atribut esa o'zgarmaydi. Boshlang'ich qiymat defaultValue da saqlanadi. Bu Atributlar va xususiyatlar darsidagi qoidaning eng yorqin misoli.

forma.reset() metodi barcha maydonlarni boshlang'ich holatiga qaytaradi — type="reset" tugmasi bosilgandek. Muvaffaqiyatli yuborishdan keyin formani tozalash uchun qulay.

Tekshirib ko'ring: <input type="number" id="narx" value="35000"> maydoniga mehmon 28000 yozdi. narx.value, narx.defaultValue va narx.getAttribute("value") nima qaytaradi?

Javob

"28000", "35000" va "35000". value — hozirgi holat, qolgan ikkitasi — HTML'da yozilgan boshlang'ich qiymat. Uchalasi ham satr.

5. form.elements: maydonlarni nomi bilan olish

5.1 Har maydonga querySelector shart emas

Formada o'nta maydon bo'lsa, o'nta querySelector yozish noqulay. Formaning o'zida tayyor ro'yxat bor — elements:

html
<form id="bron">
  <label>Ism <input name="ism" value="Ali"></label>
  <label>Telefon
    <input name="telefon" value="+998 90 000 00 00"></label>
  <label>Kishi <input name="odam" type="number" value="4"></label>
  <button type="submit">Bron qilish</button>
</form>
<script>
  const forma = document.querySelector("#bron");
  console.log(forma.elements);
  console.log(forma.elements.length);
  console.log(forma.elements.ism.value);
  console.log(forma.elements["telefon"].value);
  console.log(forma.elements[2].value);
</script>

Konsolda:

text
HTMLFormControlsCollection(4) [input, input, input, button]
4
Ali
+998 90 000 00 00
4

forma.elements — forma boshqaruv elementlari to'plami (HTMLFormControlsCollection): formadagi barcha maydon va tugmalar, HTML'dagi tartibda. label, p, div kabi oddiy elementlar unga kirmaydi. Undan maydonni uch xil olish mumkin:

Yozuv Qachon qulay
forma.elements.ism Nom oddiy so'z bo'lsa — eng ko'p ishlatiladi
forma.elements["telefon"] Nom o'zgaruvchida yoki ichida - bor bo'lsa
forma.elements[2] Tartib raqami bilan; kamdan-kam kerak

Kalit — maydonning name atributi (id bilan ham ishlaydi, lekin name asosiy). Bu ajablanarli emas: Forma qanday ishlaydi darsidan eslang, serverga ham aynan name=qiymat juftlari ketadi. JavaScript ham formani server ko'rgan nomlar bilan o'qiydi.

5.2 Qisqa yo'l va uning xavfi

forma.ism deb ham yozsa bo'ladi — brauzer formaning o'ziga ham maydon nomlarini "osib qo'yadi". Lekin bu yo'l xavfli. Formaning o'z xususiyatlari bor: action, method, submit, reset. Maydon nomi ular bilan to'qnashsa, maydon ularni yashiradi:

html
<form id="bron" action="https://example.com/bron">
  <label>Amal <input name="action" value="bron"></label>
</form>
<script>
  const forma = document.querySelector("#bron");
  console.log(forma.action);
  console.log(forma.getAttribute("action"));
</script>

Konsolda:

text
<input name="action" value="bron">
https://example.com/bron

forma.action endi manzil emas, maydonning o'zi! name="submit" li maydon esa forma.submit() metodini yo'q qiladi. Shuning uchun kursdagi qoida: maydonlarni doim forma.elements orqali oling va maydonga formaning xususiyati nomini bermang.

5.3 Teskari yo'l: maydondan formaga

Ba'zan qo'lingizda maydon bor, formasi esa kerak. Har bir maydonning form xususiyati bor — u maydon tegishli formani qaytaradi. Maydon formadan tashqarida tursa ham, unga tegishli bo'lishi mumkin: Maydon holatlari va yashirin maydonlar darsidagi form="..." atributini eslang. Formaning elements ro'yxati buni ham hisobga oladi:

html
<form id="bron">
  <label>Ism <input name="ism" value="Ali"></label>
</form>
<label>Izoh (formadan tashqarida)
  <input name="izoh" form="bron" value="Deraza yonida">
</label>
<button type="submit" form="bron">Bron qilish</button>
<script>
  const ism = document.querySelector('[name="ism"]');
  const izoh = document.querySelector('[name="izoh"]');
  console.log(ism.form.id);
  console.log(izoh.form.id);
  console.log(izoh.form.elements.length);
</script>

Konsolda:

text
bron
bron
3

Izoh maydoni va tugma HTML'da formadan tashqarida, lekin ikkalasi ham elements ichida — jami uchta. Formaga tegishli bo'lmagan maydonning form i esa null.

Yana bir yo'l: submit tinglovchisida event.target — formaning o'zi. Sahifada bir nechta forma bo'lsa, ularni bitta tinglovchi bilan (Event delegation) ushlash mumkin: document dagi submit qaysi formadan kelganini event.target aytadi.

6. Har xil maydonning qiymati

Matn maydoni bilan hammasi oddiy edi. Tanlash maydonlarida (Tanlash maydonlari) qiymat boshqacha o'qiladi.

6.1 Checkbox, radio va select

html
<form id="bron">
  <fieldset>
    <legend>Joy</legend>
    <label><input type="radio" name="joy" value="zal"> Zal</label>
    <label>
      <input type="radio" name="joy" value="ayvon" checked> Ayvon
    </label>
  </fieldset>
  <label>
    <input type="checkbox" name="rozi"> Shartlarga roziman
  </label>
  <label>Taom
    <select name="taom">
      <option value="osh">Osh</option>
      <option value="manti" selected>Manti</option>
    </select>
  </label>
</form>
<script>
  const el = document.querySelector("#bron").elements;
  console.log(el.joy.value);
  console.log(el.rozi.value, el.rozi.checked);
  console.log(el.taom.value);
  console.log(el.taom.selectedOptions[0].text);
</script>

Konsolda:

text
ayvon
on false
manti
Manti

Har biri haqida:

  • Radio guruhi. el.joy bitta element emas: bir xil name li ikkita radio bor. Brauzer ularni RadioNodeList (radio tugunlari ro'yxati) qilib beradi. Uning value si — tanlangan radio qiymati. Hech biri tanlanmagan bo'lsa — bo'sh satr "".
  • Checkbox. value belgilangan-belgilanmaganidan qat'i nazar bir xil: value atributi yozilmagan bo'lsa, "on". Belgini checked aytadi: true yoki false.
  • select. value — tanlangan option ning value si. Ekrandagi yozuvi kerak bo'lsa — selectedOptions[0].text.

selectedOptions — tanlangan variantlar ro'yxati. Oddiy select da u doim bitta elementli. U multiple li ro'yxatda haqiqiy kuchini ko'rsatadi.

6.2 Bir nechta tanlov: multiple

html
<label for="taomlar">Taomlar (Ctrl bilan bir nechtasi)</label>
<select id="taomlar" name="taomlar" multiple>
  <option value="osh" selected>Osh — 35 000</option>
  <option value="lagmon">Lag'mon — 28 000</option>
  <option value="manti" selected>Manti — 30 000</option>
</select>
<script>
  const taomlar = document.querySelector("#taomlar");
  console.log(taomlar.value);
  console.log(taomlar.selectedOptions);

  const tanlangan = [];
  for (const variant of taomlar.selectedOptions) {
    tanlangan.push(variant.value);
  }
  console.log(tanlangan);
</script>

Konsolda:

text
osh
HTMLCollection(2) [option, option]
(2) ['osh', 'manti']

value faqat birinchi tanlangan variantni berdi — manti yo'qoldi. Bir nechta tanlovda selectedOptions ni for...of bilan aylanib chiqing. HTMLCollection — Elementlarni tanlash darsidagi "jonli" to'plam: mehmon tanlovni o'zgartirsa, u ham o'zgaradi.

"Tahrirlab ko'rish" bilan uchala variantni ham selected qiling va natijani kuzating.

6.3 textarea

textarea ning qiymati ham value da. Uning HTML'dagi ichki matni (textContent) — boshlang'ich qiymat, xuddi input dagi value atributi kabi. Mehmon nima yozsa ham, textContent o'zgarmaydi. Shuning uchun textarea dan doim value o'qiladi.

Barcha qoidalar bitta jadvalda:

Maydon O'qish Natija turi
Matn, email, tel, textarea .value satr
number, range .valueAsNumber (yoki Number(.value)) son yoki NaN
Checkbox .checked true / false
Radio guruhi forma.elements.nom.value satr, tanlanmasa ""
select .value, ko'p tanlovda .selectedOptions satr / to'plam

Tekshirib ko'ring: Radio guruhidan qiymatni document.querySelector('input[name="joy"]').value bilan o'qisa nima bo'ladi?

Javob

Har doim birinchi radioning qiymati chiqadi ("zal"), qaysi biri tanlanganidan qat'i nazar. querySelector birinchi mos elementni beradi, value esa tanlanganini emas, o'sha radioning atributini qaytaradi. To'g'ri yo'l — forma.elements.joy.value yoki querySelector('input[name="joy"]:checked') (Holat pseudo-klasslari dagi :checked). Ikkinchisida hech narsa tanlanmagan bo'lsa null keladi — buni tekshiring.

7. To'liq misol: «Bahor» bron formasi

Endi hammasini bitta formada birlashtiramiz. Maydonlar va qoidalar — Brauzer validatsiyasi darsidagi kanonik bron formasi. Qulaylik uchun ular oldindan to'ldirilgan: darhol bosib ko'ring, keyin o'zgartiring.

html
<style>
  form { display: grid; gap: 6px; max-width: 320px; }
  fieldset { display: flex; gap: 12px; }
  #javob { font-weight: bold; color: #2f6b3a; }
</style>
<form action="https://example.com/bron" method="post">
  <label for="ism">Ismingiz (2–50 belgi)</label>
  <input id="ism" name="ism" value="Ali"
         required minlength="2" maxlength="50">
  <label for="telefon">Telefon (+998 90 000 00 00)</label>
  <input id="telefon" name="telefon" type="tel"
         value="+998 90 000 00 00" required
         pattern="\+998 ?\d{2} ?\d{3} ?\d{2} ?\d{2}">
  <label for="odam">Necha kishi (1–20)</label>
  <input id="odam" name="odam" type="number" value="4"
         required min="1" max="20">
  <label for="vaqt">Soat nechada (10:00–22:00)</label>
  <input id="vaqt" name="vaqt" type="time" value="19:00"
         required min="10:00" max="22:00">
  <fieldset>
    <legend>Joy</legend>
    <label><input type="radio" name="joy" value="zal"> Zal</label>
    <label>
      <input type="radio" name="joy" value="ayvon" checked> Ayvon
    </label>
  </fieldset>
  <label>
    <input type="checkbox" name="rozi" checked required>
    Bron shartlariga roziman
  </label>
  <button type="submit">Bron qilish</button>
</form>
<p id="javob"></p>
<script>
  const forma = document.querySelector("form");
  const javob = document.querySelector("#javob");

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const el = forma.elements;

    const bron = {
      ism: el.ism.value.trim(),
      telefon: el.telefon.value,
      odam: el.odam.valueAsNumber,
      vaqt: el.vaqt.value,
      joy: el.joy.value,
    };
    console.log(bron);

    javob.textContent =
      `${bron.ism}, ${bron.odam} kishilik stol ` +
      `soat ${bron.vaqt} ga band qilindi (${bron.joy}).`;
  });
</script>

«Bron qilish» ni bosing. Sahifada "Ali, 4 kishilik stol soat 19:00 ga band qilindi (ayvon)." chiqadi, konsolda esa butun obyekt:

text
{ism: 'Ali', telefon: '+998 90 000 00 00', odam: 4, vaqt: '19:00', joy: 'ayvon'}

Nimaga qarang:

  • odam: 4 — qo'shtirnoqsiz, ya'ni son. valueAsNumber ishladi. Qolgan qiymatlar — satr.
  • vaqt: '19:00' — time maydonining value si doim "SS:DD" ko'rinishida, mehmonning ekranida "7:00 PM" yozilgan bo'lsa ham.
  • rozi obyektga qo'shilmadi: required uni brauzerning o'zi tekshirdi, belgilanmagan bo'lsa submit kelmasdi.
  • Natija textContent bilan yozildi. Ism o'rniga HTML kod yozilsa ham, u shunchaki matn bo'lib chiqadi.

Endi kishi soniga 25 yozib bosing — submit kelmaydi, brauzer max="20" xabarini chiqaradi. Kod bitta qatorini ham o'zgartirmadi: HTML qoidalari va JavaScript bir-birini to'ldiradi.

Obyekt yig'ish qismi takrorlanuvchi: har maydon uchun bitta qator. O'nta maydonda o'nta qator bo'ladi. FormData darsida butun formani bitta qatorda yig'amiz.

8. Hujumchi nigohi

Forma JavaScript'da o'qildi va tekshirildi — endi xavfsizmi? Yo'q. Hujumchi uchun bu kod hech qanday to'siq emas:

  • Brauzer — mehmonning qo'lida. DevTools'da required, max="20" ni o'chirish yoki submit tinglovchisining o'zini olib tashlash — bir necha soniyalik ish. Elements panelida tinglovchilar ro'yxati bor (Event obyekti darsidagi Event Listeners).
  • Brauzer umuman shart emas. Hujumchi curl bilan https://example.com/bron ga istalgan ma'lumotni to'g'ridan-to'g'ri yuboradi. JavaScript kodingiz umuman ishga tushmaydi.
  • Maydon qiymati — begona matn. Ism o'rniga <img src=x onerror=...> yozilishi mumkin. Uni innerHTML bilan sahifaga qo'ysangiz, hujumchi kodi ishlaydi (Kontentni o'zgartirish va XSS xavfi). Biz textContent ishlatdik — bu kod bu hujumga qarshi turadi.

Qoida Brauzer validatsiyasi darsidagidek: mijozdagi tekshiruv — mehmonning qulayligi uchun, server tekshiruvi — xavfsizlik uchun. JavaScript tekshiruvi ham "mijozdagi tekshiruv" ga kiradi. Serverda hammasi qayta tekshiriladi (Validatsiya: nima uchun, qayerda va qanday).

9. Ko'p uchraydigan xatolar

9.1 preventDefault unutildi

Haqiqiy saytda submit tinglovchisi ishlaydi, textContent yoziladi va... bir zumda sahifa almashadi. Brauzer formani action manziliga jo'natdi. Konsoldagi qatorlar ham yo'qoladi — yangi sahifada konsol tozalanadi.

js
forma.addEventListener("submit", (event) => {
  // event.preventDefault(); ← unutildi
  javob.textContent = "Rahmat!"; // ko'rinmay qoladi
});

Tuzatish: event.preventDefault() ni tinglovchining eng boshiga yozing. Jonli oyna formani o'zi to'xtatgani uchun bu yerda sahifa almashmaydi — xatoning yagona belgisi pastdagi yashil yozuv («Natija oynasidagi yashil yozuv» bo'limi). Haqiqiy xulqni o'z saytingizda Live Server bilan sinab ko'ring. Sahifa almashsa ham konsol tozalanmasligi uchun DevTools'da Console sozlamalaridagi Preserve log belgisini yoqing.

9.2 Tugmaning click ini tinglash

Natija: bo'sh forma ham "yuboriladi", Enter bosilganda esa kod ikki marta ishlashi mumkin (bitta click da, bitta submit da). Tuzatish: formaning submit ini tinglang.

9.3 Satrni son deb hisoblash

el.odam.value + 1 → "41". Bo'sh maydonda esa Number(el.odam.value) → 0. Tuzatish: valueAsNumber va Number.isNaN tekshiruvi.

9.4 Checkbox'dan value o'qish

el.rozi.value belgilanmagan checkbox'da ham "on". Kod "mehmon rozi" deb o'ylaydi. Tuzatish: el.rozi.checked.

9.5 Formadan value so'rash

html
<form id="bron"><input name="ism" value="Ali"></form>
<script>
  const forma = document.querySelector("#bron");
  console.log(forma.value);
  console.log(forma.elements.ism.value);
</script>

Konsolda:

text
undefined
Ali

Formaning o'zida value yo'q — qiymat har maydonda alohida. undefined xato bermaydi, jimgina keyingi kodga o'tadi. Tuzatish: avval maydonni oling, keyin uning value sini.

9.6 name siz maydon

<input id="ism"> — name yo'q. forma.elements.ism uni id bo'yicha baribir topadi, lekin bu maydon serverga umuman ketmaydi: brauzer faqat name li maydonlarni jo'natadi. Tuzatish: har bir yuboriladigan maydonga name yozing.

10. Mashqlar

1-mashq (oson): Nima chiqadi?

Forma: <input name="soni" type="number"> (bo'sh), <input type="checkbox" name="choy"> (belgilanmagan) va ikki radio name="joy" (hech biri tanlanmagan). Bo'sh joylarni to'ldiring:

  1. el.soni.value → bo'sh satr yoki boshqa narsa?
  2. Number(el.soni.value) →
  3. el.choy.value →
  4. el.choy.checked →
  5. el.joy.value → bo'sh satrmi, null mi?
Yechim
  1. "" — bo'sh maydonning value si bo'sh satr.
  2. 0 — Number("") nol beradi. Tuzoq shu yerda.
  3. "on" — value atributi yozilmagan checkbox'ning standart qiymati. Belgilanganmi-yo'qmi — farqi yo'q.
  4. false — belgi faqat checked da.
  5. "" — radio guruhida hech biri tanlanmagan.

2-mashq (o'rta): Hisob-kitob formasi

«Bahor» kassasi uchun forma yozing: taom (select: osh 35 000, lag'mon 28 000, manti 30 000) va soni (number, 1–10). «Hisoblash» bosilganda forma ostida "Manti × 3 = 90000 so'm" chiqsin. Ishora: narxlarni obyektda saqlang ({ osh: 35000, ... }), kalit — select ning value si; taom nomini selectedOptions[0].text dan oling (Obyekt: kalit-qiymat juftliklari).

Yechim
html
<form id="kassa">
  <label>Taom
    <select name="taom">
      <option value="osh">Osh</option>
      <option value="lagmon">Lag'mon</option>
      <option value="manti">Manti</option>
    </select>
  </label>
  <label>Soni <input name="soni" type="number" value="1"
                     required min="1" max="10"></label>
  <button type="submit">Hisoblash</button>
</form>
<p id="jami"></p>
<script>
  const narxlar = { osh: 35000, lagmon: 28000, manti: 30000 };
  const forma = document.querySelector("#kassa");
  const jami = document.querySelector("#jami");

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const el = forma.elements;
    const nomi = el.taom.selectedOptions[0].text;
    const soni = el.soni.valueAsNumber;
    const summa = narxlar[el.taom.value] * soni;
    jami.textContent = `${nomi} × ${soni} = ${summa} so'm`;
  });
</script>

"Manti" va 3 ni tanlab bosing — "Manti × 3 = 90000 so'm". valueAsNumber tufayli soni — son, ko'paytma to'g'ri. required va min/max bo'sh yoki 0 qiymatni brauzerning o'zida to'xtatadi.

3-mashq (qiyin): Qo'shimchalar ro'yxati

Bron formasiga uchta checkbox qo'shing, hammasi name="qoshimcha": "Tandir non", "Salat", "Ko'k choy". Yuborilganda konsolga belgilanganlarning value lari massiv bo'lib chiqsin, masalan (2) ['non', 'choy']. Hech biri belgilanmasa — bo'sh massiv.

Ishora: bir xil name li checkbox'lar ham radio kabi RadioNodeList bo'lib keladi, lekin uning value si checkbox'lar uchun ishlamaydi. Ro'yxatni for...of bilan aylanib, checked larini yig'ing.

Yechim
html
<form id="bron">
  <fieldset>
    <legend>Qo'shimchalar</legend>
    <label>
      <input type="checkbox" name="qoshimcha" value="non" checked>
      Tandir non
    </label>
    <label>
      <input type="checkbox" name="qoshimcha" value="salat"> Salat
    </label>
    <label>
      <input type="checkbox" name="qoshimcha" value="choy" checked>
      Ko'k choy
    </label>
  </fieldset>
  <button type="submit">Bron qilish</button>
</form>
<script>
  const forma = document.querySelector("#bron");

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const tanlangan = [];
    for (const katak of forma.elements.qoshimcha) {
      if (katak.checked) {
        tanlangan.push(katak.value);
      }
    }
    console.log(tanlangan);
  });
</script>

Bosganingizda konsolda (2) ['non', 'choy'] chiqadi. Belgilarni olib tashlab, yana bosing — (0) [], ya'ni bo'sh massiv (Chrome konsoli uni qisqa qilib [] deb ko'rsatadi). Bitta checkbox qolsa ehtiyot bo'ling: name takrorlanmasa, forma.elements.qoshimcha ro'yxat emas, bitta element bo'ladi va for...of xato beradi. FormData darsidagi getAll bu muammoni butunlay yo'q qiladi.

4-mashq: Portfolio qadami — aloqa formasini ushlash

Portfolio'ngizning aloqa/index.html sahifasida forma bor (Yakuniy loyiha): ism, email, "Qaysi mavzuda?" radio guruhi (mavzu) va xabar. U https://example.com/aloqa ga jo'natadi — bunday server yo'q, mehmon xato sahifasini ko'radi. Server Express darsidan keyin paydo bo'ladi. Hozircha JavaScript formani ushlab, halol xabar chiqarsin.

  1. aloqa/index.html da formadan keyin bo'sh paragraf qo'shing: <p id="aloqa-natija"></p>.
  2. asosiy.js ga aloqaFormasiniUla funksiyasini yozing. Formani form[action$="/aloqa"] selektori bilan toping (manzil /aloqa bilan tugaydigan forma). Forma yo'q sahifalarda funksiya jimgina tugasin.
  3. submit da: standart harakatni to'xtating, ism (probellarsiz) va mavzuni o'qing, #aloqa-natija ga "Rahmat, Ali! Xabaringiz qabul qilindi." yozing va formani reset() qiling.
  4. Halollik uchun xabar oxiriga qo'shing: "(Hozircha namuna: xabar hech qayerga yuborilmadi.)"
  5. Konsolda tekshiring, keyin commit: Aloqa: formani JS bilan ushla.
Yechim

asosiy.js ga (oldingi funksiyalardan keyin):

js
function aloqaFormasiniUla() {
  const forma = document.querySelector('form[action$="/aloqa"]');
  const natija = document.querySelector("#aloqa-natija");
  if (forma === null || natija === null) {
    return;
  }

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const el = forma.elements;
    const ism = el.ism.value.trim();
    console.log("Aloqa:", ism, el.mavzu.value);

    natija.textContent =
      `Rahmat, ${ism}! Xabaringiz qabul qilindi. ` +
      "(Hozircha namuna: xabar hech qayerga yuborilmadi.)";
    forma.reset();
  });
}

aloqaFormasiniUla();

Natijani shu formaga o'xshash parchada tekshiring:

html
<form action="https://example.com/aloqa" method="post">
  <p><label for="ism">Ismingiz</label>
    <input id="ism" name="ism" value="Ali" required></p>
  <fieldset>
    <legend>Qaysi mavzuda?</legend>
    <p><input id="mavzu-ish" name="mavzu" type="radio"
              value="ish" checked required>
      <label for="mavzu-ish">Ish taklifi</label></p>
  </fieldset>
  <button type="submit">Yuborish</button>
</form>
<p id="aloqa-natija"></p>
<script>
  function aloqaFormasiniUla() {
    const forma = document.querySelector('form[action$="/aloqa"]');
    const natija = document.querySelector("#aloqa-natija");
    if (forma === null || natija === null) {
      return;
    }
    forma.addEventListener("submit", (event) => {
      event.preventDefault();
      const el = forma.elements;
      const ism = el.ism.value.trim();
      console.log("Aloqa:", ism, el.mavzu.value);
      natija.textContent =
        `Rahmat, ${ism}! Xabaringiz qabul qilindi. ` +
        "(Hozircha namuna: xabar hech qayerga yuborilmadi.)";
      forma.reset();
    });
  }
  aloqaFormasiniUla();
</script>

«Yuborish» ni bosing: forma ostida rahmat xabari chiqadi, konsolda Aloqa: Ali ish, maydonlar esa boshlang'ich holatiga qaytadi (reset). Bosh sahifada (forma yo'q) konsolda hech qanday xato chiqmasligini ham tekshiring.

#aloqa-natija ekran o'quvchiga hali "ovoz chiqarmaydi" — Malika rahmat xabarini eshitmaydi. Buni Dinamik UI'da qulaylik darsida tuzatamiz. Keyingi uch darsda esa shu forma tekshiruv va o'zbekcha xabarlarga ega bo'ladi.

11. Real ishda

  • Deyarli har bir sayt formani shu usul bilan ushlaydi: submit → preventDefault → ma'lumotni yig'ish → serverga fetch bilan jo'natish → natijani sahifada ko'rsatish. Ro'yxatdan o'tish, izoh qoldirish, savatga qo'shish — hammasi.
  • React kabi freymvorklarda (kursda alohida o'rganamiz, hozir bilish shart emas) ham ostida aynan shu submit va preventDefault turadi.
  • Analitika "forma yuborildi" hodisasini submit da yozadi. click da yozilsa, xato bilan to'xtagan urinishlar ham "yuborildi" bo'lib qoladi.
  • Intervyuda so'raladi: "Formani yuborishni qanday to'xtatasiz?", "Nega click emas, submit?", "input.value qanday turda?". Uchalasiga bugun javob berdingiz.

Xulosa

  • Formani ushlash: formaning submit hodisasi + event.preventDefault().
  • submit faqat brauzer tekshiruvidan o'tgan formada keladi; click esa bo'sh formada ham ishlaydi.
  • Maydonlar — forma.elements.nom orqali; forma.nom qisqa yo'li formaning o'z xususiyatlari bilan to'qnashadi.
  • value doim satr: sonni valueAsNumber bilan oling, Number("") — 0 tuzog'idan ehtiyot bo'ling.
  • Checkbox — checked, radio guruhi — forma.elements.nom.value, ko'p tanlovli select — selectedOptions.
  • JavaScript tekshiruvi — qulaylik; xavfsizlik — serverda.

Keyingi dars: input va change: jonli tekshirish — mehmon yozayotgan paytdayoq javob beramiz: belgi hisoblagichi va o'z vaqtida chiqadigan xato xabarlari.

Manbalar

  • MDN: "HTMLFormElement: submit event", "HTMLFormElement.elements", "RadioNodeList" — developer.mozilla.org
  • MDN: "HTMLInputElement: valueAsNumber", "HTMLSelectElement: selectedOptions" — developer.mozilla.org
  • HTML Standard: "Form submission", "Implicit submission" — html.spec.whatwg.org
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript'da forma: qiymatlarni o'qish va submit hodisasi — IlmHamroh