مراجعة سريعة
تعلّمنا في درس النماذج (Forms) الأساسيات: <form> و<input> و<label>. هنا نتعمّق في أنواع الحقول وخصائصها التي تجعل نماذجك أقوى وأكثر أمانًا.
أنواع حقل <input> (Input Types)
السمة type تحدّد نوع الحقل وتُفعّل تحققًا تلقائيًا ولوحة مفاتيح مناسبة على الجوال:
<input type="text" /> <!-- نص عادي -->
<input type="email" /> <!-- بريد (يتحقق من الصيغة) -->
<input type="password" /> <!-- كلمة مرور مخفية -->
<input type="number" /> <!-- أرقام فقط -->
<input type="tel" /> <!-- هاتف -->
<input type="url" /> <!-- رابط -->
<input type="date" /> <!-- منتقي تاريخ -->
<input type="time" /> <!-- وقت -->
<input type="color" /> <!-- منتقي ألوان -->
<input type="file" /> <!-- رفع ملف -->
<input type="range" /> <!-- شريط تمرير -->
<input type="checkbox" /> <!-- مربع اختيار -->
<input type="radio" /> <!-- زر اختيار واحد -->
<input type="hidden" /> <!-- قيمة مخفية -->
خصائص الإدخال (Input Attributes)
<input type="text" placeholder="اكتب اسمك" /> <!-- نص إرشادي -->
<input type="email" required /> <!-- إلزامي -->
<input type="text" maxlength="20" /> <!-- أقصى عدد أحرف -->
<input type="number" min="1" max="100" /> <!-- حدود رقمية -->
<input type="text" value="قيمة افتراضية" />
<input type="text" readonly /> <!-- للقراءة فقط -->
<input type="text" disabled /> <!-- معطّل -->
<input type="text" autofocus /> <!-- تركيز تلقائي -->
<input type="tel" pattern="[0-9]{10}" /> <!-- نمط تحقق -->
التسمية الصحيحة بـ <label>
اربط كل حقل بتسمية لتحسين الوصول وسهولة النقر:
<label for="email">البريد الإلكتروني</label>
<input type="email" id="email" name="email" required />
عناصر نماذج أخرى
<textarea rows="4">نص متعدد الأسطر</textarea>
<select name="city">
<option value="amman">عمّان</option>
<option value="riyadh">الرياض</option>
</select>
<fieldset>
<legend>بياناتك</legend>
<!-- حقول مجمّعة -->
</fieldset>
الأزرار (Buttons)
<button type="submit">إرسال</button>
<button type="reset">إعادة تعيين</button>
<button type="button">زر عادي (لـ JavaScript)</button>
خصائص <form>
<form action="/submit" method="post">
action: عنوان معالجة البيانات.method:get(تظهر في الرابط، للبحث) أوpost(مخفية، للبيانات الحسّاسة).
عناصر إخراج ونتائج: datalist وmeter وprogress وoutput
أربعة عناصر أقل شهرة لكنها تحلّ مشاكل حقيقية:
<label for="browser">متصفحك المفضّل:</label>
<input list="browsers" id="browser" name="browser" />
<datalist id="browsers">
<option value="Chrome"></option>
<option value="Firefox"></option>
<option value="Safari"></option>
</datalist>
<label for="usage">مساحة التخزين المستخدمة:</label>
<meter id="usage" value="7" min="0" max="10">7 من 10 GB</meter>
<label for="upload">تقدّم الرفع:</label>
<progress id="upload" value="60" max="100">60%</progress>
<form oninput="result.value = parseInt(a.value) + parseInt(b.value)">
<input type="number" id="a" value="0" /> +
<input type="number" id="b" value="0" /> =
<output name="result" for="a b">0</output>
</form>
datalist: يربط حقلinputعادي بقائمة اقتراحات عبرlist="id"— الفرق عنselect: يبقى بإمكان المستخدم كتابة قيمة غير موجودة بالقائمة، فهي اقتراحات لا خيارات مُغلَقة.meter: قيمة ضمن نطاق معروف الحدود (مساحة تخزين، تقييم نجوم) — ليس لتقدّم عملية جارية.progress: تقدّم عملية جارية فعليًا (تحميل، رفع ملف) — بلاvalueيظهر شريطًا غير محدد (indeterminate) للعمليات مجهولة المدة.output: نتيجة حساب مرتبط بحقول أخرى عبرfor— يقرؤه قارئ الشاشة كتحديث حي حين يتغيّر (بإضافةaria-liveعادةً في تطبيق حقيقي).
🔑 الفرق العملي بين
meterوprogress: قيمة ثابتة ضمن نطاق (مساحة القرص) تستخدمmeter، وقيمة تتغيّر نحو هدف (نسبة تحميل) تستخدمprogress.
autocomplete وinputmode: تجربة أفضل للجوال
<input type="text" name="fullname" autocomplete="name" />
<input type="email" name="email" autocomplete="email" />
<input type="password" name="new-password" autocomplete="new-password" />
<input type="tel" name="phone" inputmode="tel" />
<input type="text" name="otp" inputmode="numeric" pattern="[0-9]*" />
autocomplete: يخبر المتصفح ماذا يقترح من بيانات محفوظة سابقًا — قيم قياسية مثلname/email/tel/street-addressتُفعّل الملء التلقائي الذكي. لحقول كلمة المرور فرّق دائمًا بينnew-password(تسجيل حساب جديد) وcurrent-password(تسجيل الدخول) — الفرق يمنع متصفحك من اقتراح كلمة مرور قديمة في خانة "كلمة مرور جديدة".inputmode: يخبر الجوال أي لوحة مفاتيح يعرض (numeric،tel،email،url) بغضّ النظر عنtype— مفيد خصوصًا لحقلtextيجب أن يقبل نصًا لكن يُفضَّل إدخاله رقميًا (كرمز تحقق OTP).
رسائل أخطاء متاحة للوصول
رسالة خطأ حمراء تظهر بصريًا فقط لا تصل لمستخدم قارئ الشاشة. اربط الحقل بالرسالة برمجيًا عبر aria-describedby، وأعلن الخطأ عبر aria-invalid:
<label for="pw">كلمة المرور</label>
<input
type="password"
id="pw"
name="password"
aria-describedby="pw-hint pw-error"
aria-invalid="true"
/>
<p id="pw-hint">8 أحرف على الأقل، مع رقم واحد.</p>
<p id="pw-error" role="alert">كلمة المرور قصيرة جدًا.</p>
aria-describedbyيقبل أكثر من معرّف مفصولًا بمسافة — يربط الحقل بالتلميح والخطأ معًا.aria-invalid="true"يُضاف فقط بعد محاولة إرسال فاشلة (ديناميكيًا عبر JavaScript عادة) — لا تكتبه ثابتًا على حقل فارغ لم يُحاول المستخدم إرساله بعد.role="alert"على رسالة الخطأ يجعل قارئ الشاشة يعلنها فورًا عند ظهورها، دون أن يحتاج المستخدم للتنقّل إليها يدويًا.
أمان النماذج: ما لا يحميه HTML وحده
<input type="email" required pattern=".+@.+\..+" />
required وpattern وبقية التحقق المدمج تجربة مستخدم، لا حماية أمنية — أي زائر يستطيع تعطيل JavaScript أو إرسال الطلب مباشرة متجاوزًا هذه القيود بالكامل. القاعدة الثابتة: كرّر كل تحقق من صحة البيانات على الخادم أيضًا، فهو الحارس الحقيقي الوحيد.
نقطتان إضافيتان:
- استخدم
method="post"(لاget) لأي بيانات حسّاسة —getيضع القيم داخل الرابط نفسه، فتظهر في تاريخ المتصفح وسجلّات الخادم. - لا علاقة لـ HTML بتشفير الاتصال نفسه — هذا دور HTTPS على مستوى الموقع كاملًا، لا شيء يضبطه النموذج بمفرده.
الأخطاء الشائعة
- ❌ نسيان
name: الحقل بلاnameلا تُرسَل قيمته للخادم. - ❌ استخدام
textلكل شيء: استخدمemail/number/dateلتحقّق ولوحة مفاتيح أفضل. - ❌ نسيان
<label>: سيئ للوصول وسهولة الاستخدام. - ❌ الخلط بين
meterوprogress: الأول لقيمة ضمن نطاق ثابت، والثاني لعملية جارية. - ❌ الاعتماد على
required/patternكحماية أمنية كافية بدل تكرار التحقق فعليًا على الخادم.
خلاصة
أتقن أنواع input المناسبة وخصائص مثل required وplaceholder وpattern، واربط كل حقل بـ <label>. استخدم datalist/meter/progress/output في مكانها الصحيح، وautocomplete/inputmode لتجربة جوال أفضل، وaria-describedby لرسائل أخطاء يسمعها الجميع — وتذكّر أن أي تحقق بواجهة المستخدم يجب أن يتكرر على الخادم.