التحقق من نماذج HTML باستخدام JavaScript بطريقة منظمة
لا يكفي أن يحتوي النموذج على حقول صحيحة شكلياً. يحتاج المستخدم إلى معرفة الحقل الذي ينقصه، ويحتاج الخادم إلى التحقق من البيانات مرة أخرى قبل حفظها. في هذا المقال نبني تحققاً بسيطاً لنموذج تسجيل، ونفصل قواعد التحقق عن عرض الرسائل، ونمنع الإرسال عندما توجد مشكلة. سنركز على البريد وكلمة المرور والاسم، مع ملاحظة أن التحقق في المتصفح لتحسين التجربة وليس بديلاً عن تحقق الخادم. بهذه الطريقة يصبح النموذج مفهوماً وقابلاً لإضافة حقول جديدة من دون نسخ الشروط في كل حدث.
الفكرة الأساسية
تبدأ العملية عند submit لا عند click على زر واحد فقط، لأن المستخدم قد يرسل النموذج بلوحة المفاتيح. يجب منع السلوك الافتراضي بعد اكتشاف خطأ، ثم مسح الرسائل القديمة، والتحقق من كل قيمة. لا تعتمد على تعبير منتظم معقد للبريد يرفض عناوين صحيحة أو يقبل عناوين غريبة؛ تحقق من الشكل الأساسي واترك التحقق النهائي للخادم. اعرض الرسالة بالقرب من الحقل، واستخدم aria-describedby وaria-invalid عندما تهتم بإتاحة الاستخدام.
مثال برمجي عملي
const form = document.querySelector("#signup-form");
const nameInput = document.querySelector("#name");
const emailInput = document.querySelector("#email");
const passwordInput = document.querySelector("#password");
function setError(input, message) {
const error = document.querySelector(`#${input.id}-error`);
input.setCustomValidity(message);
input.setAttribute("aria-invalid", message ? "true" : "false");
error.textContent = message;
}
form.addEventListener("submit", (event) => {
setError(nameInput, nameInput.value.trim() ? "" : "اكتب الاسم");
setError(emailInput, emailInput.validity.valid ? "" : "اكتب بريداً صحيحاً");
setError(passwordInput, passwordInput.value.length >= 8 ? "" : "استخدم 8 أحرف على الأقل");
if (!form.checkValidity()) {
event.preventDefault();
}
});
شرح المثال
يستفيد المثال من قواعد HTML الأصلية مثل type=email وrequired، ثم يضيف رسائل عربية قريبة من الحقول. setCustomValidity يجعل المتصفح يعرف أن الحقل غير صالح، وcheckValidity يراجع النموذج كله قبل السماح بالإرسال. لا نستخدم click لأن حدث submit يغطي زر الفأرة ولوحة المفاتيح. يغير aria-invalid حالة الوصول، بينما يعرض العنصر error سبب المشكلة. يجب أن تحتوي صفحة HTML على عناصر الخطأ ذات المعرف المناسب حتى يعمل الربط.
اكتب جدولاً صغيراً للحقول وقواعدها قبل تنفيذ JavaScript. حدد ماذا يحدث عند ترك الحقل فارغاً، وعند وجود مسافات، وعند فقدان التركيز، وعند الإرسال. اعرض رسالة واحدة مفيدة لكل حالة ولا تغيرها بسرعة تجعل قراءتها صعبة. بعد نجاح التحقق أرسل البيانات إلى الخادم، ثم اعرض نتيجة الطلب في حالة منفصلة. اختبر النموذج من لوحة المفاتيح وعلى شاشة صغيرة، لأن المشكلة ليست في JavaScript وحده.
طريقة العمل قبل كتابة الكود
قبل فتح محرر النصوص، اكتب النتيجة التي تريد الوصول إليها وحدد المدخلات والمخرجات. يساعد هذا التمرين على كشف الحالات الغامضة مبكراً، مثل قيمة ناقصة أو قائمة فارغة أو طلب لا يصل إلى الخادم. لا تحتاج إلى مخطط كبير للمثال التعليمي، لكنك تحتاج إلى أسماء واضحة وخطوات يمكن اختبارها واحدة بعد أخرى. عندما تتغير الفكرة أثناء الكتابة، عدل التصميم قبل إضافة شروط متفرعة يصعب تتبعها.
قسّم المشكلة إلى أجزاء صغيرة، واجعل كل جزء مسؤولاً عن قرار واحد قدر الإمكان. يمكن أن تكون الأجزاء دوال، أو مكونات، أو طبقات منفصلة بحسب التقنية. لا يعني التقسيم إنشاء ملفات كثيرة، بل يعني أن تعرف أين تبحث عندما يحدث الخطأ. سجّل الافتراضات المهمة بجملة قصيرة، مثل أن القائمة مرتبة أو أن السعر غير سالب، ثم تحقق منها في المكان المناسب بدلاً من الاعتماد على الذاكرة.
اختبار المثال في حالات مختلفة
لا تختبر المسار الطبيعي فقط. جرّب مدخلاً فارغاً، وقيمة أكبر من المتوقع، وعنصراً غير موجود، وطلباً يصل من دون البيانات المطلوبة. الحالات الحدية تكشف غالباً مشكلات الفهارس والأنواع وترتيب التنفيذ. اكتب النتيجة المتوقعة قبل تشغيل الكود، ثم قارنها بالنتيجة الفعلية. إذا كان الاختبار يمر بالصدفة، أضف شرطاً أو اختباراً أوضح، ولا تكتفِ بطباعة قيمة تبدو منطقية.
- تحقق من المدخلات قبل استخدامها في الحساب أو التخزين.
- أعد رسالة مفهومة ورمزاً مناسباً عند وقوع الخطأ.
- اجعل الاختبارات قابلة للإعادة من دون اعتماد على شبكة أو وقت متغير.
- راجع أثر التغيير على الأجزاء التي تستدعي الدالة أو المكون.
ملاحظات تتعلق بجودة الكود
تظهر جودة الحل في التفاصيل الصغيرة: اسم يشرح الغرض، ودالة لا تجمع مهاماً بعيدة، ورسالة خطأ لا تترك القارئ في حيرة. لا تحاول اختصار كل سطر، فالكود المقروء أفضل من تعبير قصير يحتاج إلى شرح طويل. وفي الوقت نفسه، لا تكرر القاعدة نفسها في أماكن كثيرة؛ انقلها إلى موضع واحد عندما يكون ذلك أوضح. راجع الملف بعد أن يعمل، لأن أول نسخة تركز عادةً على الوصول إلى النتيجة أكثر من قابلية الصيانة.
احتفظ بالإعدادات التي تختلف بين جهاز وآخر خارج الكود، ولا تضع كلمات مرور أو مفاتيح خاصة في المستودع. استخدم سجلات مناسبة أثناء التطوير، ثم راجع ما ينبغي حجبه في بيئة التشغيل. إذا تعامل البرنامج مع بيانات المستخدم، فافصل بين ما يحتاجه التطبيق وما يمكن الاحتفاظ به. هذه الممارسات لا تخص لغة واحدة، بل تقلل المشكلات عندما يكبر المشروع أو يعمل عليه أكثر من شخص.
متى تعرف أن الحل يحتاج إلى تطوير؟
يحتاج المثال التعليمي إلى طبقات إضافية عندما يدخل في نظام حقيقي: قاعدة بيانات، مستخدمون متعددون، مراقبة، اختبارات، وصلاحيات. لا تضف هذه الأجزاء قبل معرفة المشكلة التي تحلها، لكن لا تنقل الكود التجريبي إلى الإنتاج كما هو. راقب حجم البيانات، وعدد الطلبات، ومصدر المدخلات، وما إذا كان الفشل يجب أن يعيد العملية أو يوقفها. اكتب قرارك في مستند صغير أو تعليق يشرح السبب، حتى لا يضطر الفريق إلى تخمينه لاحقاً.
إذا وجدت أن الخطأ يتكرر في أكثر من مكان، فابحث عن قاعدة مشتركة. وإذا أصبح التعديل في ملف صغير يؤثر في ملفات كثيرة، فراجع حدود المسؤوليات. لا توجد بنية واحدة صحيحة لكل مشروع، لكن توجد أسئلة تساعدك على اختيار بنية مناسبة: من يملك البيانات؟ من يغيرها؟ ماذا يحدث عند الفشل؟ وكيف يمكن اختبار الجزء من دون تشغيل النظام كله؟
أخطاء ينبغي تجنبها
لا تثق بقيم المتصفح عند الحفظ، فالمستخدم يستطيع إرسال طلب مباشر يتجاوز الواجهة. لا تستخدم innerHTML لعرض قيمة كتبها المستخدم، لأن ذلك قد يفتح باب حقن HTML. من الأخطاء أيضاً تنظيف البريد بطريقة تغيره بلا توضيح، أو رفض كلمة مرور مقبولة بسبب قاعدة غير ضرورية، أو ترك رسالة خطأ قديمة بعد إصلاح الحقل. اجعل التحقق متناسقاً بين العميل والخادم من حيث المعنى، لا من حيث مكان التنفيذ.
خطوة تالية مناسبة
أضف تحققاً فورياً بعد مغادرة الحقل، ثم قارنه بالتحقق عند الإرسال. إذا كان النموذج طويلاً، قسمه إلى خطوات لكن لا تفقد القيم السابقة. يمكن استخدام مكتبة تحقق عندما تكبر القواعد، بشرط فهم ما تفعله ومراجعة حجمها. ابدأ دائماً بالخصائص الأصلية في HTML، فهي تمنحك سلوكاً جيداً حتى عندما لا يعمل JavaScript.
تجربة النموذج مع لوحة المفاتيح
لا تختبر النموذج بالنقر فقط. انتقل بين الحقول باستخدام Tab، وأرسل النموذج بزر Enter، وتأكد من أن رسالة الخطأ مرتبطة بالحقل الذي يسبب المشكلة. يجب ألا تختفي القيمة التي أدخلها المستخدم عند ظهور خطأ في حقل آخر. وإذا كان هناك حقل لكلمة المرور، فاجعل رسالة التحقق واضحة من دون كشف القيمة نفسها في سجل المتصفح. بعد نجاح التحقق في الواجهة، أرسل البيانات إلى الخادم الذي يعيد التحقق مرة أخرى؛ فالتحقق الموجود في JavaScript يساعد المستخدم لكنه لا يمثل حاجزاً أمنياً. هذه الخطوات تجعل النموذج أسهل للاستخدام وأقل عرضة للبيانات الناقصة.
الخلاصة
أضف تحققاً فورياً بعد مغادرة الحقل، ثم قارنه بالتحقق عند الإرسال. إذا كان النموذج طويلاً، قسمه إلى خطوات لكن لا تفقد القيم السابقة. يمكن استخدام مكتبة تحقق عندما تكبر القواعد، بشرط فهم ما تفعله ومراجعة حجمها. ابدأ دائماً بالخصائص الأصلية في HTML، فهي تمنحك سلوكاً جيداً حتى عندما لا يعمل JavaScript. يوضح هذا الموضوع كيف يتحول مفهوم نظري إلى خطوات يمكن تشغيلها وفحصها.
ابدأ بتطبيق المثال على ملف صغير، ثم غيّر مدخلاً واحداً وراقب النتيجة. بعد ذلك أضف حالة فشل واكتب اختباراً لها، ثم انقل الفكرة إلى مشروعك الحقيقي بحذر. عندما تفهم سبب كل خطوة، ستستطيع تغيير الأدوات أو اللغة من دون فقدان المفهوم. البرمجة تتحسن بالمحاولات القصيرة والمراجعة المستمرة، لا بنسخ كود طويل من دون معرفة ما الذي يحميه أو ما الذي قد يكسره.