Free tutorials & notes in Hindi & English · Clean code examples 🧰 मुफ़्त PDF और फ़ोटो टूल्स →
🖱️ Days 8–14 – Data, DOM और Events  ·  दिन 13

दिन 13: Forms, FormData और Validation

⏱ 100 min📶 Intermediate🎯 100% self-study
दिन 13 / 30

✅ आज आप सीखेंगे

  • preventDefault के साथ submit संभालना
  • FormData और Object.fromEntries से सब fields पढ़ना
  • साफ़ validation नियम (mobile, PIN, quantity, date)
  • Fields के पास accessible error messages
  • Constraint Validation API और live गणना

🏢 असली दुनिया में

HTML course का सिर्फ़-HTML order form साफ़ ग़लत data रोकता था, पर customers अब भी कल की date के लिए order करते, delivery area के बाहर के PIN लिखते और सिर्फ़ English में अस्पष्ट browser bubble पाते थे। ख़राब forms पर businesses orders खोते हैं। आज आप ऐसा दोस्ताना form बनाएँगे जो हर ग़लती समझाए और total live जोड़े।

Submit संभालना और values पढ़ना

HTML + JavaScript
<style>
form { display: grid; gap: 10px; max-width: 380px; }
label { font-weight: 600; display: block; margin-bottom: 2px; }
input, select { width: 100%; box-sizing: border-box; }
.error { color: #b91c1c; font-size: .85rem; min-height: 1.1em; }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color: #dc2626; background: #fef2f2; }
.ok { background: #dcfce7; padding: 10px; border-radius: 8px; }
</style>

<form id="f">
  <label for="name">Name</label><input id="name" name="name" value="Aarti Gupta">
  <label for="sweet">Sweet</label>
  <select id="sweet" name="sweet"><option value="1">Kaju Katli</option><option value="2" selected>Ghewar</option></select>
  <label><input type="checkbox" name="gift" checked> Gift wrap</label>
  <fieldset><legend>Delivery</legend>
    <label><input type="radio" name="mode" value="home" checked> Home</label>
    <label><input type="radio" name="mode" value="pickup"> Pick-up</label>
  </fieldset>
  <button>Submit</button>
</form>
<pre id="out"></pre>

<script>
document.querySelector('#f').addEventListener('submit', function (e) {
  e.preventDefault();                                   // no page reload
  const data = new FormData(e.currentTarget);           // reads every named field
  const order = Object.fromEntries(data);               // → plain object
  order.gift = data.has('gift');                        // unchecked boxes are missing
  order.sweet = Number(order.sweet);
  document.querySelector('#out').textContent = JSON.stringify(order, null, 2);
});
</script>
▶  Submit: FormData turns the whole form into an object
🧠 name attribute ज़रूरी है

FormData सिर्फ़ name वाले fields पढ़ता है। Radio buttons एक name साझा करते हैं और चुनी value देते हैं; बिना tick वाला checkbox शामिल ही नहीं होता – data.has("gift") से जाँचें।

छोटे functions के रूप में validation नियम

JavaScript
const DELIVERY_PINS = ['302001', '302003', '302004', '302012', '302017'];

const rules = {
  name:  v => v.trim().length >= 2 || 'Please enter your full name.',
  phone: v => /^[6-9]\d{9}$/.test(v.replace(/\D/g, '').slice(-10)) || 'Enter a 10-digit mobile number starting with 6–9.',
  pin:   v => DELIVERY_PINS.includes(v.trim()) || 'Sorry, we do not deliver to this PIN yet.',
  qty:   v => (Number(v) >= 0.25 && Number(v) <= 50) || 'Quantity must be between 0.25 and 50 kg.',
  date:  (v, today) => v >= today || 'Choose today or a future date.',
};

function validate(order, today) {
  const errors = {};
  for (const [field, rule] of Object.entries(rules)) {
    const result = rule(order[field] ?? '', today);
    if (result !== true) errors[field] = result;
  }
  return errors;
}

const today = '2026-10-25';
console.log(validate({ name: 'Aarti', phone: '+91 98290 12345', pin: '302003', qty: '2', date: '2026-10-26' }, today));
console.log(validate({ name: 'A', phone: '12345', pin: '110001', qty: '0', date: '2026-10-20' }, today));
{} { name: 'Please enter your full name.', phone: 'Enter a 10-digit mobile number starting with 6–9.', pin: 'Sorry, we do not deliver to this PIN yet.', qty: 'Quantity must be between 0.25 and 50 kg.', date: 'Choose today or a future date.' }
💡 नियम true या message क्यों लौटाते हैं

हर नियम “ठीक है?” का जवाब true से देता है, या समझाता है क्या ग़लत है। वही object server (Node.js) पर दोबारा इस्तेमाल हो सकता है – और logic छुए बिना messages Hindi में बदल सकते हैं।

पूरा validated order form

HTML + JavaScript
<style>
form { display: grid; gap: 10px; max-width: 380px; }
label { font-weight: 600; display: block; margin-bottom: 2px; }
input, select { width: 100%; box-sizing: border-box; }
.error { color: #b91c1c; font-size: .85rem; min-height: 1.1em; }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color: #dc2626; background: #fef2f2; }
.ok { background: #dcfce7; padding: 10px; border-radius: 8px; }
</style>

<form id="order" novalidate>
  <div><label for="name">Name</label><input id="name" name="name" autocomplete="name" aria-describedby="name-err"><div class="error" id="name-err"></div></div>
  <div><label for="phone">Mobile</label><input id="phone" name="phone" type="tel" inputmode="numeric" autocomplete="tel" aria-describedby="phone-err"><div class="error" id="phone-err"></div></div>
  <div><label for="pin">PIN code</label><input id="pin" name="pin" inputmode="numeric" maxlength="6" aria-describedby="pin-err"><div class="error" id="pin-err"></div></div>
  <div><label for="qty">Kaju Katli (kg) – ₹900/kg</label><input id="qty" name="qty" type="number" value="1" step="0.25" aria-describedby="qty-err"><div class="error" id="qty-err"></div></div>
  <div><label for="date">Delivery date</label><input id="date" name="date" type="date" aria-describedby="date-err"><div class="error" id="date-err"></div></div>
  <p id="total"></p>
  <button>Place order</button>
  <div id="result" role="status"></div>
</form>

<script>
const PINS = ['302001', '302003', '302004', '302012', '302017'];
const today = new Date().toISOString().slice(0, 10);
const form = document.querySelector('#order');
form.date.min = today;

const rules = {
  name:  v => v.trim().length >= 2 || 'Please enter your full name.',
  phone: v => /^[6-9]\d{9}$/.test(v.replace(/\D/g, '').slice(-10)) || 'Enter a 10-digit mobile number starting with 6–9.',
  pin:   v => PINS.includes(v.trim()) || 'We deliver to 302001, 302003, 302004, 302012, 302017.',
  qty:   v => (Number(v) >= 0.25 && Number(v) <= 50) || 'Between 0.25 and 50 kg.',
  date:  v => (v !== '' && v >= today) || 'Choose today or a future date.',
};

function showError(field, message) {
  const input = form.elements[field];
  input.setAttribute('aria-invalid', message ? 'true' : 'false');
  document.querySelector('#' + field + '-err').textContent = message || '';
}
function check(field) {
  const result = rules[field](form.elements[field].value);
  showError(field, result === true ? '' : result);
  return result === true;
}
function updateTotal() {
  const kg = Number(form.qty.value) || 0;
  const amount = kg * 900;
  const delivery = amount >= 1500 || amount === 0 ? 0 : 60;
  document.querySelector('#total').textContent = `Total ₹${amount + delivery} (delivery ₹${delivery})`;
}

Object.keys(rules).forEach(f => form.elements[f].addEventListener('blur', () => check(f)));   // validate on leave
form.addEventListener('input', e => {
  if (e.target.getAttribute('aria-invalid') === 'true') check(e.target.name);   // re-check while fixing
  if (e.target.name === 'qty') updateTotal();
});
form.addEventListener('submit', e => {
  e.preventDefault();
  const results = Object.keys(rules).map(check);
  const firstBad = Object.keys(rules).find((f, i) => !results[i]);
  if (firstBad) { form.elements[firstBad].focus(); return; }          // move focus to the first error
  const data = Object.fromEntries(new FormData(form));
  document.querySelector('#result').innerHTML = `<p class="ok">✅ Order for ${data.qty} kg booked for ${data.date}. We will call ${data.phone}.</p>`;
});
updateTotal();
</script>
▶  Try submitting empty, then fix each field – errors update live
UX नियमहमने कैसे किया
User के लिखने से पहले न चिल्लाएँPage load पर नहीं, blur और submit पर validate
ठीक होते ही error हटेInput पर सिर्फ़ invalid fields दोबारा जाँचें
ठीक-ठीक बताएँ क्या करना है“6–9 से शुरू 10-digit mobile लिखें”
Accessible errorsaria-invalid + aria-describedby message को field से जोड़ते हैं
समस्या तक पहुँचाएँSubmit पर पहले invalid field पर focus
इंसानी formats मानें+91 98290-12345 → जाँच से पहले अंक निकाले
⚠️ Client-side validation सिर्फ़ सुविधा के लिए

कोई भी JavaScript bypass कर सकता है (DevTools, curl)। Server को सब कुछ दोबारा validate करना होगा – Day 20 का हमारा practice API यही करता है और HTTP 422 के साथ field errors लौटाता है।

Built-in Constraint Validation API

HTML + JavaScript
<style>
form { display: grid; gap: 10px; max-width: 380px; }
label { font-weight: 600; display: block; margin-bottom: 2px; }
input, select { width: 100%; box-sizing: border-box; }
.error { color: #b91c1c; font-size: .85rem; min-height: 1.1em; }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color: #dc2626; background: #fef2f2; }
.ok { background: #dcfce7; padding: 10px; border-radius: 8px; }
</style>

<form id="f2">
  <label for="email">E-mail</label>
  <input id="email" type="email" required>
  <button>Subscribe</button>
</form>

<script>
const email = document.querySelector('#email');
email.addEventListener('input', () => {
  if (email.validity.typeMismatch) email.setCustomValidity('Please enter an e-mail like name@example.com');
  else if (email.validity.valueMissing) email.setCustomValidity('E-mail is required to get offers');
  else email.setCustomValidity('');              // '' = valid again
});
document.querySelector('#f2').addEventListener('submit', e => {
  e.preventDefault();
  if (!e.currentTarget.checkValidity()) { e.currentTarget.reportValidity(); return; }
  e.currentTarget.insertAdjacentHTML('beforeend', '<p class="ok">Subscribed ✅</p>');
});
</script>
▶  validity + setCustomValidity + reportValidity: custom text in the native bubble

🏅 आज के Job Skills

✔ Submit संभालना और FormData से data पढ़ना✔ दोबारा उपयोगी validation नियम✔ Accessible, उपयोगी error messages✔ Constraint Validation API और live totals

Practice tasks

🏋️ Practice – ख़ुद करें

Task 1: Password strength checker लिखें: कम से कम 8 characters, एक अंक, एक capital letter; लिखते समय कौन से नियम पूरे हुए ✔/✖ से दिखाएँ।
Solution देखें
▶  Result
Task 2: “Confirm mobile” field जोड़ें और पहले mobile से मेल न खाए तो error दिखाएँ।
Task 3: messages = { en: {...}, hi: {...} } object से order form के सब error messages Hindi में बदलें।

Quick quiz

🧠 Quick Quiz – ख़ुद को जाँचें

1. FormData किन fields को पढ़ता है?
name ही key है।
2. FormData में बिना tick checkbox…
data.has() लें।
3. Error पहली बार दिखाने का सबसे अच्छा समय?
जल्दी न डाँटें।
4. Screen readers के लिए error message को input से जोड़ें:
साथ में aria-invalid।
5. क्या client-side validation security के लिए काफ़ी है?
Bypass हो सकता है।

Interview corner

💼 Interview Corner

Vanilla JS में forms अच्छे से कैसे validate करें?

Basics के लिए HTML attributes, नियम functions में एक जगह, blur/submit पर validate, inline accessible messages (aria-invalid, aria-describedby), पहली error पर focus, input साफ़ (trim, digits) और server पर हमेशा दोबारा validate।

Submit पर e.preventDefault() क्या करता है?

Browser का default navigation/reload रोकता है ताकि JavaScript page पर रहते हुए data validate करके (जैसे fetch से) भेज सके।

सारांश

  • submit + preventDefault + FormData + Object.fromEntries।
  • नियम छोटे functions जो true या message लौटाएँ।
  • blur/submit पर validate, accessible inline errors, पहली पर focus।
  • Client जाँच UX है; server को दोबारा validate करना होगा।
➡️ आगे

Day 14 – Mini project: add, edit, complete, filter, delete और saving वाला पूरा to-do app।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

novalidate – क्यों जोड़ा?
यह browser के अपने bubbles बंद करता है ताकि हमारे custom messages अनुभव नियंत्रित करें। हमारा JS फिर भी सब validate करता है।
क्या form library लूँ?
React में जटिल multi-step forms के लिए React Hook Form जैसी libraries मदद करती हैं। पहले vanilla version सीखें – concepts वही हैं।
← JavaScript (30 Days)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

अगला topicदिन 14: Mini Project: To-Do App आपकी प्रगति: 13 / 30 (43%) · Lesson 14 / 30 आगे बढ़ें →

यह lesson कैसा लगा?

आपकी राय से हम content और बेहतर बनाते हैं।

अपना review और सुझाव लिखें (वैकल्पिक)

Review approve होने के बाद आपका नाम और शहर इसके साथ public दिख सकते हैं। Email या phone न लिखें।

▶ CodingEasily on YouTube

Video से सीखें – आसान Hindi में

चुनी हुई video: RDBMS भाग 3 – Class XI Commerce IT

▶ Channel subscribe करें