اذهب إلى المحتوى

الاستمارات (forms) في متصفح الويب وكيفية التعامل معها في جافاسكربت


محمد أمين بوقرة

تمتلك الاستمارات وعناصر التحكّم فيها، مثل <input>، الكثير من الخاصيّات والأحداث الخاصّة بها. يساعد تعلّم هذه الخاصّيات والأحداث على التعامل مع الاستمارات براحة أكثر.

التنقل: الاستمارة والعناصر

تنتمي استمارات المستند إلى المجموعة الخاصّة document.forms، وهي ما يُطلق عليها "مجموعةً مُسمّاة (named collection)"، لأنّها مُرتّبة و مُسمّاة في آن واحد. يمكننا الحصول على استمارة ما في المستند إمّا بواسطة الرقم أو الاسم.

document.forms.my; // the form with name="my"
document.forms[0]; // the first form in the document

إذا كان لدينا استمارة ما، فإنّ جميع العناصر التي فيها تكون موجودة في المجموعة المُسمّاة form.elements. على سبيل المثال:

<form name="my">
  <input name="one" value="1">
  <input name="two" value="2">
</form>

<script>
  // الحصول على الاستمارة
  let form = document.forms.my; // <form name="my"> العنصر

  // الحصول على العنصر
  let elem = form.elements.one; // <input name="one"> العنصر

  alert(elem.value); // 1
</script>

إذا كانت لدينا عدّة عناصر لها نفس الاسم، كما هو الحال عادة مع أزرار الانتقاء (radio buttons)، فإنّ form.elements[name]‎ تكون عبارة عن مجموعة (set). على سبيل المثال:

<form>
  <input type="radio" name="age" value="10">
  <input type="radio" name="age" value="20">
</form>

<script>
let form = document.forms[0];

let ageElems = form.elements.age;

alert(ageElems[0]); // [object HTMLInputElement]
</script>

لا تتعلّق خاصيّات التنقّل هذه بهيكل الوسوم. جميع عناصر التحكّم، مهما كان عمقها في الاستمارة، موجودة في form.elements.


ملاحظة: العناصر Fieldset كاستمارات فرعيّة

قد تحتوي الاستمارة على عناصر <fieldset>، التي تمتلك بدورها الخاصيّة elements التي تسرد عناصر التحكّم التي داخلها. على سبيل المثال:

<body>
  <form id="form">
    <fieldset name="userFields">
      <legend>info</legend>
      <input name="login" type="text">
    </fieldset>
  </form>

  <script>
    alert(form.elements.login); // <input name="login">

    let fieldset = form.elements.userFields;
    alert(fieldset); // HTMLFieldSetElement

   // fieldset يمكننا الحصول على المُدخل بواسطة الاسم سواء من الاستمارة أو من
    alert(fieldset.elements.login == form.elements.login); // true
  </script>
</body>



تنبيه: الصيغة المختصرة form.name

هناك صيغة مختصرة تمكّننا من الوصول إلى العنصر بواسطة form[index/name]‎. بعبارة أخرى، بدل form.elements.login، يمكننا كتابة form.login.

تصلح هذه الطريقة أيضا، لكنّ هناك مشكلة صغيرة: إذا أتينا عنصرا ما، وغيّرنا الاسم name الخاصّ به، فسيظلّ من الممكن الوصول إليه بواسطة الاسم القديم (بالإضافة إلى الاسم الجديد). من السهل رؤية ذلك في هذا مثال:

<form id="form">
  <input name="login">
</form>

<script>
  alert(form.elements.login == form.login); // <input> نفس الـ ،true 

  form.login.name = "username"; // تغيير اسم المُدخل

  // :الاسم form.elements غيّرت
  alert(form.elements.login); // undefined
  alert(form.elements.username); // input

  // تتيح الاستمارة كلا الاسمين، القديم والجديد
  alert(form.username == form.login); // true
</script>

لا يشكّل ذلك مشكلة في الغالب، لأنّنا قلّ ما نغّير أسماء العناصر في الاستمارات.


الإشارة العكسيّة (Backreference)‏: element.form

يمكن الوصول إلى الاستمارة من أيّ عنصر داخلها بواسطة element.form. وبذلك، تشير الاستمارة إلى جميع العناصر، وتشير العناصر إلى الاستمارة، كما هو موضّح في هذه الصورة:

form-navigation.png

على سبيل المثال:

<form id="form">
  <input type="text" name="login">
</form>

<script>
  // element <- form
  let login = form.login;

  // form <- element
  alert(login.form); // HTMLFormElement
</script>

عناصر الاستمارة

لنتحدّث عن عناصر التحكّم في الاستمارة.

input و textarea

يمكننا الوصول إلى القيم التي في هذه العناصر بواسطة input.value (سلسلة نصيّة) أو input.checked (منطقيّة) بالنسبة لصناديق التأشير (checkboxes)، هكذا:

input.value = "New value";
textarea.value = "New text";

input.checked = true; // بالنسبة لصناديق التأشير أو أزرار الانتقاء

تنبيه: استخدم textarea.value، وليس textarea.innerHTML

يُرجى التنبّه إلى أنّه حتى لو كانت القيمة التي في داخل <textarea>...</textarea> هي عبارة عن عناصر HTML متداخلة، فلا ينبغي أبدا أن نستخدم الخاصيّة textarea.innerHTML للوصول إليها. ذلك لأنّ هذه الخاصيّة تحتوي على شيفرة HTML التي كانت في الصفحة بدايةً، وليس القيمة الحاليّة.


elect وoptions

للعنصر <select> ثلاث خاصيّات مهمّة:

  1. select.options -- مجموعة عناصر <option> الفرعيّة.
  2. select.value -- قيمة <option> المحدّدة حاليّا.
  3. select.selectedIndex -- عدد عناصر <option> المحدّدة حاليّا.

