الفرق بين المراجعتين لصفحة: «HTML/input/datetime-local»
ط استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}' |
ط ←ضبط المنطقة الزمنية: إزالة رابط datetime |
||
(2 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة) | |||
سطر 3: | سطر 3: | ||
شكل هذا الحقل يختلف من متصفح إلى متصفح، فالدعم الحالي ليس مثاليًا، فالوضع الحالي لهذا الحقل في متصفحات Chrome و Opera و Edge ومتصفحات الهواتف المحمولة لا بأس به، وسيُعرَض كحقل نصي في المتصفحات التي لا تدعمه:<syntaxhighlight lang="html"> | شكل هذا الحقل يختلف من متصفح إلى متصفح، فالدعم الحالي ليس مثاليًا، فالوضع الحالي لهذا الحقل في متصفحات Chrome و Opera و Edge ومتصفحات الهواتف المحمولة لا بأس به، وسيُعرَض كحقل نصي في المتصفحات التي لا تدعمه:<syntaxhighlight lang="html"> | ||
<input | <input type="datetime-local" name="datetime"> | ||
</syntaxhighlight>سيبدو هذا الحقل كما في الصورة الآتية في متصفحَي Chrome و Opera، الضغط على السهم سيؤدي إلى إظهار نافذة منتقي التاريخ، وعلى المستخدم إدخال الوقت يدويًا: | </syntaxhighlight>سيبدو هذا الحقل كما في الصورة الآتية في متصفحَي Chrome و Opera، الضغط على السهم سيؤدي إلى إظهار نافذة منتقي التاريخ، وعلى المستخدم إدخال الوقت يدويًا: | ||
سطر 13: | سطر 13: | ||
== الخاصية <code>value</code> == | == الخاصية <code>value</code> == | ||
تحتوي الخاصية <code>value</code> على سلسلة نصية (<code>DOMString</code>)، التي تُمثِّل قيمة التاريخ المُدخَل في هذا الحقل، ويمكن وضع قيمة افتراضية للتاريخ داخل حقل <code>date</code> باستخدام الخاصية <code>value</code>، كما في المثال الآتي:<syntaxhighlight lang="html"> | تحتوي الخاصية <code>value</code> على سلسلة نصية (<code>DOMString</code>)، التي تُمثِّل قيمة التاريخ المُدخَل في هذا الحقل، ويمكن وضع قيمة افتراضية للتاريخ داخل حقل <code>date</code> باستخدام الخاصية <code>value</code>، كما في المثال الآتي:<syntaxhighlight lang="html"> | ||
<label for=" | <label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة:</label> | ||
<input id=" | <input id="travel" type="datetime-local" name="travel" value="2018-06-01T08:30"> | ||
</syntaxhighlight>يجدر بالذكر أنَّ التاريخ المعروض قد يختلف عن قيمة الخاصية <code>value</code>، فصيغة التاريخ المعروض في الحقل تعتمد على محلية (locale) نظام تشغيل المستخدم، بينما قيمة القيمة <code>value</code> تكون على الشكل <code>yyyy-mm-ddThh:mm</code> دومًا. فعند إرسال الحقل السابق إلى الخادوم فسيكون مثلًا <code>partydate= | </syntaxhighlight>يجدر بالذكر أنَّ التاريخ المعروض قد يختلف عن قيمة الخاصية <code>value</code>، فصيغة التاريخ المعروض في الحقل تعتمد على محلية (locale) نظام تشغيل المستخدم، بينما قيمة القيمة <code>value</code> تكون على الشكل <code>yyyy-mm-ddThh:mm</code> دومًا. فعند إرسال الحقل السابق إلى الخادوم فسيكون مثلًا <code>partydate=2018-06-01T08:30</code>. | ||
أبقِ في ذهنك أنَّه إذا كانت البيانات ستُرسَل عبر GET، فيجب ترميز محرف النقطتين الرأسيتين <code>:</code> لكي يوضع في رابط URL، مثلًا: <code>partydate= | أبقِ في ذهنك أنَّه إذا كانت البيانات ستُرسَل عبر GET، فيجب ترميز محرف النقطتين الرأسيتين <code>:</code> لكي يوضع في رابط URL، مثلًا: <code>partydate=2018-06-01T08%3A30</code>. | ||
يمكنك أيضًا الحصول على قيمة الخاصية <code>value</code> وضبطها عبر JavaScript باستخدام الخاصية <code>HTMLInputElement.value</code>، مثال:<syntaxhighlight lang="javascript"> | يمكنك أيضًا الحصول على قيمة الخاصية <code>value</code> وضبطها عبر JavaScript باستخدام الخاصية <code>HTMLInputElement.value</code>، مثال:<syntaxhighlight lang="javascript"> | ||
var dateControl = document.querySelector('input[type=" | var dateControl = document.querySelector('input[type="datetime-local"]'); | ||
dateControl.value = ' | dateControl.value = '2018-06-01T08:30'; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
سطر 34: | سطر 34: | ||
أبسط استخدام للحقل <code>datetime-local</code> يتضمن عنصر <code>[[HTML/input|<input>]]</code> وعنصر <code>[[HTML/label|<label>]]</code> كما هو موضَّح في المثال الآتي:<syntaxhighlight lang="html"> | أبسط استخدام للحقل <code>datetime-local</code> يتضمن عنصر <code>[[HTML/input|<input>]]</code> وعنصر <code>[[HTML/label|<label>]]</code> كما هو موضَّح في المثال الآتي:<syntaxhighlight lang="html"> | ||
<form> | <form> | ||
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة:</label> | |||
<input id="travel" type="datetime-local" name="travel"> | |||
</form> | </form> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== ضبط أقل وأكبر تاريخ يمكن اختياره === | === ضبط أقل وأكبر تاريخ يمكن اختياره === | ||
يمكننا استخدام الخاصيتين <code>min</code> و <code>max</code> لوضع حدود للتواريخ والوقت التي يستطيع المستخدم اختيارها، ففي المثال الآتي سنضبط أدنى تاريخ إلى <code> | يمكننا استخدام الخاصيتين <code>min</code> و <code>max</code> لوضع حدود للتواريخ والوقت التي يستطيع المستخدم اختيارها، ففي المثال الآتي سنضبط أدنى تاريخ إلى <code>2018-06-01T08:30</code> وأقصى تاريخ إلى <code>2018-06-30T16:30</code>:<syntaxhighlight lang="javascript"> | ||
<form> | |||
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة:</label> | |||
<input id="travel" type="datetime-local" name="travel" min="2018-06-01T08:30" max="2018-06-30T16:30"> | |||
</form> | |||
</syntaxhighlight>لاحظ أنَّ بإمكانك اختيار الأيام الموجودة في شهر حزيران/يونيو فقط، إذ إنَّ قسم «الأيام» في الحقل سيكون قابلًا للتعديل فقط، ولا يمكن التمرير إلى أشهر أخرى عدا شهر حزيران/يونيو. | </syntaxhighlight>لاحظ أنَّ بإمكانك اختيار الأيام الموجودة في شهر حزيران/يونيو فقط، إذ إنَّ قسم «الأيام» في الحقل سيكون قابلًا للتعديل فقط، ولا يمكن التمرير إلى أشهر أخرى عدا شهر حزيران/يونيو. | ||
سطر 54: | سطر 54: | ||
=== ضبط المنطقة الزمنية === | === ضبط المنطقة الزمنية === | ||
لا يوفِّر الحقل <code>datetime-local</code> طريقةً لضبط المنطقة الزمنية، وهذا متوافر في حقل <code> | لا يوفِّر الحقل <code>datetime-local</code> طريقةً لضبط المنطقة الزمنية، وهذا متوافر في حقل <code>datetime</code> لكن هذا الحقل أصبح مهملًا وحُذِف من المواصفة، والسبب الرئيسي لحذفه هو عدم وجود تطبيق له في المتصفحات، إضافةً إلى موضوع كيفية تمثيله رسوميًا للمستخدم، فمن الأسهل توفير حقل (أو حقول) لإدخال الوقت والتاريخ ثم التعامل مع المنطقة الزمنية بشكل منفصل. | ||
على سبيل المثال، إذا أنشأنا نظامًا يكون فيه المستخدم مسجلًا دخوله، فيمكننا توفير المنطقة الزمنية في حقل من النوع <code>[[HTML/input/hidden|hidden]]</code>. على سبيل المثال:<syntaxhighlight lang="html"> | على سبيل المثال، إذا أنشأنا نظامًا يكون فيه المستخدم مسجلًا دخوله، فيمكننا توفير المنطقة الزمنية في حقل من النوع <code>[[HTML/input/hidden|hidden]]</code>. على سبيل المثال:<syntaxhighlight lang="html"> | ||
سطر 82: | سطر 82: | ||
ضبطنا في المثال الآتي أقل وأكبر تاريخ يمكن للمستخدم اختياره إضافةً إلى جعل الحقل إجباريًا:<syntaxhighlight lang="html"> | ضبطنا في المثال الآتي أقل وأكبر تاريخ يمكن للمستخدم اختياره إضافةً إلى جعل الحقل إجباريًا:<syntaxhighlight lang="html"> | ||
<form> | <form> | ||
<div> | |||
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة (مطلوب, من الأول من حزيران 8.30 ص حتى 30 حزيران 4.30 م):</label> | |||
<input id="travel" type="datetime-local" name="travel" min="2018-06-01T08:30" max="2018-06-30T16:30" required> | |||
</div> | |||
<div> | |||
<input type="submit" value="حجز"> | |||
</div> | |||
</form> | </form> | ||
</syntaxhighlight>إذا حاولت إرسال النموذج دون إكمال التاريخ (أو اخترتَ تاريخًا خارج الحدود المسموحة) فسيعرض المتصفح رسالة خطأ. | </syntaxhighlight>إذا حاولت إرسال النموذج دون إكمال التاريخ (أو اخترتَ تاريخًا خارج الحدود المسموحة) فسيعرض المتصفح رسالة خطأ. | ||
سطر 113: | سطر 112: | ||
<form> | <form> | ||
<div> | <div> | ||
<label for=" | <label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة (مطلوب, من الأول من حزيران 8.30 ص حتى 30 حزيران 4.30 م):</label> | ||
<input id=" | <input id="travel" type="datetime-local" name="travel" | ||
min="2018-06-01T08:30" max="2018-06-30T16:30" | |||
pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}" required> | |||
</div> | </div> | ||
<div> | <div> | ||
<input type="submit" value=" | <input type="submit" value="حجز"> | ||
</div> | </div> | ||
<input type="hidden" id="timezone" name="timezone" value="-08:00"> | <input type="hidden" id="timezone" name="timezone" value="-08:00"> | ||
سطر 135: | سطر 133: | ||
<form> | <form> | ||
<div class="nativeDateTimePicker"> | <div class="nativeDateTimePicker"> | ||
<label for=" | <label for="travel">أدخل التاريخ والوقت لحجز بطاقة الطائرة:</label> | ||
<input type="datetime-local" id=" | <input type="datetime-local" id="travel" name="travel"> | ||
<span class="validity"></span> | <span class="validity"></span> | ||
</div> | </div> | ||
<p class="fallbackLabel"> | <p class="fallbackLabel">أدخل التاريخ والوقت لحجز بطاقة الطائرة:</p> | ||
<div class="fallbackDateTimePicker"> | <div class="fallbackDateTimePicker"> | ||
<div> | <div> | ||
<span> | <span> | ||
<label for="day"> | <label for="day">اليوم:</label> | ||
<select id="day" name="day"> | <select id="day" name="day"> | ||
</select> | </select> | ||
</span> | </span> | ||
<span> | <span> | ||
<label for="month"> | <label for="month">الشهر:</label> | ||
<select id="month" name="month"> | <select id="month" name="month"> | ||
<option selected>January</option> | <option selected>January</option> | ||
سطر 165: | سطر 163: | ||
</span> | </span> | ||
<span> | <span> | ||
<label for="year"> | <label for="year">السنة:</label> | ||
<select id="year" name="year"> | <select id="year" name="year"> | ||
</select> | </select> | ||
سطر 172: | سطر 170: | ||
<div> | <div> | ||
<span> | <span> | ||
<label for="hour"> | <label for="hour">الساعة:</label> | ||
<select id="hour" name="hour"> | <select id="hour" name="hour"> | ||
</select> | </select> | ||
</span> | </span> | ||
<span> | <span> | ||
<label for="minute"> | <label for="minute">الدقيقة:</label> | ||
<select id="minute" name="minute"> | <select id="minute" name="minute"> | ||
</select> | </select> |
المراجعة الحالية بتاريخ 09:41، 28 فبراير 2018
عناصر <input>
ذات النوع date
تُنشِئ حقل إدخال يسمح بانتقاء التاريخ والوقت بسهولة، والتاريخ يتضمن السنة والشهر واليوم والساعات والدقائق.
شكل هذا الحقل يختلف من متصفح إلى متصفح، فالدعم الحالي ليس مثاليًا، فالوضع الحالي لهذا الحقل في متصفحات Chrome و Opera و Edge ومتصفحات الهواتف المحمولة لا بأس به، وسيُعرَض كحقل نصي في المتصفحات التي لا تدعمه:
<input type="datetime-local" name="datetime">
سيبدو هذا الحقل كما في الصورة الآتية في متصفحَي Chrome و Opera، الضغط على السهم سيؤدي إلى إظهار نافذة منتقي التاريخ، وعلى المستخدم إدخال الوقت يدويًا:
أما في متصفح Edge فسيبدو الحقل كما يلي:
الخاصية value
تحتوي الخاصية value
على سلسلة نصية (DOMString
)، التي تُمثِّل قيمة التاريخ المُدخَل في هذا الحقل، ويمكن وضع قيمة افتراضية للتاريخ داخل حقل date
باستخدام الخاصية value
، كما في المثال الآتي:
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة:</label>
<input id="travel" type="datetime-local" name="travel" value="2018-06-01T08:30">
يجدر بالذكر أنَّ التاريخ المعروض قد يختلف عن قيمة الخاصية value
، فصيغة التاريخ المعروض في الحقل تعتمد على محلية (locale) نظام تشغيل المستخدم، بينما قيمة القيمة value
تكون على الشكل yyyy-mm-ddThh:mm
دومًا. فعند إرسال الحقل السابق إلى الخادوم فسيكون مثلًا partydate=2018-06-01T08:30
.
أبقِ في ذهنك أنَّه إذا كانت البيانات ستُرسَل عبر GET، فيجب ترميز محرف النقطتين الرأسيتين :
لكي يوضع في رابط URL، مثلًا: partydate=2018-06-01T08%3A30
.
يمكنك أيضًا الحصول على قيمة الخاصية value
وضبطها عبر JavaScript باستخدام الخاصية HTMLInputElement.value
، مثال:
var dateControl = document.querySelector('input[type="datetime-local"]');
dateControl.value = '2018-06-01T08:30';
استخدام حقول اختيار التاريخ والوقت
قد تظن من الوهلة الأولى أنَّ استخدام حقل اختيار التاريخ والوقت هو أمرٌ بسيط، فتلك الحقول توفِّر واجهة مستخدم سهلة الاستخدام لاختيار التواريخ، وتساهم في توحيد المدخلات التي تُرسَل إلى الخادوم، بعض النظر عن محلية المستخدم. لكن هنالك مشاكل مع الحقل localdate-time
بسبب قلّة دعم المتصفحات له.
سنلقي نظرةً بادئ الأمر على أمثلة بسيطة ثم أمثلة معقدة عن الحقل datetime-local
، ثم سنُقدِّم نصيحة عن كيفية التعامل مع المتصفحات غير الداعمة لهذا الحقل.
الاستخدام الأساسي لحقل اختيار التاريخ
أبسط استخدام للحقل datetime-local
يتضمن عنصر <input>
وعنصر <label>
كما هو موضَّح في المثال الآتي:
<form>
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة:</label>
<input id="travel" type="datetime-local" name="travel">
</form>
ضبط أقل وأكبر تاريخ يمكن اختياره
يمكننا استخدام الخاصيتين min
و max
لوضع حدود للتواريخ والوقت التي يستطيع المستخدم اختيارها، ففي المثال الآتي سنضبط أدنى تاريخ إلى 2018-06-01T08:30
وأقصى تاريخ إلى 2018-06-30T16:30
:
<form>
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة:</label>
<input id="travel" type="datetime-local" name="travel" min="2018-06-01T08:30" max="2018-06-30T16:30">
</form>
لاحظ أنَّ بإمكانك اختيار الأيام الموجودة في شهر حزيران/يونيو فقط، إذ إنَّ قسم «الأيام» في الحقل سيكون قابلًا للتعديل فقط، ولا يمكن التمرير إلى أشهر أخرى عدا شهر حزيران/يونيو.
واعتمادًا على المتصفح الذي تستعملها، فيحتمل ألّا تتمكن من اختيار قيم خارج مجال الوقت المسموح (كما في متصفح Edge)، أو يمكنك أن تختارها لكن قيمة الحقل لن تكون صالحة (انظر قسم «التحقق من الحقل») (كما في متصفح Chrome).
ملاحظة: يفترض أنَّ بإمكاننا استخدام الخاصية step
لتحديد الفاصل بين الأيام التي يُسمَح باختيارها (فربما تريد السماح للمستخدم باختيار أيام الجمعة فقط)، لكن هذا لا يعمل بكفاءة في أيّ متصفح في وقت كتابة هذه الصفحة.
التحكم بحجم الحقل
لا يدعم الحقل datetime-local
خاصيات التحكم بالحجم مثل size
، لذا عليك استخدام CSS لهذا الغرض.
ضبط المنطقة الزمنية
لا يوفِّر الحقل datetime-local
طريقةً لضبط المنطقة الزمنية، وهذا متوافر في حقل datetime
لكن هذا الحقل أصبح مهملًا وحُذِف من المواصفة، والسبب الرئيسي لحذفه هو عدم وجود تطبيق له في المتصفحات، إضافةً إلى موضوع كيفية تمثيله رسوميًا للمستخدم، فمن الأسهل توفير حقل (أو حقول) لإدخال الوقت والتاريخ ثم التعامل مع المنطقة الزمنية بشكل منفصل.
على سبيل المثال، إذا أنشأنا نظامًا يكون فيه المستخدم مسجلًا دخوله، فيمكننا توفير المنطقة الزمنية في حقل من النوع hidden
. على سبيل المثال:
<input type="hidden" id="timezone" name="timezone" value="-08:00">
لكن في المقابل، إذا كان من الضروري السماح للمستخدم بإدخال منطقته الزمنية بالإضافة إلى التاريخ والوقت، فيمكنك توفير طريقة لإدخال المنطقة الزمنية، مثل العنصر <select>
:
<select name="timezone_offset" id="timezone-offset" class="span5">
<option value="-12:00">(GMT -12:00) Eniwetok, Kwajalein</option>
<option value="-11:00">(GMT -11:00) Midway Island, Samoa</option>
<option value="-10:00">(GMT -10:00) Hawaii</option>
<option value="-09:50">(GMT -9:30) Taiohae</option>
<option value="-09:00">(GMT -9:00) Alaska</option>
<option value="-08:00">(GMT -8:00) Pacific Time (US & Canada)</option>
...
</select>
وفي كلا الحالتين، يجب أن تُرسَل قيم الوقت والمنطقة الزمنية بشكل منفصل إلى الخادوم، ومن ثم عليك تخزينها كما تشاء في قاعدة البيانات.
التحقق من الحقل
افتراضيًا، لا يوفِّر الحقل datetime-local
أيّ نوع من أنواع التحقق من المدخلات، فالواجهة الرسومية التي توفرها المتصفحات لا تسمح عادةً للمستخدم بإدخال أيّ شيء عدا التواريخ والوقت، لكن يمكن ألّا يختار المستخدم قيمةً لهذا الحقل من الأساس.
إذا كنتَ تستخدم الخاصيتين min
و max
لوضع حدود للتواريخ المسموح بها (انظر قسم «ضبط أقل وأكبر تاريخ ممكن اختياره» أعلاه) فستُظهِر المتصفحات التي تدعم الحقل datetime-local
رسالة خطأ عندما يكون التاريخ المُختار خارج هذه الحدود.
أضف إلى ذلك أنَّ بإمكانك استخدام الخاصية required
لجعل هذا الحقل إجباريًا، وستُعرَض رسالة خطأ إذا حاول المستخدم إرسال النموذج دون تحديد قيمة لهذا الحقل.
ضبطنا في المثال الآتي أقل وأكبر تاريخ يمكن للمستخدم اختياره إضافةً إلى جعل الحقل إجباريًا:
<form>
<div>
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة (مطلوب, من الأول من حزيران 8.30 ص حتى 30 حزيران 4.30 م):</label>
<input id="travel" type="datetime-local" name="travel" min="2018-06-01T08:30" max="2018-06-30T16:30" required>
</div>
<div>
<input type="submit" value="حجز">
</div>
</form>
إذا حاولت إرسال النموذج دون إكمال التاريخ (أو اخترتَ تاريخًا خارج الحدود المسموحة) فسيعرض المتصفح رسالة خطأ.
تحذير مهم: التحقق من مدخلات المستخدم عبر HTML ليس بديلًا عن التأكّد منها من جهة الخادوم، فمن السهل جدًا أن يُعدِّل أحدهم شيفرة HTML لكي يتجاوز آلية التحقق، ومن الممكن أن يتجاوز أحدهم نموذج HTML كليًا ويرسل البيانات إلى الخادوم مباشرةً. فلو لم تكن الشيفرة المشغّلة على خادومك تتحقق من المدخلات التي تستقبلها فمن الممكن أن تحدث كارثة إذا أرسل أحدهم بيانات غير مُنظمة كما يجب (أو بيانات كبيرة أو من نوع خطأ وهلم جرًّا).
التعامل مع دعم المتصفحات
وكما ذكرنا سابقًا، المشكلة الرئيسية مع حقول التاريخ في هذا الوقت هي دعم المتصفحات، فمثلًا يبدو شكل منتقي التاريخ والوقت كما يلي في متصفح Firefox على هواتف أندرويد:
المتصفحات التي لا تدعم هذا الحقل ستحوِّله إلى حقل نصي، لكن هذا يُسبِّب مشاكل في موضوع الواجهة الرسومية (فالتحكم بهذا الحقل سيكون مختلفًا) والتعامل مع البيانات.
المشكلة الثانية أشد وقعًا (كما ذكرنا سابقًا)، فقيمة الحقل datetime-local
تكون موحّدة على الشكل yyyy-mm-ddThh:mm
أما محتوى الحقل النصي لا يُحدِّد صيغةً معيّنةً يجب أن يكون فيها، وهنالك الكثير من الطرائق التي يكتب فيها الناس التاريخ والوقت مثل:
ddmmyyyy
dd/mm/yyyy
mm/dd/yyyy
dd-mm-yyyy
mm-dd-yyyy
mm-dd-yyyy hh:mm
(نظام 12 ساعة)mm-dd-yyyy hh:mm
(نظام 24 ساعة)
إحدى الطرائق لحل هذه الإشكالية هي استخدام الخاصية pattern
على حقل datetime-local
، وحتى لو لم يستعملها الحقل datetime-local
المعروض في المتصفحات الحديثة، لكن الحقل النصي الذي سيظهر في المتصفحات غير الداعمة للحقل datetime-local
سيستعملها.
جرِّب مثلًا عرض المثال الآتي في متصفح غير داعم للحقل datetime-local
:
<form>
<div>
<label for="travel">اختر تاريخ ووقت حجز بطاقة الطائرة (مطلوب, من الأول من حزيران 8.30 ص حتى 30 حزيران 4.30 م):</label>
<input id="travel" type="datetime-local" name="travel"
min="2018-06-01T08:30" max="2018-06-30T16:30"
pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}" required>
</div>
<div>
<input type="submit" value="حجز">
</div>
<input type="hidden" id="timezone" name="timezone" value="-08:00">
</form>
إذا جربتَ إرسال النموذج فستلاحظ أنَّ المتصفح قد عرض رسالة خطأ إذا لم تُطابِق مدخلاتك النمط nnnn-nn-nnTnn:nn
حيث يُمثِّل n
رقمًا من 0 إلى 9. لكن هذا لا يمنع المستخدمين من إدخال تواريخ أو أوقات خطأ.
أفضل طريقة للتعامل مع التواريخ في النماذج مع دعم جميع المتصفحات هي جعل المستخدم يُدخِل اليوم والشهر والتاريخ في حقول منفصلة (يستعمل العنصر <select>
لهذا الغرض)، أو استخدام مكتبة JavaScript مثل jQuery date picker وإضافة jQuery timepicker plugin.
أمثلة
سنُنشِئ مجموعتين من عناصر النماذج لاختيار التاريخ، عنصر <input type="datetime-local">
ومجموعة من ثلاثة عناصر <select>
لاختيار التاريخ في المتصفحات غير الداعمة للحقل datetime-local
.
شيفرة HTML
تبدو شيفرة HTML كما يلي:
<form>
<div class="nativeDateTimePicker">
<label for="travel">أدخل التاريخ والوقت لحجز بطاقة الطائرة:</label>
<input type="datetime-local" id="travel" name="travel">
<span class="validity"></span>
</div>
<p class="fallbackLabel">أدخل التاريخ والوقت لحجز بطاقة الطائرة:</p>
<div class="fallbackDateTimePicker">
<div>
<span>
<label for="day">اليوم:</label>
<select id="day" name="day">
</select>
</span>
<span>
<label for="month">الشهر:</label>
<select id="month" name="month">
<option selected>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
</span>
<span>
<label for="year">السنة:</label>
<select id="year" name="year">
</select>
</span>
</div>
<div>
<span>
<label for="hour">الساعة:</label>
<select id="hour" name="hour">
</select>
</span>
<span>
<label for="minute">الدقيقة:</label>
<select id="minute" name="minute">
</select>
</span>
</div>
</div>
</form>
أسماء الأشهر ثابتة لأنها نفسها دومًا، لكن قيم اليوم والسنة تولّد ديناميكيًا اعتمادًا على الشهر والسنة المُختارَين (راجع التعليقات لتفهم كيف تعمل تلك الدوال). وقررنا توليد الساعات والدقائق ديناميكيًا لوجود عدد كبير من العناصر.
جزء مهم من الشيفرة الذي عليك أن تنتبه له هو كيفية اكتشاف دعم المتصفح لحقل datetime-local
، إذ أنشأنا عنصر <input>
جديد وضبطنا قيمة الخاصية type
إلى datetime-local
ثم تأكدنا مباشرةً من قيمة الخاصية type فالمتصفحات غير الداعمة للحقل datetime-local
ستضبط قيمة الخاصية type
إلى text
، وإذا كان الحقل datetime-local
غير مدعوم فسنخفيه وسنعرض الحقول البديلة (<select>
).
شيفرة JavaScript
// تعريف المتغيرات
var nativePicker = document.querySelector('.nativeDateTimePicker');
var fallbackPicker = document.querySelector('.fallbackDateTimePicker');
var fallbackLabel = document.querySelector('.fallbackLabel');
var yearSelect = document.querySelector('#year');
var monthSelect = document.querySelector('#month');
var daySelect = document.querySelector('#day');
var hourSelect = document.querySelector('#hour');
var minuteSelect = document.querySelector('#minute');
// إخفاء الحقول البديلة افتراضيًا
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';
// اختيار إن كان المتصفح يدعم الحقل أم لا
var test = document.createElement('input');
test.type = 'datetime-local';
// إذا كان لا يدعمه فنفِّذ ما في الدالة الشرطية الآتية
if(test.type === 'text') {
// إخفاء الحقل الأصلي وإظهار الحقل البديل
nativePicker.style.display = 'none';
fallbackPicker.style.display = 'block';
fallbackLabel.style.display = 'block';
// ملء قيم الحقول ديناميكيًا
// (لكن الأشهر ستبقى نفسها)
populateDays(monthSelect.value);
populateYears();
populateHours();
populateMinutes();
}
function populateDays(month) {
// حذف محتويات العنصر select
// لكي تتم تهيئة العنصر للمجموعة الجديدة من القيم
while(daySelect.firstChild){
daySelect.removeChild(daySelect.firstChild);
}
// إنشاء متغير فيه عدد الأيام التي ستُضاف
var dayNum;
// 31 أو 30 يومًا؟
if(month === 'January' | month === 'March' | month === 'May' | month === 'July' | month === 'August' | month === 'October' | month === 'December') {
dayNum = 31;
} else if(month === 'April' | month === 'June' | month === 'September' | month === 'November') {
dayNum = 30;
} else {
// إذا كان الشهر هو شباط/فبراير فلنحسب إن كانت السنة كبيسة
var year = yearSelect.value;
(year - 2016) % 4 === 0 ? dayNum = 29 : dayNum = 28;
}
// إضافة الخيارات إلى عنصر select
for(i = 1; i <= dayNum; i++) {
var option = document.createElement('option');
option.textContent = i;
daySelect.appendChild(option);
}
// إذا تم اختيار اليوم فسنعيد ضبطه لكيلا يعود اليوم إلى 1
// عند تغيير السنة
if(previousDay) {
daySelect.value = previousDay;
// إذا كان اليوم مضبوطًا إلى 31 مثلًا في الشهر القديم
// واختار المستخدم شهرًا فيه عدد أيام أقل مثل شباط/فبراير
// فستحاول الشيفرة الآتية حل هذه الإشكالية
if(daySelect.value === "") {
daySelect.value = previousDay - 1;
}
if(daySelect.value === "") {
daySelect.value = previousDay - 2;
}
if(daySelect.value === "") {
daySelect.value = previousDay - 3;
}
}
}
function populateYears() {
// الحصول على السنة الحالية
var date = new Date();
var year = date.getFullYear();
// إضافة السنة الحالية و100 سنة قبلها إلى عنصر select
for(var i = 0; i <= 100; i++) {
var option = document.createElement('option');
option.textContent = year-i;
yearSelect.appendChild(option);
}
}
function populateHours() {
// إضافة ساعات اليوم كلها (24 ساعة)
for(var i = 0; i <= 23; i++) {
var option = document.createElement('option');
option.textContent = (i < 10) ? ("0" + i) : i;
hourSelect.appendChild(option);
}
}
function populateMinutes() {
// إضافة جميع الدقائق (60 دقيقة)
for(var i = 0; i <= 59; i++) {
var option = document.createElement('option');
option.textContent = (i < 10) ? ("0" + i) : i;
minuteSelect.appendChild(option);
}
}
yearSelect.onchange = function() {
populateDays(monthSelect.value);
}
monthSelect.onchange = function() {
populateDays(monthSelect.value);
}
var previousDay;
daySelect.onchange = function() {
previousDay = daySelect.value;
}
دعم المتصفحات
Chrome | Firefox | Edge | Safari | Opera |
---|---|---|---|---|
20.0 | غير مدعوم | 12 | غير مدعوم | 10.62 |