الحقل month
عناصر <input>
ذات النوع month
تُنشِئ حقل إدخال يسمح بانتقاء السنة والشهر بسهولة.
شكل هذا الحقل يختلف من متصفح إلى متصفح، فالدعم الحالي ليس مثاليًا (راجع قسم دعم المتصفحات لمزيدٍ من المعلومات)، لكن هذا الحقل سيُعرَض كحقل نصي في المتصفحات التي لا تدعمه:
<input id="month" type="month">
سيبدو هذا الحقل كما في الصورة الآتية في متصفحَي Chrome و Opera:
أما في متصفح Edge فسيبدو الحقل كما يلي:
الخاصية value
تحتوي الخاصية value
على سلسلة نصية (DOMString
)، التي تُمثِّل قيمة الشهر والسنة المُدخَل في هذا الحقل، ويمكن وضع قيمة افتراضية للحقل باستخدام الخاصية value
، كما في المثال الآتي:
<label for="bday-month">What month were you both in?</label>
<input id="bday-month" type="month" name="bday-month" value="2017-06">
يجدر بالذكر أنَّ التاريخ المعروض قد يختلف عن قيمة الخاصية value
، فصيغة التاريخ المعروض في الحقل تعتمد على محلية (locale) نظام تشغيل المستخدم، بينما قيمة القيمة value
تكون على الشكل yyyy-mm
دومًا.
قيمة الحقل السابق ستكون على الشكل الآتي عند إرسالها إلى الخادوم bday-month=2017-06
.
يمكنك أيضًا الحصول على قيمة الخاصية value
وضبطها عبر JavaScript باستخدام الخاصية HTMLInputElement.value
، مثال:
var monthControl = document.querySelector('input[type="month"]');
monthControl.value = '2017-06';
استخدام حقول اختيار الشهر
قد تظن من الوهلة الأولى أنَّ استخدام حقل اختيار الشهر هو أمرٌ بسيط، فتلك الحقول توفِّر واجهة مستخدم سهلة الاستخدام لاختيار التواريخ، وتساهم في توحيد المدخلات التي تُرسَل إلى الخادوم، بعض النظر عن محلية المستخدم. لكن هنالك مشاكل مع الحقل month
بسبب قلّة دعم المتصفحات له.
سنلقي نظرةً بادئ الأمر على أمثلة بسيطة ثم أمثلة معقدة عن الحقل month
، ثم سنُقدِّم نصيحة عن كيفية التعامل مع المتصفحات غير الداعمة لهذا الحقل.
الاستخدام الأساسي لحقل اختيار الشهر
أبسط استخدام للحقل month
يتضمن عنصر <input>
وعنصر <label>
كما هو موضَّح في المثال الآتي:
<form>
<label for="bday-month">What month were you both in?</label>
<input id="bday-month" type="month" name="bday-month">
</form>
ضبط أقل وأكبر شهر يمكن اختياره
يمكننا استخدام الخاصيتين min
و max
لوضع حدود للتواريخ التي يستطيع المستخدم اختيارها، ففي المثال الآتي سنضبط أدنى تاريخ إلى 1900-01
وأقصى تاريخ إلى 2017-08
:
<form>
<label for="bday-month">What month were you both in?</label>
<input id="bday-month" type="month" name="bday-month"
min="1900-01" max="2017-08">
</form>
لاحظ أنَّ بإمكانك اختيار الأشهر الموجودة في المجال المُحدَّد فقط، إذ لا يمكن التمرير إلى أشهر أخرى.
واعتمادًا على المتصفح الذي تستعملها، فيحتمل ألّا تتمكن من اختيار قيم خارج المجال المسموح (كما في متصفح Edge)، أو يمكنك أن تختارها لكن قيمة الحقل لن تكون صالحةً (انظر قسم «التحقق من الحقل») (كما في متصفح Chrome).
ملاحظة: يفترض أنَّ بإمكاننا استخدام الخاصية step
لتحديد الفاصل بين الأشهر التي يُسمَح باختيارها (فربما تريد السماح للمستخدم باختيار شهر شباط/فبراير فقط)، لكن هذا لا يعمل بكفاءة في أيّ متصفح في وقت كتابة هذه الصفحة.
التحكم بحجم الحقل
لا يدعم الحقل month
خاصيات التحكم بالحجم مثل size
، لذا عليك استخدام CSS لهذا الغرض.
التحقق من الحقل
افتراضيًا، لا يوفِّر الحقل month
أيّ نوع من أنواع التحقق من المدخلات، فالواجهة الرسومية التي توفرها المتصفحات لا تسمح عادةً للمستخدم بإدخال أيّ شيء عدا التواريخ، لكن يمكن ألّا يختار المستخدم قيمةً لهذا الحقل من الأساس.
إذا كنتَ تستخدم الخاصيتين min
و max
لوضع حدود للتواريخ المسموح بها (انظر قسم «ضبط أقل وأكبر شهر يمكن اختياره» أعلاه) فستُظهِر المتصفحات التي تدعم الحقل month
رسالة خطأ عندما يكون التاريخ المُختار خارج هذه الحدود.
أضف إلى ذلك أنَّ بإمكانك استخدام الخاصية required
لجعل هذا الحقل إجباري، وستُعرَض رسالة خطأ إذا حاول المستخدم إرسال النموذج دون تحديد قيمة لهذا الحقل.
ضبطنا في المثال الآتي أقل وأكبر تاريخ يمكن للمستخدم اختياره إضافةً إلى جعل الحقل إجباريًا:
<form>
<div>
<label for="month">What Month would you like to visit us? (Summer months only.)</label>
<input id="month" type="month" name="month"
min="2017-06" max="2017-09" required>
<span class="validity"></span>
</div>
<div>
<input type="submit" value="Submit form">
</div>
</form>
إذا حاولت إرسال النموذج دون إكمال التاريخ (أو اخترتَ تاريخًا خارج الحدود المسموحة) فسيعرض المتصفح رسالة خطأ.
تحذير مهم: التحقق من مدخلات المستخدم عبر HTML ليس بديلًا عن التأكّد منها من جهة الخادوم، فمن السهل جدًا أن يُعدِّل أحدهم شيفرة HTML لكي يتجاوز آلية التحقق، ومن الممكن أن يتجاوز أحدهم نموذج HTML كليًا ويرسل البيانات إلى الخادوم مباشرةً. فلو لم تكن الشيفرة المشغّلة على خادومك تتحقق من المدخلات التي تستقبلها فمن الممكن أن تحدث كارثة إذا أرسل أحدهم بيانات غير مُنظمة كما يجب (أو بيانات كبيرة أو من نوع خطأ وهلم جرًّا).
التعامل مع دعم المتصفحات
وكما ذكرنا سابقًا، المشكلة الرئيسية مع حقول الشهر في هذا الوقت هي دعم المتصفحات، فمثلًا يبدو شكل منتقي التاريخ كما يلي في متصفح Firefox على هواتف أندرويد:
المتصفحات التي لا تدعم هذا الحقل ستحوِّله إلى حقل نصي، لكن هذا يُسبِّب مشاكل في موضوع الواجهة الرسومية (فالتحكم بهذا الحقل سيكون مختلفًا) والتعامل مع البيانات.
المشكلة الثانية أشد وقعًا (كما ذكرنا سابقًا)، فقيمة الحقل month
تكون موحّدة على الشكل yyyy-mm
أما محتوى الحقل النصي لا يُحدِّد صيغةً معيّنةً يجب أن يكون فيها، وهنالك الكثير من الطرائق التي يكتب فيها الناس التاريخ مثل:
mmyyyy
mm/yyyy
mm-yyyy
yyyy-mm
إحدى الطرائق لحل هذه الإشكالية هي استخدام الخاصية pattern
على حقل month
، وحتى لو لم يستعملها الحقل month
المعروض في المتصفحات الحديثة، لكن الحقل النصي الذي سيظهر في المتصفحات غير الداعمة للحقل month
سيستعملها.
جرِّب مثلًا عرض المثال الآتي في متصفح غير داعم للحقل month
:
<form>
<div>
<label for="month">What Month would you like to visit us? (Summer months only, yyyy-mm)</label>
<input id="month" type="month" name="month"
min="2017-06" max="2017-09" required
pattern="[0-9]{4}-[0-9]{2}">
<span class="validity"></span>
</div>
<div>
<input type="submit" value="Submit form">
</div>
</form>
إذا جربتَ إرسال النموذج فستلاحظ أنَّ المتصفح قد عرض رسالة خطأ إذا لم تُطابِق مدخلاتك النمط nnnn-nn
حيث يُمثِّل n
رقمًا من 0 إلى 9. لكن هذا لا يمنع المستخدمين من إدخال تواريخ خطأ.
أفضل طريقة للتعامل مع التواريخ في النماذج مع دعم جميع المتصفحات هي جعل المستخدم يُدخِل الشهر والسنة في حقول منفصلة (يستعمل العنصر <select>
لهذا الغرض)، أو استخدام مكتبة JavaScript مثل jQuery date picker و jQuery timepicker plugin.
أمثلة
سنُنشِئ مجموعتين من عناصر النماذج لاختيار التاريخ، عنصر <input type="month">
ومجموعة من عنصرَي <select>
لاختيار التاريخ في المتصفحات غير الداعمة للحقل month
.
شيفرة HTML
تبدو شيفرة HTML كما يلي:
<form>
<div class="nativeDatePicker">
<label for="month-visit">What Month would you like to visit us?</label>
<input type="month" id="month-visit" name="month-visit">
<span class="validity"></span>
</div>
<p class="fallbackLabel">What Month would you like to visit us?</p>
<div class="fallbackDatePicker">
<div>
<span>
<label for="month">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">Year:</label>
<select id="year" name="year">
</select>
</span>
</div>
</div>
</form>
أسماء الأشهر ثابتة لأنها نفسها دومًا، لكن قيم السنة تولّد ديناميكيًا اعتمادًا السنة الحالية (راجع التعليقات لتفهم كيف تعمل تلك الدوال).
جزء مهم من الشيفرة الذي عليك أن تنتبه له هو كيفية اكتشاف دعم المتصفح لحقل month
، إذ أنشأنا عنصر <input>
جديد وضبطنا قيمة الخاصية type
إلى month
ثم تأكدنا مباشرةً من قيمة الخاصية type
فالمتصفحات غير الداعمة للحقل month
ستضبط قيمة الخاصية type
إلى text
، وإذا كان الحقل month
غير مدعوم فسنخفيه وسنعرض الحقول البديلة (<select>
).
شيفرة JavaScript
سنُنشِئ أولّا بعض المتغيرات، بما فيها اللون الافتراضي، ثم سنضبط دالة لمعالجة الحدث load
الذي يُطلَق بعد اكتمال تحميل الصفحة:
// تعريف المتغيرات
var nativePicker = document.querySelector('.nativeDatePicker');
var fallbackPicker = document.querySelector('.fallbackDatePicker');
var fallbackLabel = document.querySelector('.fallbackLabel');
var yearSelect = document.querySelector('#year');
var monthSelect = document.querySelector('#month');
// إخفاء الحقول البديلة افتراضيًا
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';
// اختيار إن كان المتصفح يدعم الحقل أم لا
var test = document.createElement('input');
test.type = 'month';
// إذا كان لا يدعمه فنفِّذ ما في الدالة الشرطية الآتية
if(test.type === 'text') {
// إخفاء الحقل الأصلي وإظهار الحقل البديل
nativePicker.style.display = 'none';
fallbackPicker.style.display = 'block';
fallbackLabel.style.display = 'block';
// ملء قيم السنوات ديناميكيًا
// (لكن الأشهر ستبقى نفسها)
populateYears();
}
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);
}
}
دعم المتصفحات
Chrome | Firefox | Edge | Safari | Opera |
---|---|---|---|---|
20.0 | غير مدعوم | 12 | غير مدعوم | 10.62 |