وتوفّر هذه الخاصّيات ثلاث طرق مختلفة لإعطاء قيمة إلى <select>:

  1. العثور على العنصر المُراد <option>، ثمّ إعطاء option.selected القيمة true.
  2. وضع القيمة في select.value.
  3. جعل قيمة select.selectedIndex هي رقم الخيار option المُراد.

قد تكون الطريقة الأولى هي الأوضح، لكنّ الطريقتين (2) و(3) أكثر ملائمة في الغالب. إليك هذا المثال:

<select id="select">
  <option value="apple">Apple</option>
  <option value="pear">Pear</option>
  <option value="banana">Banana</option>
</select>

<script>
  // تؤدي جميع اﻷسطر الثلاث نفس الوظيفة
  select.options[2].selected = true;
  select.selectedIndex = 2;
  select.value = 'banana';
</script>

بخلاف معظم عناصر التحكّم الأخرى، يتيح <select> تحديد عدّة خيارات في نفس الوقت إذا كانت له السمة multiple. قلّ ما تُستخدم هذه الوظيفة، لكن إن كان ولابد، اعتمد الطريقة الأولى: أضف/أزل الخاصيّة selected في عناصر <option> الفرعيّة. يمكن الحصول على مجموعة العناصر الفرعيّة بواسطة select.options، على سبيل المثال:

<select id="select" multiple>
  <option value="blues" selected>Blues</option>
  <option value="rock" selected>Rock</option>
  <option value="classic">Classic</option>
</select>

<script>
  // الحصول على جميع القيم المُحدّدة من التحديد المتعدّد
  let selected = Array.from(select.options)
    .filter(option => option.selected)
    .map(option => option.value);

  alert(selected); // blues,rock  
</script>

يمكن الاطلاع على المواصفة الكاملة للعنصر <select> من هنا.

new Option

من النادر استعمال هذه الصيغة على انفراد، لكنّ هناك شيئا مثيرا للاهتمام.

تحتوي المواصفة على صيغة مختصرة وجميلة لإنشاء عناصر <option>:

option = new Option(text, value, defaultSelected, selected);

حيث الوسائط:

  • text -- النصّ داخل الخيار،
  • value -- قيمة الخيار،
  • defaultSelected -- إذا كانت true، تُنشأ السمة selected في HTML،
  • selected -- إذا كانت true، فإنّ الخيار يكون محدَّدا.

قد يحصل التباس طفيف بين defaultSelected وselected. الأمر بسيط: تهيّئ defaultSelected سمة HTML التي يمكننا الحصول عليها بواسطة option.getAttribute('selected')‎. بينما تبيّن selected ما إذا كان الخيار مُحدّدا أو لا، ولها أهمّية أكبر. قد تكون للخاصيّتين القيمة true أو لا تكون لها قيم بتاتا (وهو كما لو أعطيت القيمة false). على سبيل المثال:

let option = new Option("Text", "value");
// <option value="value">Text</option> تنشئ

تحديد نفس العنصر:

let option = new Option("Text", "value", true, true);

لعناصر option الخاصّيات التالية:

  • option.selected : هل الخيار مُحددّ؟
  • option.index : رقم الخيار بين خيارات <select> الأخرى.
  • option.text : المحتوى النصّي للخيار (الذي يراه الزائر).

الملخص

التنقّل في الاستمارة:

  • document.forms: يمكن الوصول إلى الاستمارة بواسطة document.forms[name/index]‎.
  • form.elements: يمكن الوصول إلى عناصر الاستمارة بواسطة form.elements[name/index]‎، أو فقط باستخدام form[name/index]‎. تعمل الخاصيّة elements مع <fieldset> كذلك.
  • element.form: تشير إلى الاستمارة الخاصّة بها بواسطة الخاصيّة form.

يمكن الوصول إلى القيمة بواسطة input.value وtextarea.value وselect.value وغيرها، بالإضافة إلى input.checked بالنسبة لصناديق التأشير وأزرار الانتقاء.

بالنسبة لـ <select>، يمكننا أيضا الحصول على القيمة بواسطة الرقم الاستدلاليّ select.selectedIndex أو من خلال مجموعة الخيارات select.options.

هذه هي الأساسيّات التي تمكّن من بدء العمل بالاستمارات. سنقف لاحقا في هذا الدليل على المزيد من الأمثلة.

في المقال التالي، سنتناول الأحداث focus وblur التي يمكن أن تقع على أيّ عنصر، لكنّها تُعالج غالبا في الاستمارات.

التمارين

أضف خيارا إلى select

الأهميّة: 5

هناك عنصر <select>:

<select id="genres">
  <option value="rock">Rock</option>
  <option value="blues" selected>Blues</option>
</select>

باستخدام جافاسكربت:

أظهر القيمة والنصّ للخيار المُحدّد. أضف الخيار <option value="classic">Classic</option>. اجعله قابلا للتحديد.

لاحظ أنّك إذا أنجزت كلّ شيء بشكل صحيح، يجب أن تُظهِر alert الكلمة blues.

الحل

إليك الحلّ خطوة بخطوة:

<select id="genres">
  <option value="rock">Rock</option>
  <option value="blues" selected>Blues</option>
</select>

<script>
  // 1)
  let selectedOption = genres.options[genres.selectedIndex];
  alert( selectedOption.value );

  // 2)
  let newOption = new Option("Classic", "classic");
  genres.append(newOption);

  // 3)
  newOption.selected = true;
</script>

المراجع

ترجمة -وبتصرف- للمقال Form properties and methods من سلسلة Browser: Document, Events, Interfaces لصاحبها Ilya Kantor


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...