الفرق بين المراجعتين لصفحة: «Next.js/building forms»
جميل-بيلوني (نقاش | مساهمات) ط مراجعة |
جميل-بيلوني (نقاش | مساهمات) ط نقل جميل-بيلوني صفحة Next.js/guides إلى Next.js/building forms دون ترك تحويلة |
(لا فرق)
|
مراجعة 17:10، 3 يناير 2023
يرتبط نموذج الويب web form بطرفي العميل والخادم، ويُستخدم لإرسال البيانات التي تعامل معها خادم ويب للمعالجة والتخزين. يُعدّ النموذج نفسه عميلًا، بينما تُعدّ آلية التخزين التي تستخدم لحفظ واستعادة وإرسال البيانات عند الحاجة هي الخادم.
سيساعدك هذا الدليل في تعلّم كيفية إنشاء نموذج ويب باستخدام Next.js.
القسم الأول: نموذج HTML
يُبنى نموذج HTML باستخدام العنصر <form>
الذي يأخذ مجموعة من السمات والحقول لهيكلة النموذج من خلال الحقول النصية وصناديق التحقق والقوائم المنسدلة والأزرار وغيرها.
إليك مثالًا عن صياغة نموذج HTML:
<!-- Basic HTML Form -->
<form action="/send-data-here" method="post">
<label for="first">First name:</label>
<input type="text" id="first" name="first" />
<label for="last">Last name:</label>
<input type="text" id="last" name="last" />
<button type="submit">Submit</button>
</form>
ستبدو الواجهة الأمامية كالتالي:
يسلك العنصر <form>
سلوك الحاوية التي تضم مختلف عناصر الدخل <input>
مثل الحقول النصية text
وأزرار الإرسال button
، وسندرس كل عنصر على حدى من هذه العناصر مع سماتها.
action
: وهي سمة تحدد وجهة بيانات النموذج عندما يُرسل، وقيمتها عادة عنوان URL (مطلق أو نسبي).method
: يحدد نوع طلب HTTP (GET
أوPOST
) المستخدم في إرسال بيانات النموذج.<label>
: عنصر يحدد عنوان عناصر أخرى، ويدعم شمولية أو سهولة الوصول accessibility وخاصةً الوصول من خلال قارئات الشاشة.<input>
: وهو العنصر الأكثر استخدامًا في هيكلة النماذج لتشكيل حقول البيانات. يعتمد هذه العنصر بشدة على قيمة السمةtype
التي يمكن أن تكون نصtext
أو صندوق تحققcheckbox
أو بريد إلكترونيemail
أو أزرار خياراتradio
وغيرها.<button>
: وتمثل الأزرار القابلة للنقر التي تستخدم في إرسال البيانات.
التحقق من النموذج Form Validation
وهي العملية التي نتحقق فيها من صحة المعلومات التي أدخلها المستخدم وصحة تنسيقها كوجود المحرف @ مثلًا في عنوان البريد الإلكتروني الذي يدخله. ويكون التحقق وفق نمطين:
- التحقق من جانب العميل: ويجري التحقق من صحة المعلومات في المتصفح.
- التحقق من جانب الخادم: ويجري التحقق من صحة المعلومات في الخادم.
ولهذين النمطين نفس الأهمية، لكننا سنركز في هذا الدليل على التحقق من جانب العميل فقط.
يُصنّف التحقق من جانب العميل ضمن فئات عدة أيضًا مثل:
- مُدمج Built-in: يستخدم سمات HTML مثل
required
وtype
وminLength
وmaxLength
وpattern
وغيرها. - مبني على JavaScript: يجري التحقق باستخدام شيفرة JavaScript.
التحقق المدمج من النماذج باستخدام سمات HTML
required
: ويحدد الحقول التي ينبغي ملؤها قبل إرسال النموذج.type
: ويحدد نوع البيانات (عدد، بريد إلكتروني، نص،..).minLength
: ويحدد العدد الأدنى المسموح من المحارف لحقل نصي.maxLength
: ويحدد العدد الأعلى المسموح من المحارف لحقل نصي.
لذلك قد يبدو النموذج الذي يستخدم هذه السمات كالتالي:
!--مع تحقق مدمج HTML نموذج -->
<form action="/send-data-here" method="post">
<label for="roll">Roll Number</label>
<input
type="text"
id="roll"
name="roll"
required
minlength="10"
maxlength="20"
/>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required />
<button type="submit">Submit</button>
</form>
بوجود أساليب التحقق السابقة لن يتمكن المستخدم من إرسال النموذج السابق إن كان حقل اسم المستخدم فارغًا، إذ يعطي خطأً ينبثق من مربع النص مباشرة. ولن يكون رقم الدور مقبولًا ما لم يكن طوله بين 10-20 محرفًا.
التحقق باستخدام شيفرة JavaScript
للتحقق من النماذج أهميته في التأكد من صحة المعلومات التي يرسلها المستخدم وصحة تنسيقها. لهذا بالإمكان الاستفادة من مستويات أعلى من التحقق تقدمها شيفرة JavaScript بالتوازي مع سمات HTML في جانب العميل. يفضّل المطورون عادة التحقق باستخدام JavaScript لأنها تعالج البيانات بسرعة مقارنة بالتحقق الذي يجري من جانب الخادم، علمًا أن عملية التحقق من جانب العميل أقل أمنًا في بعض الحالات نظرًا لقدرة المستخدم المشبوه على إرسال بيانات ضارة إلى الخادم. إليك مثالًا يظهر استخدام JavaScript في التحقق من بيانات نموذج:
<form onsubmit="validateFormWithJS()">
<label for="rollNumber">Roll Number:</label>
<input type="text" name="rollNumber" id="rollNumber" />
<label for="name">Name:</label>
<input type="text" name="name" id="name" />
<button type="submit">Submit</button>
</form>
<script>
function validateFormWithJS() {
const name = document.querySelector('#name').value
const rollNumber = document.querySelector('#rollNumber').value
if (!name) {
alert('Please enter your name.')
return false
}
if (rollNumber.length < 3) {
alert('Roll Number should be at least 3 digits long.')
return false
}
}
</script>
يُستخدم العنصر <script>
لإدراج شيفرة JavaScript من جانب العميل. وقد يضم العنصر شيفرة سطرية كما في المثال السابق، أو قد يشير إلى ملف سيفرة خارجي من خلال السمة src
. يتحقق المثال الذي عرضناه سابقًا من الاسم ورقم الدور لمستخدم، إذ لا تسمح الدالة ()validateFormWithJS
بإرسال النموذج إن كان حقل الاسم فارغًا أو كان الدور أقل من ثلاث خانات. يجري التحقق من النموذج عند النقر على زر الإرسال Submit، ولن تنتقل إلى الصفحة التي ما لم تكن القيم التي يقدمها المستخدمة صالحة.
التحقق من النماذج باستخدام التعابير النمطية
تُستخدم التعابير النمطية Regular Expressions في JavaScript للتحقق من صحة بيانات النماذج، ولا بد حينها من استخدام السمة pattern
. والتعبير النمطي الذي يُعرف اختصارًا بالشكل RegEx هو كائن يصف نمطًا محددًا من المحارف. تُطبق السمة pattern
على العنصر <input>
فقط، وبالتالي تستطيع التحقق من قيمة هذا العنصر بتعريف تعبير نمطي يُشكِّل قاعدة تحقق خاصة بك. فإن لم تتطابق القيمة التي يدخلها المستخدم مع التعبير النمطي سيعطي عنصر الدخل رسالة خطأ.
يظهر المثال التالي استخدام السمة pattern
مع عنصر دخل:
<form action="/action_page.php">
<label for="pswrd">Password:</label>
<input
type="password"
id="pswrd"
name="pswrd"
pattern="[a-z0-9]{1,15}"
title="Password should be digits (0 to 9) or alphabets (a to z)."
/>
<button type="submit">Submit</button>
</form>
ينبغي أن تضم كلمة السر أرقامًا من 0 إلى 9 وأحرفًا صغيرة من a إلى z ولا تزيد عدد المحارف عن 15 محرفًا. لا يُسمح أيضًا بمحارف أخرى مثل (# أو $ أو & أو غيرها). وهكذا سيكون التعبير النمطي الذي يحقق القواعد السابقة هو: {1,15}[a-z0-9]
.
للمزيد من التفاصيل حول التعابير النمطية، ارجع إلى مقال التعابير النمطية Regular Expressions في جافاسكريبت.
القسم الثاني: إعداد المشروع
سننشئ في هذا القسم نماذج React باستخدام Next.js.
أنشئ تطبيق جديد باستخدام create-next-app مثلًا وذلك بتنفيذ الأمر التالي في الطرفية:
npx create-next-app
أجب عن الأسئلة التي يطرحها معالج إنشاء التطبيق وامنح المشروع اسمًا. انتقل إلى جذر مجلد مشروعك الجديد ثم نفّذ أحد الأمرين npm run dev
أو yarn dev
لتبدأ خادم التطوير.
افتح عنوان URL الذي يظهر على الطرفية للتأكد من صحة عمل تطبيقك.
القسم الثالث: إعداد مسار API الخاص بنموذج Next.js
سنبني الواجهتين الأمامية والخلفية باستخدام Next.js. أنشئ لهذه الغاية وصلة API على الخادم لإرسال البيانات إليها. تُزوّدك Next.js بنظام توجيه يعتمد على الملفات مبني على مبدأ الصفحات. إذ يُربط كل ملف ضمن المجلد pages/api
بالمسار */api/
ويُعامل كوصلة API (نقطة اتصال مع الواجهة البرمجية) بدلًا من كونه صفحة page
.
انتقل إلى المجلّد pages/api
ثم أنشئ ملفًا باسم form.js
وانسخ إليه هذه الشيفرة المكتوبة بلغة Node.js:
export default function handler(req, res) {
// أرسل البيانات في جسم الطلب
const body = req.body
// تعليمات اختيارية لإظهار وضع الاستجابة
// في سطر الأوامر عند تشغيل التطبيق
console.log('body: ', body)
// التحقق من أول وآخر اسم
// والعودة مباشرة إن لم يُعثر على شيء
if (!body.first || !body.last) {
// أرسل رمز حالة الخطأ
return res.status(400).json({ data: 'First or last name not found' })
}
// الاسم موجود
// أرسل رمز حالة النجاح
res.status(200).json({ data: `${body.first} ${body.last}` })
}
تتلقى الدالة handler
الطلب req
من العميل (بيانات النموذج المُرسلة) وترسل الاستجابة res
بتنسيق JSON تضم الاسم الأول والأخير. بإمكانك الوصول إلى وصلة API هذه من خلال العنوان http://localhost:3000/api/form
، واستبدل عنوان الخادم المحلي بعنوان Vercel الفعلي مثلًا إن شئت ذلك في مرحلة النشر.
ملاحظة: بإمكانك أيضًا ربط قاعدة بيانات MongoDB أو جداول Google بوصلة API هذه لكي تخزّن البيانات التي يرسلها النموذج بأمان لاستخدامات أخرى. لا نستخدم قاعدة بيانات في هذا الدليل بل نعيد نفس البيانات المُرسلة لشرح ما يجري فقط.
إرسال بيانات النموذج دون استخدام JavaScript
بإمكانك الآن أن تستخدم الوصلة النسبية api/form/
ضمن السمة action
للنموذج. تُرسل البيانات إلى الخادم من خلال طلب HTTP من نوع POST:
<form action="/api/form" method="post">
<label for="first">First name:</label>
<input type="text" id="first" name="first" />
<label for="last">Last name:</label>
<input type="text" id="last" name="last" />
<button type="submit">Submit</button>
</form>
عندما ترسل هذا النموذج، ستُرسل البيانات إلى وصلة API الخاصة بالنماذج api/form/
، ثم يستجيب الخادم الذي يعالج عادة تلك البيانات، ويحمّل عنوان URL المحدد بواسطة السمة action
، مسببًا تحميل صفحة جديدة. ستنتقل في مثالنا إلى الوجهة http://localhost:3000/api/form
وستكون استجابة الخادم كالتالي:
القسم الرابع: تهيئة النماذج في Next.js
أنشأنا في القسم السابق مسار API لإرسال النماذج، وقد حان الوقت الآن لتهيئة العميل (النموذج نفسه) ضمن Next.js باستخدام React. ستكون خطوتنا الأولى توسيع معرفتك بنماذج HTML وتحويلها إلى React (باستخدام JSX).
إليك نفس النموذج لكن على شكل مكوّن React كُتب باستخدام JSX:
export default function Form() {
return (
<form action="/api/form" method="post">
<label htmlFor="first">First Name</label>
<input type="text" id="first" name="first" required />
<label htmlFor="last">Last Name</label>
<input type="text" id="last" name="last" required />
<button type="submit">Submit</button>
</form>
)
}
إليك ما تغيّر:
- تحوّلت السمة
for
إلىhtmlFor
(كونها كلمة مرتبطة بحلقة "for" في JavaScript). - للسمة
action
الآن عنوان URL نسبي وهو وصلة API الخاصة بالنموذج.
وهكذا تكون الهيكيلية الأساسية لنموذج Next.js قد اكتملت.
يمكنك الاطلاع على كامل المشروع والشيفرة المصدرية في المستودع المخصص على GitHub
القسم الخامس: إرسال بيانات النموذج دون JavaScript
تزيد JavaScript من تفاعلية تطبيقات الويب، إلا أنه من الضروري أحيانًا التحكم بتجميعاتها حتى لا تصبح ضخمة ويُضطر زوار الموقع إلى تعطيلها. إليك بعض الأسباب التي يُعطّل فيها الزوار JavaScript:
- لحل مشكلة حزمة الاستهلاك المحدودة.
- زيادة عمر بطارية الجهاز (هاتف أو حاسوب محمول).
- لأسباب تتعلق بالخصوصية، فقد لا يرغب المستخدم أن يُلاحق من قبل سكربتات التحليل.
وبغض النظر عن الأسباب، سينعكس تعطيل شيفرة JavaScript سلبًا على عمل الموقع إن لم يعطله كليًا.
سنفتح الآن المجلد next-forms
ضمن المجلد pages/
وسننشئ الملف no-js-form.js
.
تلميح سريع: الصفحة في Next.js هي مكوّن React مُصدَّر عن ملفات موجودة في المجلد
pages
وتمتلك إحدى الامتدادات التالية:js.
أوjsx.
أوts.
أوtsx.
. تقترن كل صفحة بمسار يتعلق باسم الملف، فلو أنشأت على سبيل المثال الملفpages/no-js-form.js
، ستتمكن من الوصول إليه من خلال العنوانyour-domain.tld/no-js-form
.
لنستخدم نفس الشيفرة السابقة:
export default function PageWithoutJSbasedForm() {
return (
<form action="/api/form" method="post">
<label htmlFor="first">First Name</label>
<input type="text" id="first" name="first" required />
<label htmlFor="last">Last Name</label>
<input type="text" id="last" name="last" required />
<button type="submit">Submit</button>
</form>
)
}
عندما تنقر على زر الإرسال وتكون شيفرة JavaScript معطّلة، سيؤدي ذلك إلى وقوع حدث النقر ويسبب تجميع بيانات النموذج وإرسالها إلى الوصلة المحددة في السمة action
عبر طلب HTTP POST. سيُعاد توجيهك بعد ذلك إلى الوصلة api/form/
، فهكذا تعمل السمة action
في النماذج.
تُرسل البيانات إلى الخادم كطلب req
إلى الدالة التي كتبناها سابقًا. ستعالج هذه الدالة البيانات وتعيد نصًا بتنسيق JSON كاستجابة res
تضم الاسم الذي أرسلته.
تلميح: لتحسين تجربة المستخدم، يمكنك توجيهه إلى صفحة أخرى تحمل عبارة شكر له لتعبئة النموذج وإرساله.
القسم السادس: إرسال النماذج في حال تفعيل JavaScript
أنشئ في المجلد pages/
ملفًا جديدًا باسم js-form.js
والذي سينشئ بدوره الصفحة js-form/
في تطبيق Next.js.
حالما يُرسل النموذج، سنمنع السلوك الافتراضي له الذي يؤدي إلى إعادة تحميل الصفحة. سنأخذ بيانات النموذج ونحولها إلى نص بتنسيق JSON ثم نرسلها إلى الخادم (تمثله وصلة API في حالتنا). يستجيب الخادم أخيرًا معيدًا نفس الاسم الذي أُرسل إليه. يجري كل ذلك من خلال دالة JavaScript بسيطة هي ()handleSubmit
.
إليك الطريقة التي قد تُكتب بها هذه الدالة، وقد وثّقناها خطوة خطوة لفهم الأمر:
export default function PageWithJSbasedForm() {
// يتعامل مع حدث إرسال النموذج
const handleSubmit = async (event) => {
// يمنع النموذج من إعادة تحديث الصفحة بعد الإرسال
event.preventDefault()
// الحصول على بيانات النموذج
const data = {
first: event.target.first.value,
last: event.target.last.value,
}
// JSON إرسال البيانات إلى الخادم بصيغة
const JSONdata = JSON.stringify(data)
//التي نرسل البيانات إليها API وصلة
const endpoint = '/api/form'
// تشكيل الطلب الذي يرسل البيانات إلى الخادم
const options = {
// POST إرسال البيانات بطلب من النوع
method: 'POST',
// JSON إبلاغ الخادم بإرسال بيانات بتنسيق
headers: {
'Content-Type': 'application/json',
},
//التي أنشأناها سابقًا JSON جسم الطلب هو بيانات
body: JSONdata,
}
// Vercel على API إرسال بيانات النموذج إلى وصلة
const response = await fetch(endpoint, options)
// JSON الحصول على البيانات من الخادم بتنسيق
// إن أعاد الخادم الاسم الذي أرسل فالنموذج يعمل بشكل صحيح
const result = await response.json()
alert(`Is this your full name: ${result.data}`)
}
return (
// عند الإرسال handleSubmit() تمرير الحدث إلى الدالة
<form onSubmit={handleSubmit}>
<label htmlFor="first">First Name</label>
<input type="text" id="first" name="first" required />
<label htmlFor="last">Last Name</label>
<input type="text" id="last" name="last" required />
<button type="submit">Submit</button>
</form>
)
}
تمثل الشيفرة السابقة صفحة بمكوّن دوال React يُدعى PageWithJSbasedForm
مع عنصر نموذج <form>
مكتوب بلغة JSX. لا يمتلك النموذج السمة action
، بل نستخدم معالج الحدث onSubmit
لإرسال البيانات إلى الدالة {handleSubmit}
.
تعالج الدالة ()handleSubmit
البيانات عبر سلسلة من الخطوات:
- تمنع الدالة
()event.preventDefault
النموذج من تحديث كامل الصفحة. - أنشانا كائن JavaScript يُدعى
data
يحمل القيمتينfirst
وlast
من النموذج. - استخدمنا التعليمة
JSON.stringify(data)
لتحويل البيانات إلى تنسيق JSON. - استخدمنا الدالة
()fetch
لإرسال البيانات إلى الوصلةapi/form/
باستخدام JSON وطلب HTTP من نوع POST. - يستجيب الخادم بإعادة الاسم الذي أرسلناه.
خلاصة
غطينا في هذا الدليل ما يلي:
- عنصر نموذج HTML الأساسي
<form>
. - فهم نماذج React.js.
- التحقق من بيانات النماذج باستخدام وبلا استخدام JavaScript.
- استخدام مسار API في للتعامل مع الطلب
req
والاستجابةres
بين العميل والخادم.
المصادر
- الصفحة Building Forms with Next.js من توثيق Next.js الرسمي.