MakeFirstStep· Frontend + зеҳни сунъӣ

Дарси 10 · DOM ва интерфейс

Шаклҳо ва санҷиш (валидатсия)

Сабти ном, вуруд, фармоиши палав бо расонидан, номнависӣ ба курс — қариб ҳар чизе, ки корбар ба сайт «медиҳад», тавассути шакл ворид мекунад. Ва корбарон хато мекунанд: майдонҳоро холӣ мегузоранд, телефонро бе рамзи кишвар менависанд, дар охири email фосила мегузоранд. Имрӯз шумо хондани маълумот аз шакл ва бо мулоимат фаҳмондани он ки чиро бояд ислоҳ кард — ҳанӯз пеш аз ирсол — меомӯзед.

  • value ва checked-ро дар майдонҳои гуногун хондан: матн, адад, тугмаҳои радио, чекбоксҳо, рӯйхат
  • Ирсоли шаклро бо ҳодисаи submit гирифтан ва маълумотро тавассути FormData ҷамъ кардан
  • Санҷиши дарунсохти браузерро истифода бурдан ва фаҳмидан, ки чӣ камбуд дорад
  • Ибораҳои муқаррарии оддӣ навиштан ва дар санҷишҳо татбиқ кардан
  • Функсияҳои санҷиши худиро навиштан ва матнҳои фаҳмои хатоҳоро бевосита дар зери майдонҳо нишон додан
  • Санҷиши «зинда»-ро анҷом додан: майдонро ҳангоми воридкунии маълумот санҷидан
Бо ин саҳифа чӣ тавр кор кардан лозим

Коди дар заминаи торик бо тугмаи ▶ Запустить — зинда аст: онро тағйир диҳед ва натиҷаро бубинед. Дар блокҳои консолӣ шакл бевосита аз сатри HTML сохта мешавад — ба ин восита мо метавонем кодро бе воридкунии дастӣ санҷем. Тирезаҳо бо ҷадвалҳои index.html / style.css / script.js — саҳифаҳои хурданд: дар боло код, дар поён пешнамоиш, ки дар он воқеан клик кардан ва чоп кардан мумкин аст. Оғоз — Ctrl + Enter. Ишораҳои вазифаҳо пинҳон шудаанд: аввал 15 дақиқа худатон кӯшиш кунед.

01 Шакл ва майдонҳои он: value ва checked

Шакл дар HTML — ин теги <form> аст, ки дар дохили он майдонҳои воридкунӣ ҷойгиранд: <input>, <select>, <textarea> ва тугмаи ирсол. Аломатгузориро шумо аллакай медонед — имрӯз ба мо муҳим аст, ки чӣ тавр маълумотро аз ин майдонҳо баровардан бо ёрии JavaScript.

Муқоиса аз ҳаёт

Анкета дар бонк ё бланки фармоиш дар чойхона: дар ҳар сатр ном («Ном», «Телефон») ва он чизе, ки шумо навиштаед, ҳаст. Дар шакл ном — атрибути name аст, ва он чизе, ки навишта шудааст, — хосияти value. Оператор бланки пуркардашударо мегирад ва сатр ба сатр мехонад — скрипти шумо айнан ҳамин тавр кор мекунад.

Майдонро чӣ тавр ёфтан

Ҳар майдонро тавассути querySelector ёфтан мумкин аст, аммо шакл роҳи қулай дорад — маҷмӯаи form.elements. Дар он майдонҳо аз рӯи атрибути name дастрасанд:

Майдонҳои шаклро мехонем · Ctrl + Enter
<form id="reg">
  <label>Имя <input name="fullName" value="Мадина"></label>
  <label>Возраст <input name="age" type="number" value="19"></label>
  <label>Город
    <select name="city">
      <option value="dushanbe">Душанбе</option>
      <option value="khujand">Худжанд</option>
    </select>
  </label>
  <label><input type="checkbox" name="agree"> Согласен с правилами</label>
  <button type="button" id="show">Показать значения</button>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.

Иҷро кунед, дар пешнамоиш чизеро тағйир диҳед (номи дигар ворид кунед, нишона гузоред) ва «Показать значения»-ро пахш кунед. Инак мо чиро ва аз куҷо мехонем:

МайдонЧиро мехонемЧӣ мегирем
<input type="text">, email, password, tel.valueСатр — айнан он чи дар майдон ҳаст (бо фосилаҳо)
<input type="number">.valueНиз сатр! "19", на адад. Майдони холӣ — ""
<textarea>.valueСатр (бо гузаришҳои сатр \n)
<select>.valueАтрибути value-и <option>-и интихобшуда, на матни намоёни он
<input type="checkbox">.checkedtrue ё false
Гурӯҳи <input type="radio"> бо як nameform.elements.ном.valuevalue-и тугмаи интихобшуда (ё "", агар чизе интихоб нашуда бошад)

Тузоқи асосӣ: value — ҳамеша сатр

Ҳатто дар type="number" қимат ҳамчун сатр меояд. Ин ҳамон ҳикояи табдили навъҳо аз дарси 2 аст:

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <input name="plov" type="number" value="40">
  <input name="tea" type="number" value="10">`;

const plov = document.querySelector("[name=plov]").value;
const tea = document.querySelector("[name=tea]").value;

console.log(plov + tea);                   // "4010" — ҳамчун сатр часпиданд!
console.log(Number(plov) + Number(tea));   // 50 — аввал ба адад табдил медиҳем
console.log(document.querySelector("[name=plov]").valueAsNumber); // 40 — фавран адад
Хатоҳои маъмул

1) Дар чекбокс .value-ро ба ҷои .checked хондан — шумо ҳамеша сатри "on"-ро мегиред, ҳатто агар нишона набошад. 2) .value-ро фаромӯш кардан ва худи элементро чоп кардан: console.log(form.elements.fullName) тегро нишон медиҳад, на матнро. 3) Ду майдони ададиро тавассути + ҷамъ кардан — часпидани сатрҳо мешавад.

Атрибутҳои name, label ва type

  • name — «номи майдон». Тавассути он мо майдонро дар form.elements меёбем, ва маҳз аз рӯи он маълумот ба FormData меафтад (бахши 3). Бе name майдон барои шакл «ноаён» аст.
  • <label> — тавзеҳ. Майдонро дар он печонед ё тавассути for ва id пайваст кунед: он гоҳ клик ба матн курсорро ба майдон мегузорад, ва хонандаҳои экранӣ мефаҳманд, ки пеши онҳо кадом майдон аст.
  • type — ба браузер ишора мекунад, ки дар телефон кадом клавиатураро нишон диҳад (tel — рақамӣ, email — бо «@») ва кадом санҷишҳоро фаъол кунад.

Барои муфассалтар хондан: Свойства и методы формы · MDN: элемент input

Амалиёт: мустаҳкам мекунем

Дар вазифаҳои консолӣ шаклҳо аз сатри HTML сохта мешаванд. Кори шумо — хондани қиматҳои лозимӣ.

ВАЗИФАИ 1.1

Анкетаи донишҷӯ

осон

Дар шакл қиматҳо аллакай ҳастанд. Онҳоро бо се сатр дар формате, ки дар намуна аст, чоп кунед: ном, шаҳр ва курс.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" value="Мадина Каримова">
    <input name="city" value="Душанбе">
    <input name="course" value="Frontend + AI">
  </form>`;

const form = document.querySelector("form");

// се сатрро тавассути console.log ва form.elements чоп кунед
Натиҷаи интизоршаванда
Имя: Мадина Каримова
Город: Душанбе
Курс: Frontend + AI
Ишора 1

Майдонро чунин меёбем: form.elements.fullName — аз рӯи қимати атрибути name.

Ишора 2

Қимат — хосияти .value аст. Сатрро часпонед: console.log("Имя: " + form.elements.fullName.value);

ВАЗИФАИ 1.2

Ҳисоб дар чойхона

осон

Хазинадор арзиши палав ва чойро дар майдонҳои ададӣ ворид мекунад. Код бояд ҷамъи умумӣ ва ҷамъро бо таҳфифи 10% чоп кунад, аммо ҳоло чизи бемаъние мисли 4010 чоп мекунад. Хондани қиматҳоро ислоҳ кунед, сатрҳои console.log-ро нарасонед.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="plov" type="number" value="40">
    <input name="tea" type="number" value="10">
  </form>`;

const form = document.querySelector("form");
const plov = form.elements.plov.value;
const tea = form.elements.tea.value;

console.log("Итого:", plov + tea);
console.log("Со скидкой 10%:", (plov + tea) * 0.9);
Натиҷаи интизоршаванда
Итого: 50
Со скидкой 10%: 45
Ишора 1

Оператори + бо сатрҳо онҳоро мечаспонад. Лозим аст, ки plov ва tea адад бошанд.

Ишора 2

Қиматҳоро ҳангоми хондан фавран ба адад табдил диҳед: const plov = Number(form.elements.plov.value); — ва ҳамин тавр барои tea.

ВАЗИФАИ 1.3

Тугмаҳои радио, чекбоксҳо ва рӯйхат

миёна

Шакли номнависӣ ба курс рӯйхат, гурӯҳи тугмаҳои радио ва ду чекбокс дорад. Чор сатр чоп кунед. Барои чекбоксҳо маҳз true / false чоп кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <select name="course">
      <option value="html">HTML и CSS</option>
      <option value="js" selected>JavaScript</option>
    </select>
    <input type="radio" name="format" value="offline">
    <input type="radio" name="format" value="online" checked>
    <input type="checkbox" name="agree" checked>
    <input type="checkbox" name="news">
  </form>`;

const form = document.querySelector("form");

// Курс: ...  Формат: ...  Согласие: ...  Рассылка: ...
Натиҷаи интизоршаванда
Курс: js
Формат: online
Согласие: true
Рассылка: false
Ишора 1

Барои рӯйхат ва барои гурӯҳи тугмаҳои радио form.elements.ном.value мувофиқ аст. Барои чекбоксҳо — .checked.

Ишора 2

Тугмаҳои радио бо name-и якхела гурӯҳ месозанд: form.elements.format.value қимати интихобшударо бармегардонад ("online").

02 Ирсоли шакл: ҳодисаи submit

