Дарси 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 ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< 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 >
form { display : grid; gap : 10px ; max-width : 320px ; }
label { display : grid; gap : 4px ; font-size : 14px ; }
input, select, button { padding : 6px 8px ; font : inherit; }
label:has(input[type="checkbox" ]) { display : flex; align-items : center; gap : 8px ; }
const form = document.querySelector ("#reg" );
document.querySelector ("#show" ).addEventListener ("click" , () => {
console.log ("fullName:" , form.elements.fullName.value);
console.log ("age:" , form.elements.age.value, typeof form.elements.age.value);
console.log ("city:" , form.elements.city.value);
console.log ("agree:" , form.elements.agree.checked);
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Иҷро кунед, дар пешнамоиш чизеро тағйир диҳед (номи дигар ворид кунед, нишона гузоред) ва «Показать значения»-ро пахш кунед. Инак мо чиро ва аз куҷо мехонем:
Майдон Чиро мехонем Чӣ мегирем <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"> бо як name form.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 === "" ? "пусто" : "заполнено").
○ Ҳалшуда қайд кардан 💬 Дар бораи ин вазифа пурсидан
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 ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< 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 >
form { display : grid; gap : 10px ; max-width : 320px ; }
label { display : grid; gap : 4px ; font-size : 14px ; }
input, button { padding : 6px 8px ; font : inherit; }
/* :user-invalid майдонро танҳо БАЪДИ он равшан мекунад, ки корбар бо он кор кардааст */
input:user-invalid { border : 2px solid #d33 ; background : #fff0f0 ; }
input:user-valid { border : 2px solid #2a9d5c ; }
const form = document.querySelector ("#f" );
// Қуттии санҷиш ирсоли воқеиро манъ мекунад, бинобар ин «Отправить»-ро бо клик коркард мекунем.
// Дар саҳифаи оддӣ ба ҷои ин form.addEventListener("submit", ...) менависанд
form.querySelector ("button" ).addEventListener ("click" , (event) => {
event.preventDefault ();
if (form.reportValidity ()) { // агар чизе нодуруст бошад, ишораҳои браузерро нишон медиҳад
console.log ("Форма прошла проверку браузера" );
}
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Аз браузер аз 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 Санҷиши худӣ: функсияҳои санҷанда ва матнҳои хатоҳо
Акнун мо ҳама чизро дорем, то санҷиши худиро нависем. Дастур оддӣ аст ва барои ҳар шакл кор мекунад:
Як санҷанда барои як майдон. Ин функсияест, ки қиматро мегирад ва матни хато -ро бармегардонад — ё сатри холии "", агар ҳама чиз хуб бошад.
Дар объект ҷамъ мекунем. { fullName: validateName, email: validateEmail, ... } — аз рӯи калид намоён аст, ки кадом санҷанда ба кадом майдон тааллуқ дорад.
Хатоҳоро нишон медиҳем. Матн — дар <span> дар зери майдон, ва худи майдонро бо чаҳорчӯбаи сурх ва атрибути aria-invalid қайд мекунем.
Намефиристем , то даме ки ақаллан як хато ҳаст.
Қадами 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 ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< 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 >
form { display : grid; gap : 12px ; max-width : 320px ; }
.field { display : grid; gap : 4px ; }
label { font-size : 14px ; }
input, button { padding : 6px 8px ; font : inherit; }
input.invalid { border : 2px solid #d33 ; background : #fff0f0 ; }
.error { color : #c0392b ; font-size : 13px ; min-height : 1em ; }
const form = document.querySelector ("#f" );
const validators = {
fullName: (v) => (v.trim ().length < 2 ? "Введите имя (минимум 2 буквы)" : "" ),
age: (v) => (Number (v) >= 16 ? "" : "Возраст — число от 16" ),
};
function showError (name, message) {
const input = form.elements[name];
const box = form.querySelector (`[data-error="${name}"]` );
box.textContent = message; // сатри холӣ хаторо пок мекунад
input.classList.toggle ("invalid" , message !== "" ); // чаҳорчӯбаи сурх
input.setAttribute ("aria-invalid" , message ? "true" : "false" ); // барои хонандаҳои экран
}
form.addEventListener ("submit" , (event) => {
event.preventDefault ();
let firstBad = null ;
for (const name in validators) {
const message = validators[name](form.elements[name].value);
showError (name, message);
if (message && !firstBad) firstBad = form.elements[name];
}
if (firstBad) {
firstBad.focus (); // курсорро ба аввалин майдони хатодор мегузорем
return ; // минбаъд намеравем — шакл фиристода намешавад
}
console.log ("Отправлено:" , JSON.stringify (Object.fromEntries (new FormData (form))));
});
// Қуттии санҷиш ирсоли воқеии шаклро манъ мекунад, бинобар ин клики тугмаро дастӣ ба submit табдил медиҳем
// (дар саҳифаи оддӣ ин иловагӣ лозим нест)
form.querySelector ("button" ).addEventListener ("click" , (event) => {
event.preventDefault ();
form.dispatchEvent (new Event ("submit" , { cancelable: true }));
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Иҷро кунед, «Отправить»-ро бо майдонҳои холӣ пахш кунед, баъд ислоҳ кунед ва боз фиристед. Ба се ҷузъ диққат диҳед: хатоҳо фавран дар ҳамаи майдонҳо нишон дода мешаванд, курсор дар аввалин майдони «бад» меистад, ва дар майдони ислоҳшуда хато нест мешавад.
Хатоҳои маъмул
Фаромӯш кардани 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 ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< 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 >
form { display : grid; gap : 12px ; max-width : 320px ; }
.field { display : grid; gap : 4px ; }
input, button { padding : 6px 8px ; font : inherit; }
input.invalid { border : 2px solid #d33 ; background : #fff0f0 ; }
.error { color : #c0392b ; font-size : 13px ; min-height : 1em ; }
const form = document.querySelector ("#f" );
const validators = {
fullName: (v) => (v.trim ().length < 2 ? "Введите имя (минимум 2 буквы)" : "" ),
email: (v) => (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test (v.trim ()) ? "" : "Введите email, например madina@mail.tj" ),
};
function showError (name, message) {
// матн дар span, синфи invalid, aria-invalid
}
form.addEventListener ("submit" , (event) => {
// preventDefault, санҷиши ҳамаи майдонҳо, showError, "Отправлено" ҳангоми муваффақият
});
// ---- санҷиш (тағйир надиҳед) ----
// Қуттии санҷиш ирсоли воқеии шаклро манъ мекунад, бинобар ин клики тугмаро дастӣ ба submit табдил медиҳем
// (дар саҳифаи оддӣ ин иловагӣ лозим нест)
form.querySelector ("button" ).addEventListener ("click" , (event) => {
event.preventDefault ();
form.dispatchEvent (new Event ("submit" , { cancelable: true }));
});
function report (name) {
const input = form.elements[name];
const text = form.querySelector (`[data-error="${name}"]` ).textContent;
console.log (`${name}: ${text || "ok"} | aria-invalid=${input.getAttribute("aria-invalid")} | invalid=${input.classList.contains("invalid")}` );
}
function tryWith (fullName, email) {
form.elements.fullName.value = fullName;
form.elements.email.value = email;
form.dispatchEvent (new Event ("submit" , { cancelable: true }));
report ("fullName" );
report ("email" );
}
tryWith (" " , "ali@mail.tj" );
tryWith ("Али" , "ali@" );
tryWith ("Али" , "ali@mail.tj" );
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда 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)
То даме ки одам майдонро тарк накардааст — хаторо нишон намедиҳем , ҳатто агар қимат ҳоло нодуруст бошад.
Вақте blur кор кард — майдон «ламсшуда» ҳисоб мешавад: месанҷем ва хаторо нишон медиҳем.
Аз ҳамин лаҳза дар ҳар input аз нав месанҷем: ҳамин ки одам ислоҳ кард, хато фавран нест мешавад.
Ҳангоми пахши «Отправить» ҳамаи майдонҳоро якбора «ламс мекунем» ва ҳамаи хатоҳоро нишон медиҳем.
Санҷиши зинда-и email ва парол · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< 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 >
form { display : grid; gap : 12px ; max-width : 320px ; }
.field { display : grid; gap : 4px ; }
.row { display : flex; gap : 6px ; }
.row input { flex : 1 ; }
input, button { padding : 6px 8px ; font : inherit; }
input.invalid { border : 2px solid #d33 ; background : #fff0f0 ; }
.error { color : #c0392b ; font-size : 13px ; min-height : 1em ; }
.hint { color : #667 ; font-size : 13px ; }
const email = document.querySelector ("#email" );
const emailError = document.querySelector ("#email-error" );
let touched = false ;
function validateEmail () {
const value = email.value.trim ();
let message = "" ;
if (value === "" ) message = "Введите email" ;
else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test (value)) message = "Похоже, в адресе ошибка" ;
emailError.textContent = message;
email.classList.toggle ("invalid" , message !== "" );
}
email.addEventListener ("blur" , () => {
touched = true ; // одам аз майдон баромад — акнун метавон хафа шуд
validateEmail ();
});
email.addEventListener ("input" , () => {
if (touched) validateEmail (); // баъди аввалин «баромадан» барои ҳар ҳарф месанҷем
});
// парол: ҳисобкунаки аломатҳо ва тугмаи «нишон додан»
const pass = document.querySelector ("#pass" );
const hint = document.querySelector ("#pass-hint" );
pass.addEventListener ("input" , () => {
hint.textContent = `Введено: ${pass.value.length} из ${pass.maxLength}` ;
});
document.querySelector ("#eye" ).addEventListener ("click" , (event) => {
const hidden = pass.type === "password" ;
pass.type = hidden ? "text" : "password" ;
event.target.textContent = hidden ? "Скрыть" : "Показать" ;
});
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Кӯшиш кунед: дар 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 ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< form id ="f" >
< input id ="password" type ="password" placeholder ="Пароль" >
< input id ="confirm" type ="password" placeholder ="Повторите пароль" >
< button id ="submit" > Создать аккаунт</ button >
</ form >
form { display : grid; gap : 10px ; max-width : 320px ; }
input, button { padding : 6px 8px ; font : inherit; }
button:disabled { opacity : .5 ; cursor : not-allowed; }
const password = document.querySelector ("#password" );
const confirm = document.querySelector ("#confirm" );
const submit = document.querySelector ("#submit" );
function updateButton () {
// submit.disabled = ... (true, то даме ки шартҳо иҷро намешаванд)
}
// updateButton()-ро ҳангоми бор шудан ва ҳангоми input дар ҳар ду майдон даъват кунед
// ---- санҷиш (тағйир надиҳед) ----
const state = () => (submit.disabled ? "заблокирована" : "активна" );
function type (field, value) {
field.value = value;
field.dispatchEvent (new Event ("input" , { bubbles: true }));
console.log (`пароль="${password.value}", повтор="${confirm.value}" → кнопка ${state()}` );
}
console.log ("старт: кнопка " + state ());
type (password, "1234" );
type (password, "12345678" );
type (confirm, "1234567" );
type (confirm, "12345678" );
type (password, "87654321" );
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда старт: кнопка заблокирована
пароль="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. Регэкспи ЗС-ро бо ҳолатҳои худамон месанҷем
Ҳатто ба ҷавоби аз ҳама боэътимод бовар накунед. Одат кунед — ҷадвали санҷишҳо :
3–5 сатри мувофиқ , аз ҷумла «ифлос» (бо фосилаҳо дар канор, бо регистри гуногун).
Сатри холӣ — бояд рад карда шавад (агар майдон ҳатмӣ бошад).
Ҳудуди дарозӣ : як кам аз ҳадди ақал, айнан ҳадди ақал, айнан ҳадди аксар, як зиёд аз ҳадди аксар.
«Хасу хошок» дар атроф : abc1234xyz дар ҷое, ки танҳо рақамҳо лозиманд. Ҳамин тавр шумо набудани ^ ва $-ро мегиред.
Маълумоти воқеии шумо : телефонҳо аз китобчаи ёддошти шумо, номҳои дӯстон бо кириллӣ, 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» чоп мешавад (паролро дар логҳо намегузорем — ҳеҷ гоҳ!).
Нақшаи кор
Аломатгузорӣ. Шакл бо novalidate, дар ҳар майдон — label, name ва span.error-и холӣ дар зери он (data-error="номи майдон").
Санҷандаҳо. Функсияҳои «қимат → матни хато», ки дар объекти validators ҷамъ шудаанд (бахши 6).
Нишон додани хатоҳо. showError — матн, чаҳорчӯбаи сурх, aria-invalid.
Санҷиши зинда. Луғати touched, коркардкунандаҳои blur ва input (бахши 7).
Ирсол. Коркардкунандаи submit: ҳамаи майдонҳоро «ламс мекунем», месанҷем, фокус ба аввалин хатодор ё муваффақият (бахши 2).
Аломатгузорӣ, услубҳо ва «скелет»-и умумӣ (қадамҳои 1, 3)-ро мо тайёр медиҳем. Кори шумо — ду марҳила.
Амалиёт: шаклро ҷамъ мекунем
ВАЗИФАИ 9.1 Марҳилаи 1: санҷандаҳо ва санҷиши зинда миёна
Скелети санҷиши зинда аллакай кор мекунад: showError, validateField ва коркардкунандаҳои blur / input навишта шудаанд. Се санҷандаро аз рӯи қоидаҳои боло ба итмом расонед. Паёмҳоро айнан нусха кунед.
Сабти ном: марҳилаи 1 · Ctrl + Enter ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< 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 >
form { display : grid; gap : 12px ; max-width : 340px ; }
.field { display : grid; gap : 4px ; }
label { font-size : 14px ; font-weight : 600 ; }
input, button { padding : 8px 10px ; font : inherit; border : 1px solid #b8c0cc ; border-radius : 8px ; }
button { background : #1d9a6c ; color : #fff ; border-color : transparent; cursor : pointer; }
input.invalid { border : 2px solid #d33 ; background : #fff0f0 ; }
.error { color : #c0392b ; font-size : 13px ; min-height : 1em ; }
const form = document.querySelector ("#reg" );
const touched = {};
const validators = {
fullName (value) {
// ном: баъди trim ҳадди ақал 2 аломат → "Имя — минимум 2 буквы"
return "" ;
},
email (value) {
// формат /^[^\s@]+@[^\s@]+\.[^\s@]+$/ → "Введите email в формате name@mail.tj"
return "" ;
},
password (value) {
// аввал дарозӣ: "Пароль — минимум 8 символов", баъд рақам: "Добавьте хотя бы одну цифру"
return "" ;
},
};
// ---- қисми тайёр: нишон додани хатоҳо ва санҷиши зинда ----
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);
});
}
// ---- санҷиш (тағйир надиҳед) ----
function typeInto (name, value) {
const field = form.elements[name];
field.value = value;
field.dispatchEvent (new Event ("input" , { bubbles: true }));
}
function leave (name) {
form.elements[name].dispatchEvent (new Event ("blur" ));
}
function msg (name) {
return form.querySelector (`[data-error="${name}"]` ).textContent || "ok" ;
}
typeInto ("fullName" , "А" );
console.log ("имя до blur: " + msg ("fullName" ));
leave ("fullName" );
console.log ("имя после blur: " + msg ("fullName" ));
typeInto ("fullName" , "Али" );
console.log ("имя после правки: " + msg ("fullName" ));
typeInto ("email" , "ali@" );
leave ("email" );
console.log ("email: " + msg ("email" ));
typeInto ("email" , "ali@mail.tj" );
console.log ("email после правки: " + msg ("email" ));
typeInto ("password" , "abcdefgh" );
leave ("password" );
console.log ("пароль 1: " + msg ("password" ));
typeInto ("password" , "abc" );
console.log ("пароль 2: " + msg ("password" ));
typeInto ("password" , "abcdefg1" );
console.log ("пароль 3: " + msg ("password" ));
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда имя до 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 ↺ Аз нав ▶ Иҷро кардан
index.html style.css script.js
< 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 >
form { display : grid; gap : 12px ; max-width : 340px ; }
.field { display : grid; gap : 4px ; }
label { font-size : 14px ; font-weight : 600 ; }
input, button { padding : 8px 10px ; font : inherit; border : 1px solid #b8c0cc ; border-radius : 8px ; }
button { background : #1d9a6c ; color : #fff ; border-color : transparent; cursor : pointer; }
input.invalid { border : 2px solid #d33 ; background : #fff0f0 ; }
.error { color : #c0392b ; font-size : 13px ; min-height : 1em ; }
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 "" ;
},
// (1) confirm(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);
});
}
// (2) ҳангоми тағйири парол confirm-ро аз нав санҷед, агар touched.confirm
// (3) коркардкунандаи submit
form.addEventListener ("submit" , (event) => {
});
// Қуттии санҷиш ирсоли воқеии шаклро манъ мекунад, бинобар ин клики тугмаро дастӣ ба submit табдил медиҳем
// (дар саҳифаи оддӣ ин иловагӣ лозим нест)
form.querySelector ("button" ).addEventListener ("click" , (event) => {
event.preventDefault ();
form.dispatchEvent (new Event ("submit" , { cancelable: true }));
});
// ---- санҷиш (тағйир надиҳед) ----
function typeInto (name, value) {
const field = form.elements[name];
field.value = value;
field.dispatchEvent (new Event ("input" , { bubbles: true }));
}
function msg (name) {
return form.querySelector (`[data-error="${name}"]` ).textContent || "ok" ;
}
typeInto ("fullName" , "Мадина" );
typeInto ("email" , "madina@mail.tj" );
typeInto ("password" , "qwerty12" );
typeInto ("confirm" , "qwerty1" );
form.dispatchEvent (new Event ("submit" , { cancelable: true }));
console.log ("повтор: " + msg ("confirm" ));
typeInto ("confirm" , "qwerty12" );
console.log ("повтор после правки: " + msg ("confirm" ));
typeInto ("password" , "qwerty99" );
console.log ("после смены пароля: " + msg ("confirm" ));
typeInto ("confirm" , "qwerty99" );
form.dispatchEvent (new Event ("submit" , { cancelable: true }));
Пешнамоиш Пӯшонидан
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда повтор: Пароли не совпадают
повтор после правки: 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» 3 Email Формати оддӣ бо «@» ва нуқта дар домен «Email-ро ворид кунед, масалан madina@mail.tj» 4 Парол Аз 8 аломат, рақам ҳаст, ҳарфи калон ҳаст, фосила нест Ҳамаи қоидаҳои вайроншударо бо рӯйхат ё тавассути « · » нишон диҳед5 Такрори парол Бо парол мувофиқ аст (ҳангоми тағйири парол аз нав санҷида мешавад) «Паролҳо мувофиқат намекунанд» 6 Розигӣ бо қоидаҳои курс Чекбокс бояд қайд карда шуда бошад «Бе розигӣ номнависӣ мумкин нест»
Чӣ бояд кор кунад
☐ Аломатгузорӣ: form novalidate, дар ҳар майдон label, name ва type-и дуруст (tel, email, password, checkbox) ҳаст.
☐ Ҳар санҷанда — функсияи алоҳидаи «қимат → матни хато ё сатри холӣ».
☐ Санҷиши зинда аз рӯи нақшаи «touched»: хато баъди баромадан аз майдон пайдо мешавад ва ҳангоми ислоҳ фавран нест мешавад.
☐ Ҳангоми ирсол ҳамаи майдонҳо санҷида мешаванд, фокус ба аввалин хатодор гузошта мешавад.
☐ Хатоҳо дар зери майдонҳо нишон дода мешаванд (textContent), майдон чаҳорчӯбаи сурх ва aria-invalid дорад.
☐ Ҳангоми муваффақият: дар саҳифа паёми «Ташаккур, Ном! Мо бо шумо бо рақами ... тамос мегирем» пайдо мешавад, маълумот тавассути FormData ҷамъ шудааст, шакл барқарор мешавад. Парол дар ҳеҷ ҷо нишон дода намешавад ва ба консол чоп намегардад.
☐ Бонус: тугмаи «Нишон додани парол» ва ҳисобкунаки аломатҳои мондааст — ҳар кадоме аз онҳо.
Чиро супорид
Истинод ба репозиторийи GitHub (папкаи lesson-10 бо файлҳои index.html, style.css, script.js) ё архив ба гурӯҳи Telegram.
Се скриншот: ирсоли холӣ (ҳамаи хатоҳо), шакли қисман пуршуда, ирсоли бомуваффақият.
Файли tests.md: ҷадвал аз ҳадди ақал 10 қимати санҷишӣ барои телефон ва email — «қимат → натиҷаи интизоршаванда» — ва қайд, ки коди шумо кадомашро гузашт.
Агар шумо ЗС-ро истифода кардед: дар README се сатр — маҳз чиро хоҳиш кардед, чиро гирифтед, чиро бо даст ислоҳ кардед. Ҳангоми санҷиш омӯзгор метавонад хоҳиш кунад, ки ҳар сатрро шарҳ диҳед.
Чӣ тавр баҳо медиҳем (0–10)
Меъёр Холҳо Аломатгузорӣ: ҳамаи 6 майдон, label, name, type, novalidate 1 Санҷандаҳои ном, телефон ва 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 ҳатмӣ мемонад.
ЗС: қоидаҳои санҷишро аз рӯи формулаи промпт талаб мекунем ва регэкспҳоро ҳамеша бо ҳолатҳои худ месанҷем: мувофиқ, сатри холӣ, ҳудуд, хасу хошок, маълумоти воқеӣ. Коде, ки шарҳ дода наметавонем, ворид намекунем. Санҷиш дар браузер — қулайӣ аст, ҳимоя — дар сервер.