Вақте одам тугмаи «Отправить»-ро пахш мекунад ё дар майдони матнӣ Enter-ро мезанад, шакл ҳодисаи submit-ро ба вуҷуд меоварад. Агар чизе накунед, браузер маълумотро ба сервер мефиристад ва саҳифаро аз нав бор мекунад — тамоми маълумоти воридшуда ва тамоми мантиқи JS-и шумо нест мешавад. Бинобар ин сатри аввали ҳар коркардкунандаи ирсол — event.preventDefault() (шумо инро аз дарси 9 медонед).

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form id="order">
    <input name="dish" value="Оши палав">
    <input name="qty" type="number" value="2">
    <button>Заказать</button>
  </form>`;

const form = document.querySelector("#order");

form.addEventListener("submit", (event) => {
  event.preventDefault();                       // намегузорем, ки саҳифа аз нав бор шавад
  const dish = form.elements.dish.value;        // қиматҳоро ДАР ДОХИЛИ коркардкунанда мехонем
  const qty = Number(form.elements.qty.value);
  console.log(`Заказ принят: ${dish} × ${qty}`);
});

form.dispatchEvent(new Event("submit", { cancelable: true }));   // пахши тугмаи «Заказать»-ро тақлид мекунем
1 · Воридкунӣодам майдонҳоро пур мекунад
→
2 · Ирсолклик ба тугма ё Enter
→
3 · submitҳодиса дар <form>
→
4 · Коди шумоpreventDefault(), хондани майдонҳо, санҷиш

submit-ро мешунавем, на click-ро

Бад: click дар тугма

Агар одам шаклро бо клавишаи Enter фиристад, тугмаро касе пахш накардааст — коди шумо кор намекунад.

JavaScript
button.addEventListener("click", () => {
  // Enter дар майдон ба ин ҷо намеояд
});
Хуб: submit дар шакл

Дар ҳар роҳи ирсол кор мекунад: муш, Enter, тугма дар телефон.

JavaScript
form.addEventListener("submit", (event) => {
  event.preventDefault();
  // ...
});

Тафсилоти муфид

event.target
Дар ҳодисаи submit ин худи шакл аст. Пас майдонҳоро чун event.target.elements.email гирифтан мумкин аст — коркардкунанда аз тағйирёбандаи берунӣ вобаста нест.
form.reset()
Ҳамаи майдонҳоро ба қиматҳои аввала бармегардонад (ҳамонҳое, ки дар атрибутҳои value / checked навишта шудаанд, ё холӣ). Баъди ирсоли бомуваффақият даъват мекунем.
form.dispatchEvent(new Event("submit", { cancelable: true }))
Ҳодисаи submit-ро дастӣ «мепаронад». Бо ин усул мо дар мисолҳо ва вазифаҳо пахши «Отправить»-ро тақлид мекунем: қуттии таълимии санҷиш ирсоли воқеии шаклҳоро манъ мекунад, бинобар ин одатии form.requestSubmit() (он тугмаро худаш пахш мекунад) дар ин ҷо кор намекунад. Дар сайти оддӣ шумо ба тугма клик мекунед ё маҳз requestSubmit()-ро даъват мекунед.
<button type="button">
Тугма дар дохили шакл ба таври пешфарз онро мефиристад. Агар тугма барои чизи дигар лозим бошад (масалан, «нишон додани парол»), type="button" нависед.
novalidate
Атрибути шакл: санҷиши дарунсохти браузерро хомӯш мекунад, то санҷиши худии шумо кор кунад (бахши 4).
Хатои маъмул: қиматро хеле барвақт мехонем

Қимати майдон ҳангоми чоп кардани одам тағйир меёбад. Бинобар ин онро дар лаҳзаи ҳодиса, дар дохили коркардкунанда хондан лозим аст. Агар як маротиба дар оғози скрипт хонед, шумо он чизро мегиред, ки ҳангоми бор шудани саҳифа дар майдон буд (аксар вақт — сатри холӣ).

Хато: email-и холӣ · Ctrl + Enter
document.body.innerHTML = `<form><input name="email"></form>`;
const form = document.querySelector("form");

const email = form.elements.email.value;   // ✖ фавран хондем — ҳанӯз холист

form.addEventListener("submit", (event) => {
  event.preventDefault();
  console.log("email:", "[" + email + "]");
});

form.elements.email.value = "madina@mail.tj";  // «корбар» суроғаро навишт
form.dispatchEvent(new Event("submit", { cancelable: true }));                          // → email: []
Муқоиса аз ҳаёт

Пешхизмат дар чойхона фармоишро на он вақт сабт мекунад, ки шумо танҳо ба сари миз нишастед, балки он вақт, ки шумо гуфтед «метавон фармоиш дод». Қиматҳои шаклро низ ҳамин тавр мехонем — дар лаҳзаи ирсол, на пешакӣ.

Барои муфассалтар хондан: Отправка формы: событие и метод submit · События change, input, cut, copy, paste

Амалиёт: мустаҳкам мекунем

Дар ҳамаи вазифаҳо скрипт худаш майдонҳоро «пур мекунад» ва ҳодисаи submit-ро даъват мекунад — шумо бояд коркардкунанда нависед.

ВАЗИФАИ 2.1

Дархост қабул шуд

осон

Ба шакл коркардкунандаи submit илова кунед: он ирсоли пешфарзро бекор мекунад ва сатре бо ном ва телефоне, ки ҳоло дар майдонҳост, чоп мекунад.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" value="Рустам">
    <input name="phone" value="+992927771234">
  </form>`;

const form = document.querySelector("form");

// коркардкунандаи submit-ро дар ин ҷо илова кунед


form.dispatchEvent(new Event("submit", { cancelable: true }));
Натиҷаи интизоршаванда
Заявка принята: Рустам, +992927771234
Ишора 1

form.addEventListener("submit", (event) => { ... }) — ва сатри аввал дар дохил event.preventDefault().

Ишора 2

Қиматҳоро дар дохили коркардкунанда хонед: form.elements.fullName.value ва form.elements.phone.value.

ВАЗИФАИ 2.2

Хаторо ёб: шаҳр гум шуд

осон

Корбар «Худжанд»-ро навишт, аммо коркардкунанда шаҳри холиро чоп мекунад. Сабабро ёбед ва ислоҳ кунед. Ду сатри охири скрипт (пуркунӣ ва ирсол)-ро тағйир додан мумкин нест.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `<form><input name="city"></form>`;
const form = document.querySelector("form");

const city = form.elements.city.value;

form.addEventListener("submit", (event) => {
  event.preventDefault();
  console.log("Город:", city);
});

form.elements.city.value = "Худжанд";   // тағйир надиҳед
form.dispatchEvent(new Event("submit", { cancelable: true }));                    // тағйир надиҳед
Натиҷаи интизоршаванда
Город: Худжанд
Ишора 1

Сатри const city = ... кай иҷро мешавад? То он ки қимати майдонро тағйир доданд.

Ишора 2

Хондани қиматро ба дохили коркардкунандаи submit интиқол диҳед.

ВАЗИФАИ 2.3

Шакли вуруд

миёна

Коркардкунандаи шакли вурудро нависед. Логинро аз фосилаҳои канорӣ тоза кардан лозим аст (trim()). Агар логин ё парол холӣ бошад — Ошибка: заполните все поля-ро чоп кунед. Вагарна Вход выполнен: логин-ро чоп кунед, шаклро барқарор кунед ва хабар диҳед, ки майдони логин баъд аз он холист ё не.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="login">
    <input name="password" type="password">
  </form>`;

const form = document.querySelector("form");

// коркардкунандаи submit


function submitWith(login, password) {
  form.elements.login.value = login;
  form.elements.password.value = password;
  form.dispatchEvent(new Event("submit", { cancelable: true }));
}

submitWith("", "12345");
submitWith("  madina  ", "");
submitWith("  madina  ", "qwerty1");
Натиҷаи интизоршаванда
Ошибка: заполните все поля
Ошибка: заполните все поля
Вход выполнен: madina
Логин после сброса: пусто
Ишора 1

Тартиб: preventDefault → логинро хондан ва trim() → паролро хондан → санҷиши if (!login || !password) → баъди хабари хато return.

Ишора 2

Баъди вуруди бомуваффақият: form.reset(), баъд console.log("Логин после сброса:", form.elements.login.value === "" ? "пусто" : "заполнено").

03 FormData: ҳамаи майдонҳоро якбора ҷамъ мекунем

Агар дар шакл 10 майдон бошад, онҳоро якто-якто тавассути .value хондан — дилгиркунанда аст ва чизеро фаромӯш кардан осон аст. Барои ин дар браузер объекти дарунсохти FormData ҳаст: шумо шаклро ба он медиҳед, ва он худаш ҳамаи майдонҳоро бо атрибути name гашта, «ном → қимат»-и онҳоро ҷамъ мекунад.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" value="Мадина">
    <select name="city">
      <option value="dushanbe" selected>Душанбе</option>
      <option value="khujand">Худжанд</option>
    </select>
    <input type="checkbox" name="skills" value="css" checked>
    <input type="checkbox" name="skills" value="js" checked>
    <input type="checkbox" name="skills" value="git">
    <input type="checkbox" name="agree" checked>
    <input type="checkbox" name="news">
  </form>`;

const form = document.querySelector("form");
const data = new FormData(form);

console.log(data.get("fullName"));    // Мадина — як қимат аз рӯи ном
console.log(data.getAll("skills"));   // ["css", "js"] — ҳамаи қиматҳои як ном
console.log(data.has("news"));        // false — чекбокси бе нишона ба FormData намеафтад
console.log(data.get("agree"));       // "on" — дар чекбокси бе атрибути value қимат "on" аст

for (const [key, value] of data) {    // FormData-ро ҳамчун ҷуфтҳои «калид, қимат» гузаштан мумкин аст
  console.log(key, "=", value);
}

Аз FormData объекти маъмулиро ба осонӣ гирифтан мумкин аст — он лозим мешавад, то маълумотро захира кунед ё ба корбар нишон диҳед (дар шакли JSON, мисли дарси 7):

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" value="Мадина">
    <input name="age" type="number" value="19">
  </form>`;

const data = new FormData(document.querySelector("form"));
const obj = Object.fromEntries(data);   // { fullName: "Мадина", age: "19" }

console.log(JSON.stringify(obj));
console.log(typeof obj.age);   // string — ҳамаи қиматҳо ҳанӯз ҳам сатранд!
Муқоиса аз ҳаёт

Ин мисли курьери почта аст, ки аз идора ҳамаи бланкҳои пуркардашударо дар як баста мегирад. Аммо ба баста вай танҳо бланкҳоро бо имзо (name) ва танҳо онҳое, ки пур шудаанд, мегирад. Майдон бе name — бланки беном аст, курьер онро намегирад.

Чӣ ба FormData намеафтад
  • майдонҳо бе атрибути name;
  • майдонҳо бо атрибути disabled (барои «танҳо хондан» readonly-ро истифода баред);
  • чекбоксҳо ва тугмаҳои радио бе нишона — калиди онҳо дар маълумот танҳо нест. Агар false лозим бошад, checked-ро бевосита гиред: form.elements.news.checked.

Ва боз Object.fromEntries барои номҳои такроршаванда (skills) танҳо қимати охирин-ро мегузорад, бинобар ин барои гурӯҳҳои чекбокс data.getAll("skills")-ро истифода баред.

Баъдтар, вақте ба кор бо сервер мерасем, ҳамин объекти FormData-ро ҳамон тавр ба сервер фиристодан мумкин мешавад. Ҳоло мақсади мо — ҷамъ кардани маълумот ва боварӣ ҳосил кардан аст, ки он дуруст аст.

Барои муфассалтар хондан: FormData · MDN: FormData

Амалиёт: мустаҳкам мекунем

Се вазифа — аз хондани оддӣ то функсияе, ки шаклро ба объекти тайёр табдил медиҳад.

ВАЗИФАИ 3.1

Се қимат аз FormData

осон

Аз шакл FormData созед ва ном, email ва шаҳрро чоп кунед — ҳар кадомро дар сатри худаш.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" value="Зарина Ахмедова">
    <input name="email" value="zarina@mail.tj">
    <select name="city">
      <option value="dushanbe" selected>Душанбе</option>
      <option value="khujand">Худжанд</option>
    </select>
  </form>`;

const form = document.querySelector("form");

// FormData созед ва се қиматро тавассути data.get(...) чоп кунед
Натиҷаи интизоршаванда
Имя: Зарина Ахмедова
Email: zarina@mail.tj
Город: dushanbe
Ишора 1

const data = new FormData(form); — шакл дар қавс дода мешавад.

Ишора 2

data.get("email") қимати майдонро бо name="email" бармегардонад.

ВАЗИФАИ 3.2

Шаклро таъмир кун: майдонҳои гумшуда

миёна

Аз се майдон ба FormData танҳо яктояш афтод. HTML-и шакл-ро (на JS) ислоҳ кунед, то дар объекти ниҳоӣ се майдон бошад: fullName, phone ва agree. Телефон бояд барои корбар таҳриршаванда нашавад, аммо ба маълумот афтад.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input value="Далер">
    <input name="phone" value="+992900000000" disabled>
    <input type="checkbox" name="agree" checked>
  </form>`;

const form = document.querySelector("form");
console.log(JSON.stringify(Object.fromEntries(new FormData(form))));
Натиҷаи интизоршаванда
{"fullName":"Далер","phone":"+992900000000","agree":"on"}
Ишора 1

Ба майдони аввал як атрибут намерасад, ки ба он «ном» дар маълумоти шакл медиҳад.

Ишора 2

Дар майдони дуюм disabled-ро ба readonly иваз кунед: он ҳанӯз таҳриршаванда нест, аммо аллакай дар ирсол иштирок мекунад.

ВАЗИФАИ 3.3

Функсияи readForm

душвор

Функсияи readForm(form)-ро нависед, ки объектро бо чунин майдонҳо ба чунин тартиб бармегардонад: fullName (сатр), age (адад), skills (массиви малакаҳои қайдшуда), agree ва news (true/false).

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" value="Рустам">
    <input name="age" type="number" value="21">
    <input type="checkbox" name="skills" value="html" checked>
    <input type="checkbox" name="skills" value="css">
    <input type="checkbox" name="skills" value="js" checked>
    <input type="checkbox" name="agree" checked>
    <input type="checkbox" name="news">
  </form>`;

function readForm(form) {
  // объекти { fullName, age, skills, agree, news }-ро баргардонед
}

console.log(JSON.stringify(readForm(document.querySelector("form"))));
Натиҷаи интизоршаванда
{"fullName":"Рустам","age":21,"skills":["html","js"],"agree":true,"news":false}
Ишора 1

Аз const data = new FormData(form); оғоз кунед. Сатр ва массивро аз он ҷо гиред: data.get(...) ва data.getAll(...).

Ишора 2

Синну сол — Number(data.get("age")). Чекбоксҳо дар FormData метавонанд набошанд, бинобар ин барои онҳо form.elements.agree.checked боэътимодтар аст.

04 Санҷиши дарунсохти браузер

Санҷиш (валидатсия) — ин тафтиш аст, ки маълумот мувофиқ аст: майдон холӣ нест, email ба email монанд аст, синну сол дар ҳудуди оқилона. Браузер санҷиши тайёр дорад — онро атрибутҳои HTML фаъол мекунанд, ва JavaScript метавонад онро пурсон шавад.

АтрибутЧиро месанҷадНамуна
requiredМайдон ҳатмист<input required>
type="email", urlФормати суроға (@ ҳаст, домен ҳаст)<input type="email">
min, maxҲудуди адад (ва сана)<input type="number" min="16" max="70">
minlength, maxlengthДарозии матн<input minlength="2" maxlength="30">
patternМатн ба қолаб мувофиқ аст (ибораи муқаррарӣ — бахши 5)<input pattern="[0-9]{4}">

Бевосита дар пешнамоиш кӯшиш кунед: майдонро холӣ гузоред ё «ali@» нависед ва «Отправить»-ро пахш кунед. Браузер худаш ишораи пайдошавандаро нишон медиҳад ва шаклро пеш намегузаронад.

Санҷиши дарунсохт · Ctrl + Enter
<form id="f">
  <label>Имя <input name="fullName" required></label>
  <label>Email <input name="email" type="email" required></label>
  <label>Возраст <input name="age" type="number" min="16" max="70"></label>
  <button>Отправить</button>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.

Аз браузер аз JavaScript мепурсем

Ҳар майдон усулҳо ва хосиятҳо дорад, ки натиҷаи санҷиши дарунсохтро хабар медиҳанд:

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="email" type="email" required value="madina@">
  </form>`;

const email = document.querySelector("[name=email]");

console.log(email.checkValidity());          // false — майдон санҷишро намегузарад
console.log(email.validity.valid);           // false — ҳамон чиз, аммо ҳамчун хосият
console.log(email.validity.typeMismatch);    // true — «навъ нодуруст»: ин email нест
console.log(email.validity.valueMissing);    // false — майдон холӣ нест

email.value = "madina@mail.tj";
console.log(email.checkValidity());          // true — акнун ҳама чиз хуб аст
checkValidity()
true / false бармегардонад. Дар шакл ҳамаи майдонҳои онро якбора месанҷад.
reportValidity()
Ҳамон, аммо боз ишораи пайдошавандаи браузерро ба корбар нишон медиҳад.
validity
Объект бо парчамҳои сабабҳо: valueMissing (холӣ дар required), typeMismatch (на email/url), patternMismatch (pattern мувофиқ наомад), rangeUnderflow / rangeOverflow (аз min кам / аз max зиёд), tooShort / tooLong, customError.
validationMessage
Матни хато бо забони браузери корбар. Дар як одам он русӣ, дар дигаре англисӣ аст — онро идора кардан мумкин нест.
setCustomValidity("матн")
Майдонро бо паёми шумо дастӣ нодуруст эълон мекунад. Сатри холӣ "" хаторо мебардорад.
setCustomValidity: қоидаҳои худӣ · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="password" type="password" value="qwerty123">
    <input name="confirm" type="password" value="qwerty321">
  </form>`;

const { password, confirm } = document.querySelector("form").elements;

confirm.setCustomValidity(password.value === confirm.value ? "" : "Пароли не совпадают");

console.log(confirm.checkValidity());        // false — паролҳо гуногунанд
console.log(confirm.validationMessage);      // Пароли не совпадают
Муқоиса аз ҳаёт

Санҷиши дарунсохт мисли посбон дар даромадгоҳи маркази савдо аст: вай чизи равшанро мебинад (чипта ҳаст ё не, пропуск холӣ нест), аммо қоидаҳои мағозаи шуморо намедонад. Вай нахоҳад гуфт «Ба шумо маҳз рақами тоҷикӣ бо рамзи +992 лозим аст» ва сабаби радро бо забони барои шумо фаҳмо ва дар ҷои дурусти саҳифа шарҳ намедиҳад. Барои ин санҷиши худӣ лозим аст.

Санҷиши дарунсохт чӣ камбуд дорад

  • Матнҳои хато — бо забон ва услуби браузер, онҳоро мувофиқи тарҳи сайт тарроҳӣ кардан мумкин нест.
  • Як ҳубобча дар як вақт — одам танҳо хатои аввалро мебинад, на ҳамаро якбора.
  • Қоидаҳои мураккаб — «паролҳо мувофиқанд», «телефон танҳо тоҷикӣ» коди худиро талаб мекунанд.
  • Санҷиши зинда ҳангоми воридкунӣ — бе JavaScript-и худӣ «зебо» намешавад.
Нозукиҳо

1) minlength ва maxlength танҳо вақте месанҷанд, ки қиматро одам ворид мекунад. Агар аз JavaScript input.value = "a" нависед, парчами tooShort кор намекунад. 2) Ҳамаи санҷишҳои браузер ва JS-и шумо дар саҳифа ба осонӣ гузашта мешаванд (кифоя аст DevTools-ро кушоед), бинобар ин дар сайти воқеӣ маълумотро ба таври иловагӣ дар сервер ҳам месанҷанд. Санҷиш дар браузер — ин қулайӣ барои одам аст, на ҳимоя.

Аз ин рӯ дар амал чунин мекунанд: атрибутҳои асосӣ (required, type)-ро барои ишораҳои клавиатураи мобилӣ мегузоранд, ва худи санҷиш ва матнҳои хатоҳоро дар JavaScript менависанд ва ҳубобчаҳои браузериро бо атрибути novalidate дар шакл хомӯш мекунанд:

JavaScript
<form id="reg" novalidate>
  <input name="email" type="email" required>
</form>

Барои муфассалтар хондан: MDN: валидация форм на стороне клиента · MDN: ValidityState

Амалиёт: мустаҳкам мекунем

Аз браузер мепурсем ва ба санҷиши худӣ гузаштанро меомӯзем.

ВАЗИФАИ 4.1

Кӣ нодуруст аст

осон

Дар шакл чор майдон ҳаст. Аз болои form.elements гузаред ва бо як сатр номҳои майдонҳоеро, ки санҷиши браузерро намегузаранд, бо вергул чоп кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" required value="">
    <input name="email" type="email" value="madina@">
    <input name="age" type="number" min="16" max="70" value="15">
    <input name="phone" pattern="\\+992[0-9]{9}" value="+992927771234">
  </form>`;

const form = document.querySelector("form");
const bad = [];

// аз болои form.elements гузаред ва массиви bad-ро бо номҳои майдонҳои нодуруст пур кунед

console.log("Невалидные поля: " + bad.join(", "));
Натиҷаи интизоршаванда
Невалидные поля: fullName, email, age
Ишора 1

for (const field of form.elements) { ... } — ҳамаи майдонҳои шаклро навбатӣ мегузарад.

Ишора 2

Дар дохили давра: if (!field.checkValidity()) bad.push(field.name);

ВАЗИФАИ 4.2

Чаро нодуруст аст

миёна

Функсияи reasonOf(input)-ро нависед. Он ба парчамҳои validity нигоҳ мекунад ва сабабро бармегардонад: "пусто" (valueMissing), "не email" (typeMismatch), "слишком мало" (rangeUnderflow), "не по шаблону" (patternMismatch) ё "ок", агар майдон дуруст бошад.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <input id="a" required value="">
  <input id="b" type="email" value="ali.mail.tj">
  <input id="c" type="number" min="16" value="12">
  <input id="d" pattern="[0-9]{4}" value="12ab">
  <input id="e" required value="всё хорошо">`;

function reasonOf(input) {
  // яке аз панҷ сатрро баргардонед
}

for (const id of ["a", "b", "c", "d", "e"]) {
  console.log(id + ": " + reasonOf(document.getElementById(id)));
}
Натиҷаи интизоршаванда
a: пусто
b: не email
c: слишком мало
d: не по шаблону
e: ок
Ишора 1

Парчамҳо дар input.validity ҳастанд. Навбатӣ санҷед: if (input.validity.valueMissing) return "пусто";

Ишора 2

Баъди чор санҷиш бо return-и барвақт сатри охири функсия — return "ок";

ВАЗИФАИ 4.3

Оё шакл дар маҷмӯъ дуруст аст

осон

Дар шакл майдони ҳатмии «Ном» ва email-и дуруст ҳаст. Натиҷаи checkValidity()-и шакл-ро пеш аз пур кардани ном чоп кунед, баъд номи «Мадина»-ро нависед ва натиҷаро боз як бор чоп кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <form>
    <input name="fullName" required>
    <input name="email" type="email" value="madina@mail.tj">
  </form>`;

const form = document.querySelector("form");

// 1) form.checkValidity()-ро чоп кунед
// 2) номро дар майдони fullName нависед
// 3) form.checkValidity()-ро боз як бор чоп кунед
Натиҷаи интизоршаванда
false
true
Ишора 1

Худи шакл ҳамон усулро дорад, ки майдон: form.checkValidity() — он ҳамаи майдонҳоро якбора месанҷад.

Ишора 2

Қимат чунин таъин мешавад: form.elements.fullName.value = "Мадина";

05 Ибораҳои муқаррарӣ барои навомӯзон

Ибораи муқаррарӣ (regex, «регэксп») — ин қолаби кӯтоҳест, ки тавсиф мекунад, сатр чӣ гуна бояд бошад. «Танҳо рақамҳо», «бо +992 оғоз мешавад ва баъд нӯҳ рақам», «ҳарфҳои лотинӣ ва зерхат» — ҳамаи инро бо як сатр навиштан мумкин аст. Барои санҷиши шаклҳо ин абзори ивазнашаванда аст.

Муқоиса аз ҳаёт

Дӯзанда андоза мегирад ва матоъро аз рӯи қолаб мебурад: қисм ё дақиқ ба қолаб мемонад, ё не. Ибораи муқаррарӣ — қолаб барои матн. Шумо шаклро як маротиба тавсиф мекунед, ва компютер ҳар сатрро ба он мемонад ва ҷавоб медиҳад «мувофиқ аст» ё «мувофиқ нест».

Таҳрир кардан мумкин аст · Ctrl + Enter
const onlyDigits = /^\d+$/;          // байни слэшҳо — қолаб

console.log(onlyDigits.test("12345"));  // true  — мувофиқ аст
console.log(onlyDigits.test("12a45"));  // false — ҳарф ҳаст
console.log(onlyDigits.test(""));       // false — холӣ (ақаллан як рақам лозим аст)

Ибораи муқаррарӣ байни ду слэш навишта мешавад /.../. Усули .test(сатр) true бармегардонад, агар сатр ба қолаб мувофиқ бошад, вагарна — false. Акнун «ҳарфҳои» ин забонро шарҳ медиҳем.

Алифбои регэксп: танҳо якчанд аломат

СабтМаъноНамуна
abcАломатҳои оддӣ маънои худро доранд/tj/ «tj»-ро меёбад
\dЯк рақам (0–9)/\d/ ба «a1» мувофиқ аст
\DЯк аломат, ки рақам НЕСТ/\D/ ба «a1» мувофиқ аст
\sАломати фосила: фосила, таб, гузариш ба сатри нав/\s/ ба «a b» мувофиқ аст
.Ҳар як аломат/a.c/ ба «abc», «a-c» мувофиқ аст
[abc]Як аломат аз рӯйхат/[аеи]/ — яке аз се садонок
[a-z], [0-9]Як аломат аз диапазон/[a-zA-Z]/ — ҳар ҳарфи лотинӣ
[^abc]Як аломат, ки дар рӯйхат НЕСТ/[^\s@]/ — на фосила ва на «@»
^ ва $Оғоз ва анҷоми тамоми сатр/^\d+$/ — тамоми сатр аз рақамҳо
+Пешина — як маротиба ё бештар/\d+/ — адад аз ҳар миқдор рақам
*Пешина — нол маротиба ё бештар/ab*/ — «a», «ab», «abbb»
?Пешина — як маротиба ё на як маротиба ҳам/\+?\d+/ — плюс ҳатмӣ нест
{4}, {3,16}Айнан 4 маротиба / аз 3 то 16 маротиба/\d{9}/ — нӯҳ рақам
\+, \.Слэш пеш аз аломати махсус: худи аломатро меҷӯем\. — маҳз нуқта, на «ҳар аломат»

Регэкспро қисм ба қисм мехонем

Рақами телефон дар Тоҷикистон: +992 ва нӯҳ рақам. Қолабро аз чап ба рост шарҳ медиҳем:

^ \+992 \d{9} $
/^\+992\d{9}$/ — сатр бо «+992» оғоз мешавад, баъд айнан нӯҳ рақам, ва дигар чизе нест
Таҳрир кардан мумкин аст · Ctrl + Enter
const phone = /^\+992\d{9}$/;

console.log(phone.test("+992927771234"));    // true
console.log(phone.test("+99292777123"));     // false — танҳо 8 рақам
console.log(phone.test("+9929277712345"));   // false — 10 рақам, зиёдатӣ
console.log(phone.test("927771234"));        // false — рамзи кишвар нест

Лангарҳои ^ ва $: хатои аз ҳама маъмул

Бе ^ ва $ регэксп пораи мувофиқро дар дохили сатр меҷӯяд — ва хасу хошокро дар атрофаш мегузаронад:

Хато: лангарҳоро фаромӯш кардем · Ctrl + Enter
const bad  = /\d{4}/;      // «дар ягон ҷои сатр 4 рақами пайи ҳам ҳаст»
const good = /^\d{4}$/;    // «тамоми сатр — айнан 4 рақам»

console.log(bad.test("abc1234xyz"));   // true  ← ✖ хасу хошокро гузарониданд
console.log(good.test("abc1234xyz"));  // false ← ин тавр дуруст аст
console.log(good.test("1234"));        // true

Парчамҳо ва иваз: воридотро тоза мекунем

Баъди слэши пӯшанда парчамҳо мегузоштан мумкин аст: i — ҳарфҳои калон ва хурдро фарқ накардан, g — ҳамаи мувофиқатҳоро ҷустан, на танҳо аввалинро. Бо усули replace ин роҳи қулай барои аз фосила ва дефисҳо тоза кардани телефон аст:

Таҳрир кардан мумкин аст · Ctrl + Enter
const raw = "+992 92 777-12-34";
const clean = raw.replace(/[\s-]/g, "");   // ҳамаи фосила ва дефисҳоро мебарорем
console.log(clean);                        // +992927771234

console.log(/^tj$/i.test("TJ"));           // true — регистр аз сабаби парчами i муҳим нест
console.log("a1b22c333".replace(/\D/g, ""));  // 122333 — танҳо рақамҳоро мондем

Қолабҳои тайёр барои шаклҳо

Чиро месанҷемРегэкспЧӣ тавр хондан
Телефон +992/^\+992\d{9}$/«+992» ва айнан 9 рақам
Логин/^[a-zA-Z][a-zA-Z0-9_]{2,15}$/якум — ҳарфи лотинӣ, баъд 2–15 ҳарф, рақам ё «_»: ҳамагӣ 3–16 аломат
Email (оддӣ)/^[^\s@]+@[^\s@]+\.[^\s@]+$/чизе бе фосила ва «@», баъд «@», баъд боз ҳамон гуна, баъд нуқта ва боз чизе
Рақам ҳаст/\d/дар ягон ҷои сатр рақам вомехӯрад (лангарҳо лозим нестанд!)
Ҳарфи калон ҳаст/[A-Z]/дар ягон ҷо ҳарфи калони лотинӣ ҳаст
Ном бо кириллӣ/^[А-Яа-яЁё\s-]+$/танҳо ҳарфҳои русӣ (Ё ва ё-ро алоҳида илова кардан лозим аст), фосилаҳо ва дефис
Дар бораи регэкспҳо чиро бояд донист
  • Лангарҳо. Агар месанҷед «тамоми сатр чунин аст» — ^ ва $ гузоред. Агар меҷӯед «дар бар мегирад» — нагузоред.
  • Ҳадс назанед, санҷед. Регэксп — ин код аст. Онро бо 5–10 мисол санҷед: мувофиқ ва номувофиқ (дар бахши ЗС мо инро мунтазам иҷро мекунем).
  • Мураккаб накунед. Ибораи комил барои email вуҷуд надорад, ва «комил»-ҳо се сатр мегиранд ва касе онҳоро намефаҳмад. Санҷиши оддии формат кофист. Ва ки суроға воқеан вуҷуд дорад, бо мактуб бо рамз месанҷанд, на бо регэксп.
  • Кириллӣ ва \w. Қолаби \w (ҳарфҳо, рақамҳо, «_») танҳо лотиниро мефаҳмад. Барои ҳарфҳои русӣ ва тоҷикӣ диапазонҳоро ошкоро нависед ва бо номҳои воқеӣ санҷед.

Барои муфассалтар хондан: Шаблоны и флаги · Якоря: начало ^ и конец $ · MDN: регулярные выражения

Амалиёт: мустаҳкам мекунем

Қолабҳои худро менависем. Дар ҳамаи вазифаҳо натиҷа дар маҷмӯи собити сатрҳо санҷида мешавад.

ВАЗИФАИ 5.1

Танҳо рақамҳо

осон

Се зерхатро бо қолаби «тамоми сатр аз ақаллан як рақам иборат аст» иваз кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
const onlyDigits = /___/;

for (const s of ["12345", "12a45", "", "007"]) {
  console.log("[" + s + "] → " + onlyDigits.test(s));
}
Натиҷаи интизоршаванда
[12345] → true
[12a45] → false
[] → false
[007] → true
Ишора 1

Лангарҳои оғоз ва анҷоми сатр ва «рақам, як маротиба ё бештар» лозиманд.

Ишора 2

/^\d+$/

ВАЗИФАИ 5.2

Телефон бо фосилаҳо

миёна

Функсияи isPhone(value)-ро нависед: аввал аз сатр ҳамаи фосила ва дефисҳоро мебарорад, баъд месанҷад, ки рақами намуди +992 ва нӯҳ рақам ҳосил шуд.

Таҳрир кардан мумкин аст · Ctrl + Enter
function isPhone(value) {
  // 1) value-ро тоза кунед   2) қолабро санҷед
}

const tests = ["+992927771234", "+992 92 777-12-34", "927771234", "+99292777123", "+992abc771234", ""];
for (const t of tests) {
  console.log("[" + t + "] → " + isPhone(t));
}
Натиҷаи интизоршаванда
[+992927771234] → true
[+992 92 777-12-34] → true
[927771234] → false
[+99292777123] → false
[+992abc771234] → false
[] → false
Ишора 1

Тозакунӣ: value.replace(/[\s-]/g, "") — парчами g лозим аст, то ҳамаи фосилаҳо бароварда шаванд, на танҳо аввалӣ.

Ишора 2

Қолаб — аз бахши боло: /^\+992\d{9}$/. Функсия натиҷаи .test(...)-ро бармегардонад.

ВАЗИФАИ 5.3

Қоидаҳо барои логин

миёна

isLogin(value)-ро нависед. Логин мувофиқ аст, агар он танҳо аз ҳарфҳои лотинӣ, рақамҳо ва «_» иборат бошад, бо ҳарф оғоз шавад ва дарозиаш аз 3 то 16 аломат бошад.

Таҳрир кардан мумкин аст · Ctrl + Enter
function isLogin(value) {
  // true ё false-ро баргардонед
}

const tests = ["madina_01", "Rustam", "1madina", "ma", "madina-01", "Shahrom_Komilov_2024_x"];
for (const t of tests) {
  console.log(t + " → " + isLogin(t));
}
Натиҷаи интизоршаванда
madina_01 → true
Rustam → true
1madina → false
ma → false
madina-01 → false
Shahrom_Komilov_2024_x → false
Ишора 1

Қолаб аз ду қисм: ҳарфи аввал [a-zA-Z], боқимонда — [a-zA-Z0-9_] бо миқдор. Агар тамоми дарозӣ 3–16 бошад, «боқимонда» чанд бояд бошад?

Ишора 2

return /^[a-zA-Z][a-zA-Z0-9_]{2,15}$/.test(value);

ВАЗИФАИ 5.4

Хаторо ёб: индекс аз шаш рақам

осон

Индекси почта — айнан шаш рақам. Регэксп зиёдатиро мегузаронад. Онро ислоҳ кунед, то ҳар чор сатр ҷавоби дуруст диҳанд.

Таҳрир кардан мумкин аст · Ctrl + Enter
const zip = /\d{6}/;

for (const s of ["734025", "73402", "7340256", "ab734025"]) {
  console.log(s + " → " + zip.test(s));
}
Натиҷаи интизоршаванда
734025 → true
73402 → false
7340256 → false
ab734025 → false
Ишора 1

Ҳоло қолаб шаш рақамро дар ягон ҷои дохили сатр меҷӯяд. Бояд гуфт, ки сатр танҳо аз онҳо иборат аст.

Ишора 2

Лангарҳоро илова кунед: /^\d{6}$/

ВАЗИФАИ 5.5

Қувваи парол

душвор

passwordStrength(p)-ро нависед. Парол барои ҳар шарти иҷрошуда як хол мегирад: дарозӣ аз 8 аломат; ҳарфи хурди лотинӣ ҳаст; ҳарфи калони лотинӣ ҳаст; рақам ҳаст; аломати махсус аз маҷмӯи !@#$%^&* ҳаст. Натиҷа: 0–2 хол — слабый, 3–4 — средний, 5 — сильный.

Таҳрир кардан мумкин аст · Ctrl + Enter
function passwordStrength(p) {
  let points = 0;
  // ба points барои ҳар шарт 1-тоӣ илова кунед

  // "слабый", "средний" ё "сильный"-ро баргардонед
}

for (const p of ["", "abc", "12345678", "madina123", "Madina2024", "Madina2024!"]) {
  console.log("[" + p + "] → " + passwordStrength(p));
}
Натиҷаи интизоршаванда
[] → слабый
[abc] → слабый
[12345678] → слабый
[madina123] → средний
[Madina2024] → средний
[Madina2024!] → сильный
Ишора 1

Панҷ if-и алоҳида: if (p.length >= 8) points++;, if (/[a-z]/.test(p)) points++; ва ғайра. Дар ин ҷо лангарҳо лозим нестанд — мо «дар бар мегирад»-ро меҷӯем.

Ишора 2

Аломатҳои махсус: /[!@#$%^&*]/. Дар охир: if (points <= 2) return "слабый"; if (points <= 4) return "средний"; return "сильный";

06 Санҷиши худӣ: функсияҳои санҷанда ва матнҳои хатоҳо

Акнун мо ҳама чизро дорем, то санҷиши худиро нависем. Дастур оддӣ аст ва барои ҳар шакл кор мекунад:

  1. Як санҷанда барои як майдон. Ин функсияест, ки қиматро мегирад ва матни хато-ро бармегардонад — ё сатри холии "", агар ҳама чиз хуб бошад.
  2. Дар объект ҷамъ мекунем. { fullName: validateName, email: validateEmail, ... } — аз рӯи калид намоён аст, ки кадом санҷанда ба кадом майдон тааллуқ дорад.
  3. Хатоҳоро нишон медиҳем. Матн — дар <span> дар зери майдон, ва худи майдонро бо чаҳорчӯбаи сурх ва атрибути aria-invalid қайд мекунем.
  4. Намефиристем, то даме ки ақаллан як хато ҳаст.

Қадами 1: санҷанда — функсияи «қимат → матни хато» аст

Таҳрир кардан мумкин аст · Ctrl + Enter
function validateEmail(value) {
  const email = value.trim();                       // фосилаҳои канориро мебарорем
  if (email === "") return "Введите email";
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
    return "Похоже, в адресе ошибка. Пример: madina@mail.tj";
  }
  return "";                                        // сатри холӣ = хато нест
}

console.log("[" + validateEmail("") + "]");
console.log("[" + validateEmail("madina@") + "]");
console.log("[" + validateEmail("  madina@mail.tj ") + "]");

Функсия танҳо месанҷад ва дар бораи саҳифа чизе намедонад. Бинобар ин санҷидани он осон аст (мо ҳоло онро бо се мисол даъват кардем) ва истифодаи такрории он осон — дар ҳар саҳифа ва бо ҳар тарҳ. Қоидаи «як функсия ҳисоб мекунад, дигар нишон медиҳад»-ро шумо дар дарси 5 дидаед.

Муқоиса аз ҳаёт

Назоратчӣ дар даромадгоҳи метро. Вай аз пасатон намедавад — дар назди турникет меистад ва ба чипта менигарад. Агар чизе нодуруст бошад, вай сабабро ном мегирад («корт гузоред», «пул намерасад»). Санҷанда — ҳамон назоратчӣ: дар баромад ё «гузаред» (""), ё сабаби фаҳмои радкунӣ.

Кадом матнҳои хато навиштан лозим

Бад

«Ошибка!», «Неверное значение», «Invalid input», «Поле заполнено неверно». Одам намефаҳмад, чӣ нодуруст аст ва чӣ тавр ислоҳ кардан лозим.

Хуб

«Введите номер в формате +992 и 9 цифр», «Пароль — минимум 8 символов», «Пароли не совпадают». Гуфта шудааст, ки чиро интизорем, ва фавран намуна намоён аст.

  • Бо «Шумо» ва оромона сухан гӯед: на «Ту нодуруст ворид кардӣ», балки «Лутфан, email-ро санҷед».
  • Қоида-ро ном гиред, на танҳо далели хаторо: «ақаллан 2 ҳарф» муфидтар аз «хеле кӯтоҳ» аст.
  • Хаторо дар паҳлӯи майдон нишон диҳед, на бо як тирезаи alert дар болои саҳифа.
  • Майдони ҳатмии холӣ ва формати нодуруст — паёмҳои гуногун-анд: «Введите email» ва «Неверный формат email».

Қадами 2: ҳамаи майдонҳоро якбора месанҷем

Вақте санҷандаҳо якчанд бошанд, онҳоро дар объект нигоҳ доштан ва бо давра гузаштан қулай аст. Дар баромад — объекти хатоҳо: дар он калидҳо танҳо барои майдонҳои нодуруст ҳастанд. Объекти холӣ — ҳама чиз хуб.

Таҳрир кардан мумкин аст · Ctrl + Enter
const validators = {
  fullName: (v) => (v.trim().length < 2 ? "Введите имя (минимум 2 буквы)" : ""),
  age: (v) => (Number(v) >= 16 ? "" : "Курс с 16 лет"),
};

function validateAll(data) {
  const errors = {};
  for (const field in validators) {
    const message = validators[field](data[field]);
    if (message) errors[field] = message;
  }
  return errors;
}

console.log(JSON.stringify(validateAll({ fullName: "Мадина", age: "19" })));   // {}
console.log(JSON.stringify(validateAll({ fullName: "М", age: "15" })));

Қадами 3: хаторо дар саҳифа нишон медиҳем

Ҳар майдон «ҷой барои хато» мегирад — <span>-и холӣ дар паҳлӯ. Ҳангоми хато мо матнро ба он менависем, ҳангоми набудани он — пок мекунем. Ҳамеша textContent-ро истифода баред, на innerHTML: воридоти корбарро ҳамчун HTML ба саҳифа гузоштан мумкин нест.

Хатоҳо дар зери майдонҳо · Ctrl + Enter
<form id="f" novalidate>
  <div class="field">
    <label for="fullName">Имя</label>
    <input id="fullName" name="fullName">
    <span class="error" data-error="fullName"></span>
  </div>
  <div class="field">
    <label for="age">Возраст</label>
    <input id="age" name="age" inputmode="numeric">
    <span class="error" data-error="age"></span>
  </div>
  <button>Отправить</button>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.

Иҷро кунед, «Отправить»-ро бо майдонҳои холӣ пахш кунед, баъд ислоҳ кунед ва боз фиристед. Ба се ҷузъ диққат диҳед: хатоҳо фавран дар ҳамаи майдонҳо нишон дода мешаванд, курсор дар аввалин майдони «бад» меистад, ва дар майдони ислоҳшуда хато нест мешавад.

Хатоҳои маъмул
  • Фаромӯш кардани trim() — « » (фосилаҳо) ҳамчун ном ғайрихолӣ ҳисоб мешавад.
  • Сатрро ҳамчун адад муқоиса мекунем — "5" < "16" сатрҳоро аз рӯи аломатҳо муқоиса мекунад. Аввал Number(...).
  • Хатои кӯҳнаро пок намекунем — одам майдонро ислоҳ кард, аммо матни сурх монд. Бинобар ин showError ҳамеша, ҳатто барои майдонҳои дуруст — бо сатри холӣ даъват мешавад.
  • Воридотро тавассути innerHTML нишон медиҳем — барои XSS роҳ мекушояд. Танҳо textContent.
  • Санҷиш танҳо дар браузер — барои сайти воқеӣ боз санҷиши сервер низ лозим аст.

Барои муфассалтар хондан: Фокусировка: focus/blur · MDN: валидация форм с помощью JavaScript

Амалиёт: мустаҳкам мекунем

Санҷандаҳо менависем — аз як майдон то шакли том. Матнҳои хатоҳои чопшаванда ҳарф ба ҳарф муқоиса мешаванд, бинобар ин онҳоро аз шарт нусха кунед.

ВАЗИФАИ 6.1

Санҷандаи ном

осон

validateName(value)-ро нависед. Фосилаҳои канорӣ нодида гирифта мешаванд. Номи холӣ → Введите имя. Аз ду аломат кӯтоҳтар → Имя слишком короткое. Вагарна — сатри холӣ.

Таҳрир кардан мумкин аст · Ctrl + Enter
function validateName(value) {
  // "" ё матни хаторо баргардонед
}

for (const v of ["", "   ", "А", "Мадина", "  Фарход  "]) {
  console.log("[" + validateName(v) + "]");
}
Натиҷаи интизоршаванда
[Введите имя]
[Введите имя]
[Имя слишком короткое]
[]
[]
Ишора 1

Аввал const name = value.trim(); — баъд бо сатри тозашуда кор мекунем.

Ишора 2

Ду санҷиш бо return-и барвақт: if (name === "") return "Введите имя"; ва if (name.length < 2) return .... Дар охир — return "";

ВАЗИФАИ 6.2

Санҷандаи синну сол

миёна

validateAge(value)-ро нависед — қимат ҳамчун сатр аз майдон меояд. Қоидаҳо бо ин тартиб: холӣ (баъди trim) → Введите возраст; адад не → Возраст — это число; камтар аз 16 → Курс с 16 лет; зиёдтар аз 70 → Проверьте возраст; вагарна "".

Таҳрир кардан мумкин аст · Ctrl + Enter
function validateAge(value) {
  // фаромӯш накунед: Number("") ба 0 баробар аст, бинобар ин холиро алоҳида ва аввал месанҷем
}

for (const v of ["", "abc", "15", "24", "99", " 30 "]) {
  console.log("[" + validateAge(v) + "]");
}
Натиҷаи интизоршаванда
[Введите возраст]
[Возраст — это число]
[Курс с 16 лет]
[]
[Проверьте возраст]
[]
Ишора 1

Тартиб: const text = value.trim(); → холӣ → const age = Number(text); → Number.isNaN(age) → ҳудудҳо.

Ишора 2

Number("abc") NaN медиҳад, ва онро танҳо тавассути Number.isNaN(age) санҷидан мумкин аст (муқоисаи age === NaN ҳамеша false аст).

ВАЗИФАИ 6.3

Ҳамаи мушкилоти парол якбора

миёна

validatePassword(password, login)-ро нависед, ки массиви ҳамаи мушкилоти ёфтшударо (бо ин тартиб) бармегардонад: Минимум 8 символов; Добавьте цифру (ягон рақам нест); Без пробелов (аломати фосила ҳаст); Не совпадает с логином (парол бо логин бе ҳисоби регистр баробар аст). Агар мушкилот набошад — массиви холӣ.

Таҳрир кардан мумкин аст · Ctrl + Enter
function validatePassword(password, login) {
  const problems = [];
  // матнҳоро тавассути push ба problems илова кунед
  return problems;
}

const tests = [["abc", "madina"], ["Madina", "madina"], ["pass word 1", "x"], ["qwerty123", "madina"]];
for (const [p, l] of tests) {
  console.log(validatePassword(p, l).join(" | ") || "ок");
}
Натиҷаи интизоршаванда
Минимум 8 символов | Добавьте цифру
Минимум 8 символов | Добавьте цифру | Не совпадает с логином
Без пробелов
ок
Ишора 1

Чор if-и новобаста бе return: ҳар кадом ҳангоми зарурат матни худро ба массив илова мекунад.

Ишора 2

Рақам: !/\d/.test(password). Фосила: /\s/.test(password). Логин: password.toLowerCase() === login.toLowerCase().

ВАЗИФАИ 6.4

Шаклро дар маҷмӯъ месанҷем

миёна

Се санҷанда аллакай навишта шудаанд. validateForm(data)-ро нависед: он барои ҳар майдон аз объекти validators санҷандаи лозимиро даъват мекунад ва объекти хатоҳоро бармегардонад — бо калидҳо танҳо барои майдонҳои нодуруст.

Таҳрир кардан мумкин аст · Ctrl + Enter
function validateName(v) {
  return v.trim().length < 2 ? "Введите имя" : "";
}
function validateEmail(v) {
  if (v.trim() === "") return "Введите email";
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.trim()) ? "" : "Неверный email";
}
function validatePhone(v) {
  return /^\+992\d{9}$/.test(v.replace(/[\s-]/g, "")) ? "" : "Телефон: +992 и 9 цифр";
}

const validators = { fullName: validateName, email: validateEmail, phone: validatePhone };

function validateForm(data) {
  // объекти хатоҳоро баргардонед
}

const forms = [
  { fullName: "Мадина", email: "madina@mail.tj", phone: "+992 92 777 12 34" },
  { fullName: " ", email: "madina@", phone: "+992927771234" },
  { fullName: "Фарход", email: "", phone: "927771234" },
];
for (const data of forms) console.log(JSON.stringify(validateForm(data)));
Натиҷаи интизоршаванда
{}
{"fullName":"Введите имя","email":"Неверный email"}
{"email":"Введите email","phone":"Телефон: +992 и 9 цифр"}
Ишора 1

const errors = {}; созед, бо давраи for (const field in validators) гузаред ва дар охир errors-ро баргардонед.

Ишора 2

Дар дохили давра: const message = validators[field](data[field]); ва if (message) errors[field] = message;

ВАЗИФАИ 6.5

Хатоҳо дар саҳифа

душвор

Дар скрипт ду қисм намерасад. showError(name, message)-ро нависед: он матнро ба span[data-error="ном"] менависад, синфи invalid-ро дар майдон мегузорад ё мебардорад ва aria-invalid-ро ба "true" ё "false" мегузорад. Баъд коркардкунандаи submit-ро нависед: бекор кардани ирсол, санҷиши ҳамаи майдонҳо тавассути validators, нишон додани хатоҳо ва ҳангоми муваффақият console.log("Отправлено"). Блоки «проверка»-ро дар поён тағйир надиҳед.

showError ва submit-ро ба итмом расонед · Ctrl + Enter
<form id="f" novalidate>
  <div class="field">
    <label for="fullName">Имя</label>
    <input id="fullName" name="fullName">
    <span class="error" data-error="fullName"></span>
  </div>
  <div class="field">
    <label for="email">Email</label>
    <input id="email" name="email">
    <span class="error" data-error="email"></span>
  </div>
  <button>Отправить</button>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда
fullName: Введите имя (минимум 2 буквы) | aria-invalid=true | invalid=true
email: ok | aria-invalid=false | invalid=false
fullName: ok | aria-invalid=false | invalid=false
email: Введите email, например madina@mail.tj | aria-invalid=true | invalid=true
Отправлено
fullName: ok | aria-invalid=false | invalid=false
email: ok | aria-invalid=false | invalid=false
Ишора 1

showError: майдони form.elements[name] ва тавзеҳи form.querySelector(`[data-error="${name}"]`)-ро ёбед; textContent-ро нависед; classList.toggle("invalid", message !== ""); setAttribute("aria-invalid", message ? "true" : "false").

Ишора 2

Дар коркардкунанда: event.preventDefault(), let ok = true;, давраи for (const name in validators) — дар дохил паёмро ҳисоб мекунем, showError-ро даъват мекунем (ҳатто агар паём холӣ бошад!) ва ҳангоми хато ok = false мегузорем. Баъди давра: if (ok) console.log("Отправлено");

07 Санҷиши зинда: ҳангоми чоп кардани одам месанҷем

Санҷиш танҳо ҳангоми пахши «Отправить» кор мекунад, аммо нокулай аст: одам даҳ майдонро пур кард ва дар бораи хато дар аввалин майдон мефаҳмад. Санҷиши зинда фавран ишора мекунад. Барои он се ҳодиса лозим аст:

input
Дар ҳар тағйири қимат кор мекунад: клавиша заданд, матн гузоштанд, аломатро пок карданд.
change
Вақте кор мекунад, ки қимат тағйир ёфт ва майдон фокусро аз даст дод (барои чекбокс ва рӯйхат — фавран ҳангоми интихоб).
blur
Майдон фокусро аз даст дод — одам ба майдони дигар рафт. Боло намеравад (баръакси focusout).
Муқоиса аз ҳаёт

Пешхизмати хуб дар чойхона шуморо дар нисфи сухан намебурад: «Не, палав аллакай нест!» Вай интизор мешавад, то шумо гуфтанро тамом кунед, ва танҳо баъд ислоҳ мекунад. Шакл низ ҳамин тавр: то даме ки одам воридкунии майдонро тамом накардааст, ба майдон хафа нашавед, вагарна аввалин ҳарфи email «Неверный email»-и сурхро ба вуҷуд меорад.

Қоидаи «ламс шуд / ламс нашуд» (touched)

  1. То даме ки одам майдонро тарк накардааст — хаторо нишон намедиҳем, ҳатто агар қимат ҳоло нодуруст бошад.
  2. Вақте blur кор кард — майдон «ламсшуда» ҳисоб мешавад: месанҷем ва хаторо нишон медиҳем.
  3. Аз ҳамин лаҳза дар ҳар input аз нав месанҷем: ҳамин ки одам ислоҳ кард, хато фавран нест мешавад.
  4. Ҳангоми пахши «Отправить» ҳамаи майдонҳоро якбора «ламс мекунем» ва ҳамаи хатоҳоро нишон медиҳем.
Санҷиши зинда-и email ва парол · Ctrl + Enter
<form id="f" novalidate>
  <div class="field">
    <label for="email">Email</label>
    <input id="email" name="email" type="email" autocomplete="off">
    <span class="error" id="email-error"></span>
  </div>
  <div class="field">
    <label for="pass">Пароль</label>
    <div class="row">
      <input id="pass" name="pass" type="password" maxlength="20">
      <button type="button" id="eye">Показать</button>
    </div>
    <span class="hint" id="pass-hint">Введено: 0 из 20</span>
  </div>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.

Кӯшиш кунед: дар email «ali» чоп кунед — чизе намешавад. Tab-ро пахш кунед — хато пайдо шуд. «@mail.tj»-ро нависед — хато ҳангоми чоп кардан нест шуд.

Муқоисаи ду майдон: парол ва такрор

Қоидаи «паролҳо мувофиқанд» аз ду майдон вобаста аст, бинобар ин ҳангоми тағйири ҳар кадом онҳо санҷидан лозим аст. Хатои маъмул — танҳо ба майдони дуюм обуна шудан: одам пароли аввалро ислоҳ кард, аммо хатои сурх дар дуюм монд.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `<input id="pass"><input id="again"><span id="msg"></span>`;
const pass = document.querySelector("#pass");
const again = document.querySelector("#again");
const msg = document.querySelector("#msg");

function checkMatch() {
  msg.textContent = pass.value === again.value ? "" : "Пароли не совпадают";
}
pass.addEventListener("input", checkMatch);    // ҳар ду майдон ба натиҷа таъсир мерасонанд
again.addEventListener("input", checkMatch);

pass.value = "qwerty1";   pass.dispatchEvent(new Event("input"));
again.value = "qwerty1";  again.dispatchEvent(new Event("input"));
console.log("[" + msg.textContent + "]");       // [] — мувофиқ шуданд
pass.value = "qwerty2";   pass.dispatchEvent(new Event("input"));
console.log("[" + msg.textContent + "]");       // [Пароли не совпадают] — аввалиро ислоҳ карданд
Хатоҳои маъмул
  • Хеле барвақт хафа мешавем. Хатои сурх баъди ҳарфи аввал нороҳат мекунад. «touched»-ро истифода баред.
  • Танҳо дар change месанҷем. Он гоҳ одам хаторо танҳо баъди аз майдон баромадан мебинад — ин аллакай санҷиши «зинда» нест. Ҳодисаи асосӣ — input.
  • Санҷиш ҳангоми ирсолро фаромӯш кардем. Одам метавонад «Отправить»-ро пахш кунад, умуман ба майдон надаромада: санҷиши зинда санҷиши submit-ро пурра мекунад, на иваз.
  • Тугмаро бе шарҳ қуфл мекунем. Тугмаи қуфлшудаи «Отправить» бе ишора, ки чӣ намерасад, — интерфейси бад. Беҳтар аст хатоҳоро нишон диҳед ва тугмаро фаъол монед.

Барои муфассалтар хондан: События change, input · Фокусировка: focus/blur

Амалиёт: мустаҳкам мекунем

Дар вазифаҳо скрипт худаш дар майдонҳо «чоп мекунад» ва ҳодисаҳоро (dispatchEvent) даъват мекунад — шумо бояд вокуниш нависед.

ВАЗИФАИ 7.1

Нишон додани парол

осон

Ҳангоми клик ба тугма навъи майдон байни password ва text иваз мешавад, ва матни тугма — байни «Показать» ва «Скрыть».

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `
  <input id="pass" type="password" value="secret">
  <button id="eye" type="button">Показать</button>`;

const pass = document.querySelector("#pass");
const eye = document.querySelector("#eye");

// коркардкунандаи click-ро барои тугмаи eye илова кунед


eye.click();
console.log(pass.type, eye.textContent);
eye.click();
console.log(pass.type, eye.textContent);
Натиҷаи интизоршаванда
text Скрыть
password Показать
Ишора 1

Дар дохили коркардкунанда аввал бифаҳмед, ки оё парол пинҳон аст: const hidden = pass.type === "password";

Ишора 2

Оператори сегона: pass.type = hidden ? "text" : "password"; ва ба ҳамин монанд барои eye.textContent.

ВАЗИФАИ 7.2

Ҳисобкунаки аломатҳо

миёна

Дар зери майдони «О себе» навиштаи «Осталось: N» ҳаст, ки N — чанд аломат боз ворид кардан мумкин аст (маҳдудият 40). Он бояд фавран ҳангоми бор шудан дуруст бошад ва барои ҳар ҳодисаи input нав шавад.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `<textarea id="bio"></textarea><p id="left"></p>`;
const bio = document.querySelector("#bio");
const left = document.querySelector("#left");
const LIMIT = 40;

// 1) функсияи update() ба left матни «Осталось: N»-ро менависад
// 2) онро фавран ва ба ҳодисаи input даъват кунед


console.log(left.textContent);
bio.value = "Привет!";
bio.dispatchEvent(new Event("input"));
console.log(left.textContent);
bio.value = "а".repeat(40);
bio.dispatchEvent(new Event("input"));
console.log(left.textContent);
Натиҷаи интизоршаванда
Осталось: 40
Осталось: 33
Осталось: 0
Ишора 1

Дарозии матн — bio.value.length. Монда: LIMIT - bio.value.length.

Ишора 2

function update() { left.textContent = `Осталось: ${LIMIT - bio.value.length}`; }-ро эълон кунед, update();-ро даъват кунед ва bio.addEventListener("input", update);-ро илова кунед

ВАЗИФАИ 7.3

Танҳо баъди баромадан аз майдон хафа мешавем

миёна

Қоидаи «touched»-ро барои майдони email амалӣ кунед. Дар blur майдон ламсшуда ҳисоб мешавад ва санҷида мешавад. Дар input санҷиш танҳо дар сурате меравад, ки майдон аллакай ламс шуда бошад. Хато — Неверный email, ва ҳангоми суроғаи дуруст матни хато холӣ аст.

Таҳрир кардан мумкин аст · Ctrl + Enter
document.body.innerHTML = `<input id="email"><span id="error"></span>`;
const email = document.querySelector("#email");
const error = document.querySelector("#error");

// коди шумо: тағйирёбандаи touched, функсияи validate, коркардкунандаҳои blur ва input


function show() {
  console.log(error.textContent || "нет ошибки");
}

email.value = "ali";
email.dispatchEvent(new Event("input"));
show();
email.dispatchEvent(new Event("blur"));
show();
email.value = "ali@mail.tj";
email.dispatchEvent(new Event("input"));
show();
Натиҷаи интизоршаванда
нет ошибки
Неверный email
нет ошибки
Ишора 1

Тағйирёбандаи let touched = false; лозим аст. Дар коркардкунандаи blur touched = true мегузорем ва validate()-ро даъват мекунем.

Ишора 2

validate() ба error.textContent ё "Неверный email" (агар қимат ба /^[^\s@]+@[^\s@]+\.[^\s@]+$/ мувофиқ набошад), ё сатри холиро менависад. Коркардкунандаи input: if (touched) validate();

ВАЗИФАИ 7.4

Тугма аз ду майдон вобаста аст

душвор

Тугмаи «Создать аккаунт» бояд танҳо дар сурате фаъол бошад, ки парол аз 8 аломат кӯтоҳтар набошад ва такрори парол ба он баробар бошад. updateButton()-ро нависед, онро ҳангоми бор шудан ва ҳангоми воридкунӣ дар ҳар кадоме аз ду майдон даъват кунед.

Парол ва такрор · Ctrl + Enter
<form id="f">
  <input id="password" type="password" placeholder="Пароль">
  <input id="confirm" type="password" placeholder="Повторите пароль">
  <button id="submit">Создать аккаунт</button>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда
старт: кнопка заблокирована
пароль="1234", повтор="" → кнопка заблокирована
пароль="12345678", повтор="" → кнопка заблокирована
пароль="12345678", повтор="1234567" → кнопка заблокирована
пароль="12345678", повтор="12345678" → кнопка активна
пароль="87654321", повтор="12345678" → кнопка заблокирована
Ишора 1

Шарти омодагӣ: password.value.length >= 8 && password.value === confirm.value. Тугма вақте қуфл аст, ки он нодуруст бошад: submit.disabled = !ready;

Ишора 2

Бо ҳар ду сатр обуна шавед: password.addEventListener("input", updateButton); ва ҳамин гуна барои confirm. Фаромӯш накунед, ки updateButton();-ро як маротиба фавран даъват кунед.

08 Блоки ЗС: қоидаҳои санҷиш ва регэкспҳо

Ишораи ЗС

Ибораҳои муқаррарӣ — яке аз беҳтарин вазифаҳо барои ЗС: навиштани онҳо бо даст вақтро мегирад, ва бо калимаҳо шарҳ додани «чӣ мехоҳам» осон аст. Аммо маҳз дар ин ҷо ЗС бештар бо эътимод хато мекунад. Бинобар ин нақша ҳамеша як аст: ЗС пешниҳод мекунад — шумо бо мисолҳои худ месанҷед.

Қоидаҳои курсро ёдрас мекунем: аввал 15 дақиқа худатон кӯшиш кунед, ва ҳеҷ гоҳ коде, ки сатр ба сатр шарҳ дода наметавонед, ворид накунед. Имрӯз шумо аллакай регэкспҳоро хонда метавонед, бинобар ин ҷавоби ЗС-ро қисм ба қисм таҳлил кардан мумкин аст.

1. Қоидаҳои санҷишро талаб мекунем

Формулаи промптро истифода мебарем: контекст → вазифа → маҳдудиятҳо → формати ҷавоб → санҷиш.

санҷиши шакли сабти номро соз
Контекст: ман бо JavaScript-и холис бе китобхонаҳо менависам, сатҳ — навомӯз. Шакли сабти номро барои курсҳо дар Душанбе месозам. Вазифа: барои майдонҳо қоидаҳои санҷиш тартиб деҳ: ном, телефон (Тоҷикистон, +992), email, парол, такрори парол. Барои ҳар кадом — шарт, паёми хато бо забони тоҷикӣ ва ибораи муқаррарӣ, агар лозим бошад. Маҳдудиятҳо: регэкспҳои оддӣ, ки навомӯз хонда тавонад; бе китобхонаҳои беруна; паёмҳо — мулоим, бо намунаи воридкунии дуруст. Формати ҷавоб: ҷадвали «майдон | қоида | паёми хато | регэксп». Санҷиш: барои ҳар регэксп 3 сатрро, ки мувофиқанд, ва 3-тоеро, ки мувофиқ нестанд, биёр ва регэкспро қисм ба қисм шарҳ деҳ.

2. Регэкспи ЗС-ро бо ҳолатҳои худамон месанҷем

Ҳатто ба ҷавоби аз ҳама боэътимод бовар накунед. Одат кунед — ҷадвали санҷишҳо:

  1. 3–5 сатри мувофиқ, аз ҷумла «ифлос» (бо фосилаҳо дар канор, бо регистри гуногун).
  2. Сатри холӣ — бояд рад карда шавад (агар майдон ҳатмӣ бошад).
  3. Ҳудуди дарозӣ: як кам аз ҳадди ақал, айнан ҳадди ақал, айнан ҳадди аксар, як зиёд аз ҳадди аксар.
  4. «Хасу хошок» дар атроф: abc1234xyz дар ҷое, ки танҳо рақамҳо лозиманд. Ҳамин тавр шумо набудани ^ ва $-ро мегиред.
  5. Маълумоти воқеии шумо: телефонҳо аз китобчаи ёддошти шумо, номҳои дӯстон бо кириллӣ, email-и воқеии шумо.
Миниистенд барои санҷиши регэксп · Ctrl + Enter
const re = /^\+992\d{9}$/;   // регэкспи ЗС

const cases = [
  ["+992927771234", true],      // мувофиқ аст
  [" +992927771234", false],    // фосила дар оғоз — шумо қарор медиҳед, ки иҷозат аст ё не
  ["+99292777123", false],      // як рақам кам
  ["+9929277712345", false],    // як рақам зиёд
  ["abc+992927771234xyz", false],  // хасу хошок дар атроф
  ["", false],                  // холӣ
];

for (const [value, expected] of cases) {
  console.log((re.test(value) === expected ? "ok  " : "FAIL") + " [" + value + "]");
}

3. ЗС чӣ чизро бештар нодуруст мекунад

Дар ҷавоби ЗС чиро мебинедМушкилот дар чистЧӣ тавр ислоҳ кардан
Регэксп бе ^ ва $Хасу хошокро дар атроф мегузаронад: abc1234xyz ҳамчун «рақамҳо» мегузарадЛангарҳоро илова кардан, агар тамоми сатр санҷида шавад
Email аз 200 аломат бо тӯдаи қавсҳоКасе онро хонда ва нигоҳубин карда наметавонад, ҳамзамон мавҷудияти воқеии суроғаро ҳам намесанҷадОддӣ /^[^\s@]+@[^\s@]+\.[^\s@]+$/
\w ё [a-z] барои номҳоҲарфҳои кириллӣ ва тоҷикӣ рад мешавандДиапазонҳои ошкоро [А-Яа-яЁё] ва санҷиш бо номҳои воқеӣ
Телефон ^\d{10}$Қолаб барои кишвари дигарДар промпт ба ЗС гуфтан: Тоҷикистон, +992, 9 рақам
<input type="number"> барои телефонСифрҳои пешоянд ва «+»-ро гум мекунад, майдон тирчаҳо дорадtype="tel" + санҷиш бо сатр
Регэксп бо парчами g ва усули .test()Объект мавқеъро «дар хотир дорад»: ҷавобҳо ба навбат true / false мешавандПарчами g-ро барои санҷишҳо бардоштан
errorBox.innerHTML = userInputХатарнок: корбар метавонад HTML гузорадerrorBox.textContent = ...
«Санҷиш дар клиент — ин ҳимоя аст»Санҷиши браузерро ба осонӣ гузаштан мумкин астЁд дошта бошед: боз сервер низ месанҷад
Тузоқи парчами g · Ctrl + Enter
const re = /\d/g;                  // парчами g — «дар хотир дор, дар куҷо истодӣ»
console.log(re.test("1"));         // true
console.log(re.test("1"));         // false ← ✖ ҳамон сатр, ҷавоби дигар
console.log(re.test("1"));         // true

4. Боз се промпти муфид

Ибораи муқаррарии /^[a-zA-Z][a-zA-Z0-9_]{2,15}$/-ро қисм ба қисм, мисли барои навомӯз шарҳ деҳ. Барои ҳар қисм — маънои он чист. Баъд 3 сатри мувофиқ ва 3 сатри номувофиқро бо шарҳи сабаб биёр.
Инак функсияи validatePhone-и ман: [код]. 10 сатри санҷиширо фикр кун, ки дар онҳо он метавонад вайрон шавад: фосилаҳо, дефисҳо, ҳарфҳо, сатри холӣ, рақами хеле дароз. Ҷавоб — массиви ҷуфтҳои [сатр, натиҷаи интизоршаванда] дар намуди коди JS.
Паёмҳои хатои шакли маро чунон аз нав нависӣ, ки мулоим, кӯтоҳ бошанд ва қоида ва намунаро ном баранд. Маънояшро тағйир нахӯр. Буд: «Неверно», «Ошибка в пароле», «Плохой телефон».
Қоидаи асосӣ

Регэкспи ЗС-ро қисм ба қисм бихонед, чунон ки мо дар бахши 5 кардем. Агар ягон қисмро шарҳ дода наметавонед — аз ЗС шарҳ пурсед ва онро бо санҷишҳо тасдиқ кунед, ё ибораро соддатар кунед. Кодеро, ки намефаҳмед, ҳангоми вайрон шудан дар маълумоти воқеӣ ислоҳ карда наметавонед.

Амалиёт бо ЗС

Асосӣ дар ин вазифаҳо — гирифтани код не, балки санҷидани он. Вазифаи аввалро дар чат бо ЗС иҷро кунед, боқиро — дар ин ҷо.

ВАЗИФАИ 8.1

Промпт барои қоидаҳои санҷиш

осон

Мувофиқи формула барои шакли «Номнависӣ ба бахши футбол» промпт тартиб диҳед: майдонҳо ном, синну сол (аз 7 то 17), телефон +992, email-и падару модар, розигӣ. Ҷадвали қоидаҳо, паёмҳои хато ва регэкспҳоро бо 3+3 сатри санҷишӣ талаб кунед. Ба ЗС фиристед, ва регэкспҳои гирифтаро аз миниистенди ин бахш гузаронед. Сабт кунед: кадом регэксп санҷишҳои шуморо нагузашт ва чиро ислоҳ кардед. Ин вазифа санҷиши худкор надорад — вақте тамом кардед, онро дастӣ қайд кунед.

Ишора 1

Панҷ блоки промпт: контекст (JS, навомӯз, Душанбе), вазифа, маҳдудиятҳо (регэкспҳои оддӣ, паёмҳои мулоим), формат (ҷадвал), санҷиш (сатрҳои санҷишӣ).

Ишора 2

Барои синну сол регэксп лозим нест — ин муқоисаи оддии ададҳост. ЗС-и хуб ҳамин тавр ҷавоб медиҳад; агар барои диапазони 7–17 регэксп пешниҳод кунад, ин сабаби шубҳа аст.

ВАЗИФАИ 8.2

Санҷиши регэкспи ЗС: телефон

миёна

ЗС регэксп барои телефони Тоҷикистонро пешниҳод кард. Истендро иҷро кунед ва ёбед, ки дар кадом мисолҳо хато мекунад, баъд онро ислоҳ кунед, то ҳамаи сатрҳо ok гиранд ва натиҷа Не прошли: 0 бошад. Рӯйхати санҷишҳоро тағйир надиҳед.

Таҳрир кардан мумкин аст · Ctrl + Enter
const phoneRe = /^\+992\d{9}/;   // регэкспи ЗС

const cases = [
  ["+992927771234", true],
  ["+992927771234567", false],
  ["+99292777123", false],
  ["992927771234", false],
  ["+992 927771234", false],
  ["+992abcdefghi", false],
  ["", false],
];

let failed = 0;
for (const [value, expected] of cases) {
  const ok = phoneRe.test(value) === expected;
  if (!ok) failed++;
  console.log((ok ? "ok" : "FAIL") + ": [" + value + "]");
}
console.log("Не прошли: " + failed);
Натиҷаи интизоршаванда
ok: [+992927771234]
ok: [+992927771234567]
ok: [+99292777123]
ok: [992927771234]
ok: [+992 927771234]
ok: [+992abcdefghi]
ok: []
Не прошли: 0
Ишора 1

Кадом сатр «рақамҳои зиёдатӣ дар охир» гузашта метавонад? Қолаб оғози сатрро месанҷад, аммо дар бораи охир чизе намегӯяд.

Ишора 2

Лангари охири сатрро илова кунед: /^\+992\d{9}$/

ВАЗИФАИ 8.3

Email аз ЗС: ислоҳ мекунем ва ба санҷишҳо бовар мекунем

душвор

Функсияи isEmail-ро ЗС навишт. Он зиёдатиро мегузаронад ва фосилаҳои канориро коркард намекунад. Онро чунон ислоҳ кунед, ки ҳамаи ҳашт санҷиш гузарад: суроға бо фосилаҳои канорӣ дуруст ҳисоб мешавад (фосилаҳоро бояд бурид), ва суроғаҳои бе домен бо нуқта, бе ном, бо фосила дар дохил ё бо ду «@» — нодуруст. Рӯйхати cases-ро тағйир надиҳед.

Таҳрир кардан мумкин аст · Ctrl + Enter
const isEmail = (s) => /^.+@.+$/.test(s);   // версияи ЗС

const cases = [
  ["madina@mail.tj", true],
  ["  madina@mail.tj  ", true],
  ["m.karimova+tj@gmail.com", true],
  ["madina@", false],
  ["madina@mail", false],
  ["@mail.tj", false],
  ["ma dina@mail.tj", false],
  ["madina@@mail.tj", false],
];

let failed = 0;
for (const [value, expected] of cases) {
  const ok = isEmail(value) === expected;
  if (!ok) failed++;
  console.log((ok ? "ok" : "FAIL") + ": [" + value + "]");
}
console.log("Не прошли: " + failed);
Натиҷаи интизоршаванда
ok: [madina@mail.tj]
ok: [  madina@mail.tj  ]
ok: [m.karimova+tj@gmail.com]
ok: [madina@]
ok: [madina@mail]
ok: [@mail.tj]
ok: [ma dina@mail.tj]
ok: [madina@@mail.tj]
Не прошли: 0
Ишора 1

Нуқта . дар регэксп — «ҳар аломат», аз ҷумла фосила ва «@». Барои қисмҳои суроға «ҳар аломат, ғайр аз фосила ва @» лозим аст: [^\s@]+.

Ишора 2

(s) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s.trim()) — фосилаҳоро пеш аз санҷиш мебуранд ва нуқтаро дар домен талаб мекунем.

09 Амалиёт дар дарс: шакли сабти ном бо санҷиши зинда

Ҳамаро дар як шакл ҷамъ мекунем — чунон, ки шумо дар ҳар сайт мебинед. Мо номнависӣ ба курсро месозем: ном, email, парол ва такрори парол.

Қоидаҳои шакли мо
  • Ном — ҳадди ақал 2 аломат бе фосилаҳо дар канор. Хато: «Имя — минимум 2 буквы».
  • Email — формати оддӣ чизе@чизе.чизе. Хато: «Введите email в формате name@mail.tj».
  • Парол — ҳадди ақал 8 аломат, баъд ҳадди ақал як рақам. Хатоҳо: «Пароль — минимум 8 символов» ва «Добавьте хотя бы одну цифру».
  • Такрори парол — бо парол мувофиқ аст. Хато: «Пароли не совпадают».
  • Хатоҳо баъди баромадан аз майдон пайдо мешаванд (blur), баъд барои ҳар воридкунӣ нав мешаванд (input).
  • Ҳангоми ирсол ҳамаи майдонҳо якбора санҷида мешаванд, курсор ба аввалин хатодор меравад, ва ҳангоми муваффақият «Регистрация: имя, email» чоп мешавад (паролро дар логҳо намегузорем — ҳеҷ гоҳ!).

Нақшаи кор

  1. Аломатгузорӣ. Шакл бо novalidate, дар ҳар майдон — label, name ва span.error-и холӣ дар зери он (data-error="номи майдон").
  2. Санҷандаҳо. Функсияҳои «қимат → матни хато», ки дар объекти validators ҷамъ шудаанд (бахши 6).
  3. Нишон додани хатоҳо. showError — матн, чаҳорчӯбаи сурх, aria-invalid.
  4. Санҷиши зинда. Луғати touched, коркардкунандаҳои blur ва input (бахши 7).
  5. Ирсол. Коркардкунандаи submit: ҳамаи майдонҳоро «ламс мекунем», месанҷем, фокус ба аввалин хатодор ё муваффақият (бахши 2).

Аломатгузорӣ, услубҳо ва «скелет»-и умумӣ (қадамҳои 1, 3)-ро мо тайёр медиҳем. Кори шумо — ду марҳила.

Амалиёт: шаклро ҷамъ мекунем

ВАЗИФАИ 9.1

Марҳилаи 1: санҷандаҳо ва санҷиши зинда

миёна

Скелети санҷиши зинда аллакай кор мекунад: showError, validateField ва коркардкунандаҳои blur / input навишта шудаанд. Се санҷандаро аз рӯи қоидаҳои боло ба итмом расонед. Паёмҳоро айнан нусха кунед.

Сабти ном: марҳилаи 1 · Ctrl + Enter
<form id="reg" novalidate>
  <div class="field">
    <label for="fullName">Имя</label>
    <input id="fullName" name="fullName" autocomplete="off">
    <span class="error" data-error="fullName"></span>
  </div>
  <div class="field">
    <label for="email">Email</label>
    <input id="email" name="email" type="email" autocomplete="off">
    <span class="error" data-error="email"></span>
  </div>
  <div class="field">
    <label for="password">Пароль</label>
    <input id="password" name="password" type="password">
    <span class="error" data-error="password"></span>
  </div>
  <div class="field">
    <label for="confirm">Повторите пароль</label>
    <input id="confirm" name="confirm" type="password">
    <span class="error" data-error="confirm"></span>
  </div>
  <button>Создать аккаунт</button>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда
имя до blur: ok
имя после blur: Имя — минимум 2 буквы
имя после правки: ok
email: Введите email в формате name@mail.tj
email после правки: ok
пароль 1: Добавьте хотя бы одну цифру
пароль 2: Пароль — минимум 8 символов
пароль 3: ok
Ишора 1

Ном: return value.trim().length < 2 ? "Имя — минимум 2 буквы" : ""; Email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim()) ? "" : "Введите email в формате name@mail.tj".

Ишора 2

Парол — ду санҷиш бо return-и барвақт: if (value.length < 8) return "Пароль — минимум 8 символов";, баъд if (!/\d/.test(value)) return "Добавьте хотя бы одну цифру";, дар охир return "";

ВАЗИФАИ 9.2

Марҳилаи 2: такрори парол ва ирсол

душвор

Се санҷандаи марҳилаи 1 аллакай тайёранд. Илова кунед: (1) санҷандаи confirm — «Пароли не совпадают»; (2) аз нав санҷидани confirm ҳангоми тағйири парол, агар confirm аллакай «ламсшуда» бошад; (3) коркардкунандаи submit: бекор кардани ирсол, ҳамаи майдонҳоро «ламс мекунем» ва месанҷем, ҳангоми хато фокусро ба аввалин майдони хатодор мегузорем, вагарна Регистрация: имя, email (бе парол) чоп мекунем.

Сабти ном: марҳилаи 2 · Ctrl + Enter
<form id="reg" novalidate>
  <div class="field">
    <label for="fullName">Имя</label>
    <input id="fullName" name="fullName" autocomplete="off">
    <span class="error" data-error="fullName"></span>
  </div>
  <div class="field">
    <label for="email">Email</label>
    <input id="email" name="email" type="email" autocomplete="off">
    <span class="error" data-error="email"></span>
  </div>
  <div class="field">
    <label for="password">Пароль</label>
    <input id="password" name="password" type="password">
    <span class="error" data-error="password"></span>
  </div>
  <div class="field">
    <label for="confirm">Повторите пароль</label>
    <input id="confirm" name="confirm" type="password">
    <span class="error" data-error="confirm"></span>
  </div>
  <button>Создать аккаунт</button>
</form>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда
повтор: Пароли не совпадают
повтор после правки: ok
после смены пароля: Пароли не совпадают
Регистрация: Мадина, madina@mail.tj
Ишора 1

(1) confirm(value) { return value === form.elements.password.value ? "" : "Пароли не совпадают"; }, (2) form.elements.password.addEventListener("input", () => { if (touched.confirm) validateField("confirm"); });

Ишора 2

Submit: event.preventDefault(); баъд let firstBad = null; ва давра аз рӯи Object.keys(validators): touched[name] = true; if (!validateField(name) && !firstBad) firstBad = form.elements[name];. Агар firstBad бошад — firstBad.focus(); return;. Вагарна — const data = Object.fromEntries(new FormData(form)); ва чопи ном ва email.

Ҳалли намунавӣ (танҳо баъди кӯшиши худ кушоед)
JavaScript
const form = document.querySelector("#reg");
const touched = {};

const validators = {
  fullName(value) {
    return value.trim().length < 2 ? "Имя — минимум 2 буквы" : "";
  },
  email(value) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim()) ? "" : "Введите email в формате name@mail.tj";
  },
  password(value) {
    if (value.length < 8) return "Пароль — минимум 8 символов";
    if (!/\d/.test(value)) return "Добавьте хотя бы одну цифру";
    return "";
  },
  confirm(value) {
    return value === form.elements.password.value ? "" : "Пароли не совпадают";
  },
};

function showError(name, message) {
  const input = form.elements[name];
  form.querySelector(`[data-error="${name}"]`).textContent = message;
  input.classList.toggle("invalid", message !== "");
  input.setAttribute("aria-invalid", message ? "true" : "false");
}

function validateField(name) {
  const message = validators[name](form.elements[name].value);
  showError(name, message);
  return message === "";
}

for (const name of Object.keys(validators)) {
  const input = form.elements[name];
  input.addEventListener("blur", () => {
    touched[name] = true;
    validateField(name);
  });
  input.addEventListener("input", () => {
    if (touched[name]) validateField(name);
  });
}

form.elements.password.addEventListener("input", () => {
  if (touched.confirm) validateField("confirm");
});

form.addEventListener("submit", (event) => {
  event.preventDefault();
  let firstBad = null;
  for (const name of Object.keys(validators)) {
    touched[name] = true;
    if (!validateField(name) && !firstBad) firstBad = form.elements[name];
  }
  if (firstBad) {
    firstBad.focus();
    return;
  }
  const data = Object.fromEntries(new FormData(form));
  console.log(`Регистрация: ${data.fullName}, ${data.email}`);
});

// Қуттии санҷиш ирсоли воқеии шаклро манъ мекунад, бинобар ин клики тугмаро дастӣ ба submit табдил медиҳем
// (дар саҳифаи оддӣ ин иловагӣ лозим нест)
form.querySelector("button").addEventListener("click", (event) => {
  event.preventDefault();
  form.dispatchEvent(new Event("submit", { cancelable: true }));
});
Санҷиши ЗС-и шакли шумо

Вақте коди шумо кор мекунад, аз ЗС хоҳиш кунед, ки барои он санҷишҳо фикр кунад: «Инак шакли сабти номи ман ва санҷандаҳо: [код]. Барои ҳар майдон 10 қиматеро фикр кун, ки дар онҳо санҷиш метавонад хато кунад (фосилаҳо, холӣ, хеле дароз, аломатҳои махсус). Барои ҳар кадом — натиҷаи интизоршаванда». Ин қиматҳоро аз санҷандаҳои худ гузаронед ва ихтилофҳоро ёбед.

★ Вазифаи хонагӣ: шакл аз 6 майдон

Шакли сабти номро ба курси «Frontend + AI» бо шаш майдон, санҷиши пурра ва матнҳои фаҳмои хатоҳо созед. Аз кори синфӣ оғоз кунед: он аллакай скелет дорад, шумо бояд онро васеъ кунед ва ба натиҷаи озода расонед.

Майдонҳои шакл

#МайдонҚоидаНамунаи матни хато
1Ном ва насабҲадди ақал 2 калима, ҳар кадом аз 2 ҳарф, танҳо ҳарфҳо, фосилаҳо ва дефис«Ном ва насабро ворид кунед, масалан: Мадина Каримова»
2ТелефонФормати +992 ва 9 рақам; фосилаҳо ва дефисҳо ҳангоми воридкунӣ иҷозат дода мешаванд«Рақам дар формати +992 92 777 12 34»
3EmailФормати оддӣ бо «@» ва нуқта дар домен«Email-ро ворид кунед, масалан madina@mail.tj»
4ПаролАз 8 аломат, рақам ҳаст, ҳарфи калон ҳаст, фосила нестҲамаи қоидаҳои вайроншударо бо рӯйхат ё тавассути « · » нишон диҳед
5Такрори паролБо парол мувофиқ аст (ҳангоми тағйири парол аз нав санҷида мешавад)«Паролҳо мувофиқат намекунанд»
6Розигӣ бо қоидаҳои курсЧекбокс бояд қайд карда шуда бошад«Бе розигӣ номнависӣ мумкин нест»

Чӣ бояд кор кунад

  • ☐ Аломатгузорӣ: form novalidate, дар ҳар майдон label, name ва type-и дуруст (tel, email, password, checkbox) ҳаст.
  • ☐ Ҳар санҷанда — функсияи алоҳидаи «қимат → матни хато ё сатри холӣ».
  • ☐ Санҷиши зинда аз рӯи нақшаи «touched»: хато баъди баромадан аз майдон пайдо мешавад ва ҳангоми ислоҳ фавран нест мешавад.
  • ☐ Ҳангоми ирсол ҳамаи майдонҳо санҷида мешаванд, фокус ба аввалин хатодор гузошта мешавад.
  • ☐ Хатоҳо дар зери майдонҳо нишон дода мешаванд (textContent), майдон чаҳорчӯбаи сурх ва aria-invalid дорад.
  • ☐ Ҳангоми муваффақият: дар саҳифа паёми «Ташаккур, Ном! Мо бо шумо бо рақами ... тамос мегирем» пайдо мешавад, маълумот тавассути FormData ҷамъ шудааст, шакл барқарор мешавад. Парол дар ҳеҷ ҷо нишон дода намешавад ва ба консол чоп намегардад.
  • ☐ Бонус: тугмаи «Нишон додани парол» ва ҳисобкунаки аломатҳои мондааст — ҳар кадоме аз онҳо.

Чиро супорид

  1. Истинод ба репозиторийи GitHub (папкаи lesson-10 бо файлҳои index.html, style.css, script.js) ё архив ба гурӯҳи Telegram.
  2. Се скриншот: ирсоли холӣ (ҳамаи хатоҳо), шакли қисман пуршуда, ирсоли бомуваффақият.
  3. Файли tests.md: ҷадвал аз ҳадди ақал 10 қимати санҷишӣ барои телефон ва email — «қимат → натиҷаи интизоршаванда» — ва қайд, ки коди шумо кадомашро гузашт.
  4. Агар шумо ЗС-ро истифода кардед: дар README се сатр — маҳз чиро хоҳиш кардед, чиро гирифтед, чиро бо даст ислоҳ кардед. Ҳангоми санҷиш омӯзгор метавонад хоҳиш кунад, ки ҳар сатрро шарҳ диҳед.

Чӣ тавр баҳо медиҳем (0–10)

МеъёрХолҳо
Аломатгузорӣ: ҳамаи 6 майдон, label, name, type, novalidate1
Санҷандаҳои ном, телефон ва email дар маълумоти бад ва хуб кор мекунанд3
Парол (ҳамаи қоидаҳо) ва такрори парол (аз ҷумла ҳангоми тағйири парол)2
Чекбоксҳои розигӣ1
Санҷиши зинда (touched), бе «хафа шудан» аз ҳарфи аввал1
Ирсол: ҳамаи хатоҳо якбора, фокус ба аввалин, муваффақият, барқарор кардани шакл1
Матнҳои фаҳмои хатоҳо (қоида ва намунаро ном мебаранд), коди тоза1
Ишора оид ба вақт

2–3 соат ҷудо кунед. Аввал танҳо санҷандаҳоро созед ва онҳоро дар консол бо 5–10 қимат санҷед, баъд саҳифаро пайваст кунед. Агар монед — аввал 15 дақиқа худатон, баъд савол дар чати гурӯҳ (бо код ва матни хато), баъд ЗС аз рӯи формулаи промпт.

✓ Ёддошти дарс

  • Майдонҳоро мехонем: form.elements.name.value барои матн, адад, рӯйхат ва гурӯҳи радио; .checked барои чекбокс. value — ҳамеша сатр, адад — тавассути Number(...) ё valueAsNumber.
  • submit: дар шакл мешунавем, сатри аввал event.preventDefault(), қиматҳоро дар дохили коркардкунанда мехонем. form.reset() — пок кардан, form.dispatchEvent(new Event("submit", { cancelable: true })) — ба таври барномавӣ фиристодан.
  • FormData: new FormData(form), .get / .getAll / .has, Object.fromEntries(data). Бе name, бо disabled ва чекбоксҳои қайдношуда ба маълумот намеафтанд.
  • Санҷиши дарунсохт: required, type, min/max, pattern; checkValidity(), validity.*, setCustomValidity(). Матнҳои худӣ ва қоидаҳои мураккаб — бо JS-и худӣ ва novalidate.
  • Регэкспҳо: /қолаб/.test(сатр). \d рақам, \s фосила, [a-z] диапазон, + * ? {n,m} миқдор, ^ $ лангарҳои оғоз ва анҷом. Телефон: /^\+992\d{9}$/. Ҳамеша бо маълумоти бад санҷед.
  • Санҷандаи худӣ — функсияи «қимат → матни хато ё ""». Ҳамаи майдонҳо — дар объекти validators, хатоҳоро тавассути textContent дар зери майдон нишон медиҳем, илова aria-invalid. Матнҳои хато қоида ва намунаро ном мебаранд.
  • Санҷиши зинда: blur майдонро «ламсшуда» мекунад, баъд input барои ҳар воридкунӣ аз нав месанҷад. Муқоисаи ду майдон — ҳар дуро мешунавем. Санҷиш ҳангоми submit ҳатмӣ мемонад.
  • ЗС: қоидаҳои санҷишро аз рӯи формулаи промпт талаб мекунем ва регэкспҳоро ҳамеша бо ҳолатҳои худ месанҷем: мувофиқ, сатри холӣ, ҳудуд, хасу хошок, маълумоти воқеӣ. Коде, ки шарҳ дода наметавонем, ворид намекунем. Санҷиш дар браузер — қулайӣ аст, ҳимоя — дар сервер.