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

البحث في الموقع

المحتوى عن 'forms'.

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المحتوى


التصنيفات

  • الإدارة والقيادة
  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • السلوك التنظيمي في المؤسسات
  • عالم الأعمال
  • التجارة والتجارة الإلكترونية
  • نصائح وإرشادات
  • مقالات ريادة أعمال عامة

التصنيفات

  • مقالات برمجة عامة
  • مقالات برمجة متقدمة
  • PHP
    • Laravel
    • ووردبريس
  • جافاسكربت
    • لغة TypeScript
    • Node.js
    • React
    • Vue.js
    • Angular
    • jQuery
    • Cordova
  • HTML
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • لغة C#‎
    • ‎.NET
    • منصة Xamarin
  • لغة C++‎
  • لغة C
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • لغة Rust
  • برمجة أندرويد
  • لغة R
  • الذكاء الاصطناعي
  • صناعة الألعاب
  • سير العمل
    • Git
  • الأنظمة والأنظمة المدمجة

التصنيفات

  • تصميم تجربة المستخدم UX
  • تصميم واجهة المستخدم UI
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب GIMP
    • كريتا Krita
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • مقالات DevOps عامة
  • خوادم
    • الويب HTTP
    • البريد الإلكتروني
    • قواعد البيانات
    • DNS
    • Samba
  • الحوسبة السحابية
    • Docker
  • إدارة الإعدادات والنشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
    • ريدهات (Red Hat)
  • خواديم ويندوز
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • شبكات
    • سيسكو (Cisco)

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح
  • مبادئ علم التسويق

التصنيفات

  • مقالات عمل حر عامة
  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • العمل الحر المهني
    • العمل بالترجمة
    • العمل كمساعد افتراضي
    • العمل بكتابة المحتوى

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
    • بريستاشوب
    • أوبن كارت
    • دروبال
  • الترجمة بمساعدة الحاسوب
    • omegaT
    • memoQ
    • Trados
    • Memsource
  • برامج تخطيط موارد المؤسسات ERP
    • تطبيقات أودو odoo
  • أنظمة تشغيل الحواسيب والهواتف
    • ويندوز
    • لينكس
  • مقالات عامة

التصنيفات

  • آخر التحديثات

أسئلة وأجوبة

  • الأقسام
    • أسئلة البرمجة
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات

التصنيفات

  • كتب ريادة الأعمال
  • كتب العمل الحر
  • كتب تسويق ومبيعات
  • كتب برمجة
  • كتب تصميم
  • كتب DevOps

ابحث في

ابحث عن


تاريخ الإنشاء

  • بداية

    نهاية


آخر تحديث

  • بداية

    نهاية


رشح النتائج حسب

تاريخ الانضمام

  • بداية

    نهاية


المجموعة


النبذة الشخصية

تم العثور على 9 نتائج

  1. سنتعرف هنا في هذا المقال على كيفية إنشاء عدة نماذج Forms في برنامج سكريبوس. نماذج PDF صُمِّمت نماذج PDF لتُمكّن للمستخدم الذي يعرضها عبر الإنترنت أو محليًا على الحاسوب، من إضافة بيانات إلى هذا النموذج بعد أن يطبعها المستخدم أو يرسلها عبر البريد الإلكتروني. مكونات نموذج PDF يمكنك إضافة أي شيء تريده إلى ملف PDF مثل النصوص والصور والأشكال، وأي شيء يقدمه برنامج سكريبوس Scribus. وإذا أردت إنشاء نموذج PDF، فيجب أن تتعلم أيضًا كيفية استخدام أدوات PDF الخاصة، إذ توجد هذه الأدوات في شريط أدوات PDF من اليسار إلى اليمين كما يلي: زر ضغط PDF-Button: يُستخدَم الزر لبدء بعض الإجراءات، وسننشئ زرّين في مثالنا أحدهما لطباعة النموذج والآخر لإرساله ليكون بمثابة بريد إلكتروني، ويمكننا تحسين الزر بواجهة نسميها "أيقونة icon". قد يستخدم الزر الواحد ما يصل إلى ثلاثة أيقونات مختلفة، والتي تمكّننا من إظهار تأثير الضغط على الزر وتغيير الأيقونة التي تظهر عندما تتحرك الفأرة فوق الزر. حقل نص Text Field: يُعَد حقل النص مثل إطار نص، ولكن مع إمكانية استخدام الأعداد التي تُمثَّل مثل تاريخ أو التي تحتوي على عدد معين من الأعداد العشرية أو التي تظهر في صورة نسبة مئوية. مربع اختيار Check Box: مربع صغير يُظهِر العلامة [×] عند النقر عليه. سنستخدم في مثالنا هذا المربع للإشارة إلى أن المتقدّم للدورة هو ذكر أو أنثى. مربع تحرير وسرد Combo Box: مربع التحرير والسرد هو قائمة منسدلة فيها خيارات موضوعة ضمن نموذج مطوي، حيث يفتح المستخدم القائمة لتحديد الخيار. مربع قائمة List Box: يُستخدم مربع القائمة أيضًا لتقديم خيارات، ولكن تكون في هذه الحالة بعض العناصر من القائمة على الأقل مرئيةً دائمًا. يمكن للمستخدم التمرير في القائمة، ولكن لا يُعَد فتحها أولًا أمرًا ضروريًا. حاشية نص Text Annotation: هي حقل نص يحتوي ملاحظات تكون غير مرئية في نموذج pdf، حيث يمكنك استخدام الحاشية لإضافة نص إلى النموذج فقط، ولكن يمكنك أيضًا إضافة روابط إلى مواقع في مكان آخر في المستند أو إلى مواقع إلكترونية على الإنترنت. حاشية رابط Link Annotation: يُستخدم للروابط إلى مواقع في المستند، حيث يمكن في هذه الحالة استخدام الإحداثيات الدقيقة بواحدة النقطة Point، وذلك وفقًا لأنظمة القياس المستخدَمة في برنامج سكريبوس Scribus. يمكن أيضًا استخدام روابط لمواقع إلكترونية خارجية. كيفية البدء في إنشاء نموذج PDF يجب مراعاة الميزات التالية عند تصميم نموذج PDF: التخطيط Layout: حاول تصميم نموذجك مسبقًا، حيث يمكنك إضافة إطارات نص وجداول وصور وأشكال، أو أي شيء يمكن أن يقدمه برنامج سكريبوس. ستُستخدَم هذه العناصر لتمثيل النمط الأساسي الذي تستخدمه شركتك أو مؤسستك، وسيكون إظهار المعلومات المتوقَّعة من المستخدم ضمن النموذج أمرًا ضروريًا. حقول PDF: يجب استخدام الحقول المتاحة التي يقدمها سكريبوس، والتي لها أنواع متعددة. الإعداد Set up: يجب عليك التعرف على التعديلات المتعددة الممكنة على الحقول، ويمكنك إعداد الحقول في نوافذ متعددة. عمليات التحقّق Validations: يمكن ضبط حدود للمدخلات التي تُدخَل في الحقل، إذ يمكنك تقييد إدخال عدد بحدود معينة على سبيل المثال، وهذا ما سنطبّقه في مثالنا. العمليات الحسابية Calculations: يمكنك إعداد عملية حسابية معينة للحقل، حيث تكون الاحتمالات هي جمع محتويات حقلين أو أكثر أو ضربها وما إلى ذلك، كما يمكن أيضًا حساب القيمة العليا أو الدنيا، أو حساب متوسط القيم لعدد كبير من الحقول، ويمكن أيضًا إجراء حسابات أخرى أكثر تعقيدًا ولكنها تتطلب برمجة لذلك. البرمجة Programming: إذا أردت أن يكون نموذجك ذكيًا، فيجب تعلّم البرمجة باستخدام لغة JavaScript، وهي لغة برمجة لا تُستخدَم في نماذج PDF فقط، ولكن على مواقع الويب أيضًا. إن لم تتعرّف على البرمجة سابقًا، فتوقع أن تستغرق بضعة أشهر لتصبح ماهرًا فيها إلى حد ما. ستقدّم لك الفقرة التالية بعض التلميحات والنصائح عن مكان العثور على مزيد من المعلومات حول لغة JavaScript. لغة JavaScript Java: هي لغة برمجة سوّقت لها شركة Sun Microsystems في عام 1995، حيث أمضى المطورون المسؤولونن جيمس جوسلينج James Gosling ومايك شيريدان Mike Sheridan وباتريك نوتون Patrick Naughton، حوالي أربع سنوات لتطوير هذه اللغة. تقول القصة أن هؤلاء المطورين شربوا كثيرًا من القهوة، وهو شيء لا بد أن تفعله عندما تبدأ في البرمجة، حيث جاءت العلامة التجارية للقهوة التي شربوها من جزيرة Java، ومن هنا جاء اسم هذه اللغة وأيقونتها التي تعرض فنجان قهوة مُصمَّم. أخذت لغة JavaScript الاصطلاحات وتعريفات التسمية المتعددة من لغة Java ولكن لديها إعداد مختلف حتى الآن، وقد استُخدِمت هذه اللغة في الأصل من جانب العميل في المتصفحات، فإذا تصفحت الإنترنت وألقيت نظرةً خاطفةً على صفحة يقدمها لك الخادم، فأنت العميل. لقد طوَّر هذه اللغة براندون فينش Brendan Finch في عام 1995، والذي عمل في شركة نتسكيب Netscape التي صمَّمت متصفحًا مشهورًا نافس إنترنت إكسبلورر Internet Explorer منافسةً شديدةً لفترة طويلة. لغة JavaScript لبرامج Acrobat: وضعت شركة البرمجيات أدوبي Adobe معيار PDF، حيث يُحتمَل أن تجد برنامج Acrobat Reader على حاسوبك الخاص، لأنه قارئ لمستندات PDF، ويُستخدَم على نظاق واسع. تبذل هذه الشركة جهودًا كبيرة لشرح استخدام لغة JavaScript، لأنها الخيار الأفضل في نماذج PDF. برنامج سكريبوس ولغة Javascript: يصعُب إلى حد ما معرفة مدى "فهم" سكريبوس لمقدار تعلّق لغة JavaScript بالنماذج. نموذج PDF يُظهِر الشكل الآتي النموذج الذي سنبنيه خطوةً بخطوة كما يظهر في سكريبوس، وتُعَد الدوائر الحمراء مجرد علامات للإشارة إلى عناصر النموذج التالية: حقول النص Text fields. مربعات الاختيار Check Boxes. مربعات التحرير والسرد Combo Box. حقل الحاشية النصية Annotation field. الأزرار Buttons. كل شيء آخر -مثل الترويسة والخطوط- هي كائنات سكريبوس عادية. هناك أيضًا بعض الإطارات النصية البسيطة مثل الإطارات التي تحتوي على M وF، والتكلفة باليورو Cost (euro)‎، وعدد المتقدمين Nr attending، وكذا التكلفة الإجمالية باليورو Totals (euro)‎، وهي ببساطة تسميات لعناصر النموذج المجاورة لها. يوضّح الشكل التالي النموذج كما يظهر في برنامج Adobe Reader باستثناء الأزرار، إذ يُظهِر اللون الأزرق الفاتح المناطق التي يمكن إدخال بعض المدخلات فيها ضمن النموذج. تُعَد الكلمة Name مدخلةً افتراضيةً تشير أيضًا إلى نوع الدخل، لذلك يمكنك حذفها وإدخال اسمك لملء هذا النموذج. يجب أن تدرك أنه لا يمكن اختبار النموذج أثناء تصميمه ضمن سكريبوس، أي لا تعمل جميع عناصر النموذج في سكريبوس، لذلك يجب عليك اتخاذ الخطوات التالية في كل مرة تنفّذ فيها خطوةً في عملية التصميم وتريد التحقق منها: احفظ النموذج في سكريبوس مثل ملف sla. صدّر النموذج بتنسيق PDF. ابحث عن ملف PDF الناتج وافتحه باستخدام برنامج Adobe Reader. اختبر النموذج. إذا وجدت أي أخطاء أو أردت متابعة التصميم، فيجب أن تغلق Adobe Reader وتعود إلى بيئة سكريبوس. أجرِ التغييرات التي تريدها أو وسّع النموذج. احفظه مرةً أخرى في سكريبوس، وصدّر ملف PDF جديد واستبدل إصدار PDF السابق به. قد يبدو هذا أمرًا بديهيًا، ولكن في بعض الأحيان يمكن نسيانه، وهو ما يؤدي إلى إنشاء إصدارات مختلفة متعددة، وبالتالي ترتبِك أثناء محاولتك لمعرفة النسخة النهائية "الحقيقية". كرّر هذه الخطوات كلما كان ذلك ضروريًا إلى أن يعمل النموذج تمامًا كما تخيلته. ستعتاد على عناصر النموذج المختلفة مع مرور الوقت، ولن تجد أن إعادة فحص ملف PDF بعد كل تغيير أمرًا ضروريًا. التخطيط Layout سننشئ نموذج تسجيل وهمي لنوع معين من التدريب لمدرسي اللغة الإنجليزية كلغة ثانية EFL باستخدام منهجية معينة، وهنا اتبع الآتي: جهّز مستندًا جديدًا بحجم A4 أو رسالة Letter. تحتاج بعض إطارات النص. نضع اسم المعهد في الأعلى، ثم نطبّق الألوان لاحقًا، إذ سنأخذ اللون من لون واجهة الزر. يمكن تصميم أيقونة الأزرار باستخدام برنامج رسم بسيط مثل الرسام (إن استخدمت نظام تشغيل ويندوز). سنستخدم في الزاوية اليسرى السفلية إطارين نصيين صغيرين يحويان إما ذكر M(ale)‎ أو أنثى F(emale)‎. توجد على اليمين ثلاثة إطارات نصية التي تحتوي Cost (euros)‎ وNr attending وTotals (euro)‎، ويكون ارتفاع الإطارات 5.5 مم تقريبًا، والخط Arial وحجمه 12 نقطة. سنخفّض النص في الإطارات قليلًا، مما يُعطي مظهرًا أفضل. انقر على قسم الأعمدة وتباعد النص Columns & text distances في تبويب نص Text من نافذة خصائص Properties، أو من نافذة خصائص النص في الإصدار 1.5.7 من برنامج سكريبوس، وطبّق تباعدًا 1 مم من الأعلى. سنضيف خطين سميكين هنا، وستظهر لنا النتائج حتى الآن مثلما في الشكل الآتي. لا تُعَد مواضع الأدلة Guides مهمة جدًا، حيث يمكنك تقدير مواضعها وسيفي ذلك بالغرض. لاحظ أن الهدف الرئيسي من الأدلة هو المساعدة في محاذاة الكائنات المختلفة، وإنشاء بعض التوازن ضمن التخطيط. إضافة عناصر نموذج PDF الخطوة التالية هي إضافة عناصر نموذج PDF والتي هي: سبعة حقول نصية ومربعي اختيار ومربع تحرير وسرد وزرّين، ولكل من هذه العناصر طريقته الخاصة: حقل النص Text field: يمكن للشخص الذي يستخدم النموذج ملء المعلومات في حقل نصي، ولكن سنضيف في مثالنا نصًا افتراضيًا يوضّح للمستخدم المعلومات المتوقعة. سترى في الشكل الآتي حقلين نصيين مكتملين على اليسار وحقلًا آخر يجب ملؤه بنص مناسب، حيث يمكنك كتابة النص مباشرةً في حقول النص، مثل الكتابة في إطارات النص النمطية، وبعد ذلك حدّد حقلًا نصيًا واستخدم محرّر القصص Story editor في سكريبوس لتحرير محتويات الإطار. مربعات الاختيار Check boxes: يوجد حقلان يمكن ملؤهما بعلامة، إذ نستخدم هذين الحقلين للدلالة على جنس المتقدّم. لا يمكن أن يكون المتقدّم ذكرًا وأنثى في الوقت نفسه، لذلك يجب أن يسمح النموذج بوضع علامة واحدة فقط في أحد مربعات الاختيار. سنتأكد من أن وضع علامة في أحد المربعات يزيل العلامة من المربع الآخر باستخدام البرمجة. قد تكون لدينا قائمة بالخيارات غير الحصرية التي يمكن للمستخدم الاختيار من بينها في بعض الحالات، وبما أنه سيكون هناك أكثر من خيار واحد، فلن نحتاج إلى هذه البرمجة التي تقيّد الاختيار. مربع التحرير والسرد Combo box: سنملأ مربع التحرير والسرد بعدد من خيارات التدريب، حيث سيملأ برنامج صغير هذا المربع مؤقتًاعندما ينقر المستخدم عليه، وستُملَأ التكلفة في أحد حقول النص بمجرد أن يختار المتقدّم التسجيل في تدريب معين، ويتطلب ذلك أيضًا قليلًا من البرمجة. ستُدخَل النتيجة فقط عندما ينقر المستخدم في حقل آخر، إذ سنجبر المستخدم على ذلك عن طريق ملء خانة عدد المتقدمين بالقيمة صفر، ولهذا يجب على المستخدم تغيير ذلك، وبالتالي سينفّذ البرنامج، ويمكنك تطبيق ذلك بطرق أخرى أيضًا. الأزرار Buttons: يمكن البدء بإجراء من خلال النقر على زر. الزر الأشهر الذي نستخدمه يوميًا هو زر موافق أو OK، إذ يسمح لنا برنامج سكريبوس أيضًا بإضافة مثل هذا الزر إلى النموذج. نجد خلف زر طباعة النموذج "Print From" جزء البرنامج الذي ينفّذ هذا الإجراء. لا يحتاج زر إرسال النموذج أيَّ شيفرة برمجية لأنه يمكن ضبط هذا الإجراء في نافذة ضمن برنامج سكريبوس. الأحداث Events يُعَد النقر على زر أو النقر في حقل نصي حدثًا إذا ملأت حقلًا نصيًا، أو إذا اخترت من مربع قائمة أو مربع تحرير وسرد ثم نقرت في حقل آخر، فهذا يسمى أيضًا. يتصل الحدث بحقل نصي أو زر أو أي عنصر تحكم آخر في نموذج PDF، ويوفّر كل حدث يمكن اكتشافه إمكانية إضافة جزء من شيفرة برمجية إليه. سنضيف في نموذجنا زرًا لطباعة النموذج عندما ينقر المستخدم عليه. وسنستخدم حدث mouse down (أي النقر على زر الفأرة الأيسر عند وضع مؤشرها على الزر) لبرمجة الجزء الذي سينفّذ هذه المهمة، بحيث إذا نقر المستخدم على الزر عشر مرات فرضًا، فسيُطبَع النموذج عشر مرات. تسمَّى طريقة البرمجة هذه بالبرمجة المُقادة بالأحداث، فجميع أنظمة التشغيل المتوفرة حاليًا للحواسيب مثل Apple OS X وOS / 2 وLinux وWindows وغيرها مبنية على هذا المبدأ، ولا بد أنك على دراية بهذه الطريقة، وستتعرّف الآن على الجانب الخلفي من هذه التقنية وتبرمجها بنفسك. ارسم حقل pdf نصي على يسار النموذج. اضبطه على النحو التالي: نوع الخط Arial وحجمه 12 نقطة، تباعد من الأعلى 1 مم، العرض تقريبًا 60 مم والارتفاع 5.5 مم. انسخ هذا الحقل ثلاث مرات (باستخدام Ctrl + C ثم Ctrl + V من لوحة المفاتيح في نظام Windows)، ثم ضَع هذه النسخ أسفل بعضها البعض بدقة. لاحظ أنه يمكنك أيضًا استخدام قائمة عنصر Item ثم مضاعفة/تحويل ثم نُسخ مطابقة Multiple Duplicate لإنشاء هذه النسخ، إما عن طريق نسخ سلسلة منها مع تباعد رأسي معين، أو إنشاء عدد من الصفوف مع التباعد الذي ضبطته. انقر على حقل النص الأول بزر الفأرة الأيمن واختر من القائمة المنبثقة تحرير نص Edit text باستخدام محرّر القصص. ثم يفتح محرر القصص، حيث يمكنك كتابة النص. حرّر النص وأغلق نافذة محرّر القصص، ثم سيظهر النص في حقل النص. كرّر هذا الإجراء لإضافة النصوص إلى الحقول الأربعة التالية: الاسم Name والعنوان Address والرمز البريدي Postal code والمدينة City. ارسم مربعي الاختيار بجوار إطارات النص التي تقرأ M وF على التوالي. نحتاج إلى عناصر تحكم pdf التالية على الجانب الأيمن من النموذج: مربع التحرير والسرد في الأعلى. ثلاثة حقول نصية تحت مربع التحرير والسرد وعلى يمين الإطارات النصية الثلاثة الموجودة سابقًا. ثم زرين أسفل هذه المجموعة. يوضّح الشكل التالي النموذج كما يجب أن يبدو عليه حتى الآن. لاحظ أن الإطار االمحدّد باللون الأحمر غير مذكور، ولكنه إطار حاشية نصية Text Annotation. وضع أيقونة Icon على الزر يمكن تحسين الأزرار باستخدام صورة صغيرة عليها، إذ نسمّي هذه الصورة أيقونة، أو يمكنك بدلًا من ذلك إضافة نص قصير إلى واجهة الزر فقط. تُعَد إضافة نص إلى زر في سكريبوس مثل إضافة نص إلى حقل نصي. سنرسم هذه الأيقونة في مثالنا كما يلي: استخدم برنامج رسم مثل برنامج الرسام الخاص بنظام Windows. حدّد حجم لوحة الرسم الذي يجب أن يتناسب مع حجم الزر. يجب أن يكون القياس 200‎ x 100 بكسل أكثر من كافٍ. وستجد الحجم في أيّ برنامج ضمن الخيار خصائص من قائمة ملف. سيسمح لك برنامج الرسم بإضافة نص، واستخدام خط مثل Wingdings أو Symbol لإضافة إشارات خاصة مثل لوحة مفاتيح الحاسوب والسهم والمغلّف. أضف بعض ألوان للخلفية وبعض الخطوط السميكة مع تظليل أغمق قليلًا، فهذا يعطي إحساسًا بتأثير الظل. احفظ رسم الأيقونة وانتقل إلى سكريبوس. إعداد الحقول المهمة التالية هي إعداد جميع الحقول من خلال نافذة خصائص الحقل Field Properties. لنبدأ بأحد الأزرار: انقر نقرًا مزدوجًا على الزر الموجود على اليمين، لتفتح نافذة خصائص الحقل. أسنِد اسمًا لهذا الحقل. إذا تخطيت ذلك فإن جميع عناصر التحكم في النموذج ستأخذ اسمًا عامًا يتكون من نوع الحقل ورقم، حيث لن يكون هذا الاسم واضحًا جدًا. لذلك انتقل إلى تبويب المظهر Appearance وأسند اسمًا يوضّح الغرض من الحقل. اختر الخيار لا طباعة No Print في قسم الوضوح Visibility. وإذا قرر المستخدم طباعة النموذج بعد ذلك، فلن تكون طباعة الأزرار أمرًا ضروريًا. حدّد التبويب خيارات Options واختر نوع الزر عادي Normal. ثم تفتح نافذة فتح Open، وستحدّد واجهة الزر (الرمز أو الأيقونة) التي جهّزتها للتو. ضع في بالك أنه يمكنك استخدام ما يصل إلى ثلاثة أيقونات: عادي Normal (المرئي في معظم الأحيان)، وPressed الذي ظهر عند النقر على الزر، وتدفق Roll over الذي يظهر عندما يحوم مؤشر الفأرة فوق الزر. وقد استخدمنا في مثالنا أيقونةً واحدةً فقط. انقر على تبويب إجراء Action وحدّد النوع Type سلّم النموذج Submit form. اكتب رابط url في خانة تسليم للرابط Submit to url. يوضّح الشكل التالي كيفية استخدام عنوان البريد الإلكتروني، حيث سيحاول برنامج Adobe Acrobat Reader فتح عميل البريد على حاسوب المستخدم. وإذا فشل في ذلك فستظهر نافذة مع بعض الخيارات. اكتمل إعداد الزر الآن. يمكن تحسين الزر الأيسر الذي يعالج طباعة النموذج باستخدام أيقونة بنفس الطريقة السابقة. لكننا استخدمنا محرر القصص لإضافة نص إلى الزر. إذا استخدمت لون خلفية للزر الذي يرسل نتائج النموذج عبر البريد الإلكتروني تمامًا كما فعلنا، فيمكنك استخدام أداة سكريبوس قطارة العين Pipet لإضافة هذا اللون إلى ألوان المستند واستخدامه لتحسين عنوان النموذج والخطين اللذين أضفناهما سابقًا. اصطلاحات التسمية Naming Conventions تمكّننا الأسماء المُسنَدة للحقول في "الجزء الخلفي" من النموذج من أداء مهام معينة من خلال أجزاء الشيفرة البرمجية، حيث يجب ألّا يكون جانب المستخدم (الجزء الأمامي) وجانب المبرمج (الجزء الخلفي) من النموذج متماثلين. تُعَد الأسماء العامة مرهقةً عمليًا، لأنها تُستخدم أيضًا لتقديم نتائج النموذج عند إرسالها عن طريق البريد الإلكتروني، ولذلك يُفضَّل أن تحصل على نتيجة كما يلي: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } اسم الحقل الدخل G. Bruijnes Name Langstraat 6 Address ‎1234 AA Postal code Stadje City ON Female وتكون النتيجة الأقل وضوحًا بأسماء عامة كما يلي: اسم الحقل الدخل G. Bruijnes Text22 Langstraat 6 Text37 ON Text42 يمكن أن تختلف لغة التسميات عن اللغة المستخدمة في النموذج، لأن النتائج قد يعالجها موظفون لا يتحدثون الإنجليزية، ولكن هذا ليس ضروريًا ويمكنك استخدام أي شيء تريده. يستخدم المبرمجون غالبًا نوعًا مختلفًا من التسميات يسمَّى الترميز المجري Hungarian Notation، حيث يُذكَر نوع الكائن في الاسم (نسمي الحقل كائنًا أو عنصر تحكم)، لذلك تكون اللغة الإنجليزية في هذه الحالة هي اللغة السائدة وتكون أسماء الحقول كما يلي: اسم الحقل chkFemale txtAcqAddress btnPrintForm توضّح البادئة chk أننا نتعامل مع مربع اختيار، وستشير txt إلى حقل نصي، وbtn إلى زر. إعداد الحقول الأخرى يمكنك إعداد الحقول بالنقر المزدوج عليها لتظهر نافذة خصائص الحقل. يوضح الجدول التالي جميع المعلومات الضرورية لأنواع الحقول الأخرى: عنصر التحكم التبويب في نافذة خصائص الحقل الإعداد Checkbox (M)‎ المظهر Appearance الاسم: M Checkbox (M)‎ خيارات Options الإعداد الافتراضي غير مُحدَّد Checkbox (F)‎ المظهر Appearance الاسم: F Checkbox (F)‎ خيارات Options الإعداد الافتراضي غير مُحدَّد (معظم المعلمين من الإناث) Combo box المظهر الاسم: Training الحقل الموجود بجوار التكلفة Cost المظهر الاسم: Cost الحقل الموجود بجوار التكلفة Cost نسّق Format الملف منسّق كـ: عدد Number، كسور عشرية: 0، استخدم رمز العملة Use Currency symbol: دون تحديد، التنسيق: 9,999.99 الحقل الموجود بجوار التكلفة Cost تحقّق Validate يجب أن تكون القيمة أكبر أو يساوي: 1 الحقل الموجود بجوار التكلفة Cost في محرّر القصص Story Editor: الدخل Input، والمحاذاة Alignment الدخل: 0، والمحاذاة: إلى اليمين الحقل الموجود بجوار التكلفة الإجمالية Totals المظهر الاسم: Totals الحقل الموجود بجوار التكلفة الإجمالية Totals نسّق Format الملف منسّق كـ: عدد Number، كسور عشرية: 0، استخدم رمز العملة Use Currency symbol: دون تحديد، التنسيق: 9,999.99 إذا أضفت حقل حاشية نصية النوع Type وصلة شبكية خارجية External weblink إذا أضفت حقل حاشية نصية الموقع Destination أي موقع إالكتروني www.yourwebsite.com مثلًا وبذلك يكتمل إعداد الحقول. إضافة البرمجة (أجزاء الشيفرة البرمجية) نستخدم لغة JavaScript لأتمتة أحداث معينة. ليست هناك حاجة لأن تكون لديك أي خبرة برمجية محددة لتتمكن من فهم أجزاء الشيفرة التي سنستخدمها. ;إذا أردت إنشاء المزيد من نماذج pdf بنفسك، فلن يكون هناك مفر، إذ يجب عليك تعلم لغة JavaScript. مربعات الاختيار check boxes معظم المدرسين من الإناث، ولذلك حدّدنا مربع الاختيار F افتراضيًا. انقر نقرًا مزدوجًا على مربع الاختيار M. حدد التبويب الإجراء Action في نافذة خصائص الحقل. اختر النوع Type: جافاسكربت JavaScript. اختر الحدث Event: الفأرة للأعلى Mouse up. انقر على زر تحرير Edit. انسخ جزء الشيفرة التالي: var v = this.getField("F"); v.value="Off"; يقع جزء الشيفرة في حدث الفأرة للأعلى Mouse up في مربع الاختيار M. إذا نقرت على مربع الاختيار M، فستوضَع علامة الاختيار في هذا المربع، وهذا يعني أنه يجب إزالة علامة الاختيار المعيارية في مربع الاختيار F. أشرنا أولًا إلى الحقل F في هذا الجزء من الشيفرة، ثم يمكننا عند تحقّق ذلك أن نحوّل قيمة الحقل F إلى "إيقاف Off". اختر قائمة ملف File ثم حفظ وإغلاق Save and Exit في قائمة المحرر عند الانتهاء. ثم سترى جزء الشيفرة في نافذة خصائص الحقل. انقر على الزر "موافق" في نافذة "خصائص الحقل Field Properties". انقر نقرًا مزدوجًا على مربع الاختيار F. حدد التبويب الإجراء وأضف الإعداد نفسه الذي أجريته مع مربع الاختيار M. جزء الشيفرة مختلف قليلًا. قد يرتكب المستخدم خطأً أو قد يغير رأيه، لذلك يجب أيضًا أن نكون قادرين على إزالة العلامة من مربع الاختيار M: var m = this.getField("M"); m.value="Off"; مصطلحات برمجية يعني الاختصار var متغيرًا variable، فالمتغير هو اسم عشوائي نستخدمه للإشارة إلى شيء ما. وتشير المتغيرات في أجزاء الشيفرة السابقة إلى الحقول ذات الأسماء M وF على التوالي، وهي الحقول التي وضعناها في النموذج بجوار حقلي النص M(ale)‎ وF(emale)‎؛ بينما Value هو خاصية الكائن، والكائن هو الحقل، حيث لكل كائن خصائص محددة تمامُا كما هو الحال في الحياة الواقعية، حيث تمتلك السيارة خاصية اللون Color وخاصية عدد الأبواب NumberOfDoors على سبيل المثال. يقع الحدث عندما يحدث شيء مثل النقر بالفأرة على زر أو تحريك الفأرة فوق كائن مثل حقل نص أو مربع اختيار. لاحظ أن المتغير v يوضح أن اسم المتغير في لغة JavaScript لا يجب أن يتطابق مع اسم الحقل. أجزاء الشيفرة لمربع التحرير والسرد يستخدم مربع التحرير والسرد جزأين برمجيين، حيث يكون الجزء الأول نشطًا عندما ينقر المستخدم على المربع ويزوّده بقائمة الدورات الممكنة، وبالتالي تقديم عدد من الخيارات. يجب أن ننفّذ ذلك في وقت تحميل النموذج في قارئ PDF، ولكن هذا خارج نطاق هذا المقال، لذلك سنستخدم الطريقة التالية: انقر نقرًا مزدوجًا على مربع التحرير والسرد. حدّد تبويب الإجراء Action. اختر النوع: جافاسكربت JavaScript. اختر الحدث: On focus. انقر على الزر تحرير وانسخ جزء الشيفرة التالي: var f = this.getField("Training"); f.editable = false; f.doNotSpellCheck = true; f.commitOnSelChange = true; f.setItems( ["Choose course!", "Basic", "Intermediate", "Advanced"]); يمكن منع حدوث تغيير في إعدادات الحقل باستخدام شيفرة برمجية، إذ يمكننا أن نحرم المستخدم من إمكانية ملء تدريب غير موجود من خلال f.editable = false;‎. وإذا سمحنا بالتعديل، فسيصبح الأمر برمته أكثر تعقيدًا، لأنه يجب أيضًا التحقق من معلومات المستخدم المتوفرة، وقد عطّلنا التدقيق الإملائي أيضًا لأننا سنضيف أسماء التدريبات الصحيحة بأنفسنا. سيُملَأ مربع التحرير والسرد بأربعة احتمالات، أولها اختيار الدورة، حيث يشير المستخدم إلى المعلومات المطلوبة. تمثّل المدخلات الثلاثة الأخرى الدورات التدريبية المتاحة. ويمكنك إضافة ما تريد، ولكن يجب بعد ذلك تعديل جزء الشيفرة الآتي: اختر حفظ وإغلاق في قائمة ملف ضمن المحرّر. حدّد الحدث On blur، حيث يشير هذا الحدث إلى النقر بالفأرة في المربع أو استخدام مفتاح Tab من لوحة المفاتيح لينتقل المؤشر إلى مربع التحرير والسرد، بعد ذلك انسخ جزء الشيفرة التالي: var t = this.getField("Training"); var c = this.getField("Cost"); switch (t.value){ case 'Basic': { c.value=250; } break; case 'Intermediate': { c.value=275; } break; case 'Advanced': { c.value=325; } break; default: { c.value=0; } } يشير المتغير c إلى حقل النص الذي اسمه Cost ويمثّل التكلفة. يُكتَب المبلغ في هذا الحقل اعتمادًا على الاختيار الذي أُجري في مربع التحرير والسرد، وهناك قيمة افتراضية هي 0، وهي صالحة طالما لم يُحدَّد أي خيار. العمليات الحسابية Calculations يجب أن نجري العملية الحسابية اللازمة لجداء عدد المتقدمين بتكلفة الدورة كما يلي: انقر على الحقل خلف إطار النص المكتوب عليه Totals. حدّد تبويب احسب Calculate. انقر فوق زر اختيار "القيمة هي Value is the" واختر "الناتج product" من القائمة. انقر على الزر "التقط Pick"، واحرص على أن تكون الحقول Cost وNrAt في قسم الحقول المحدَّدة كما في الشكل الآتي. أغلق جميع النوافذ بزر موافق. اختبار النموذج احفظ عملك في سكريبوس. صدّر الملف بصيغة pdf. احفظ الملف مرةً أخرى في سكريبوس، وذلك لحفظ التغييرات التي أجريتها على طريقة تصدير سكريبوس للملف بصيغة pdf. ابحث عن ملف pdf على القرص الصلب وافتحه باستخدام برنامج Acrobat Reader أو أي قارئ PDF آخر. تحقق مما إذا كان كل شيء يعمل بصورة صحيحة. إذا كانت التغييرات مطلوبة فأغلق ملف pdf، وأجرِ تغييرات في بيئة سكريبوس وكرّر الخطوات السابقة. لننفّذ هذه الخطوات معًا كما يلي: انتقل أولًا إلى سكريبوس، وافتح القائمة ملف File واختر حفظ Save. ارجع إلى القائمة ملف واختر تصدير Export، ثم اختر حفظ مثل PDF. ما عليك سوى إجراء تغييرات في بضع تبويبات فقط هي: التبويب التغيير الإعداد عام General إخراج للملف: Output to File: استخدم اسمًا وموقعًا يسهّلان عليك العثور على الملف بعد ذلك. عام General التوافق Compatibility الإصدار PDF 1.4 (Acrobat 5)‎ على الأقل خطوط Fonts الخطوط للتضمين Fonts to embed اضغط على ضمّن الكل Embed all لون Color الإخراج بهدف: Output Intended For: شاشة / ويب Screen / Web انقر الآن على زر حفظ Save. افتح مستكشف Windows أو أي مدير ملفات آخر مناسب لنظام التشغيل الذي تستخدمه مثل نوتيلوس Nautilus في نظام أوبونتو Ubuntu، أو فايندر Finder على آبل Apple. ابحث عن ملف pdf وافتحه، إذ يمكنك تشغيل برنامج Adobe Reader وفتح الملف منه. قد يعرض القارئ تحذيرًا، وهذا التحذير واضح، فالنموذج قادر على إرسال البيانات بالبريد الإلكتروني. تحقق مما إذا كان كل شيء صحيحًا، وانقر على مربع التحرير والسرد، بعدها حدّد دورةً تدريبية، واختبر أيضًا عمل زر طباعة النموذج. إذا ثُبِّت عميل بريد إلكتروني مثل أوتلوك Outlook لنظام التشغيل ويندوز، فستُعالَج نتائج النموذج مباشرة. بينما في حالة وجود خدمة بريد عبر الإنترنت مثل ياهو Yahoo أو جيميل Gmail، فيجب حفظ ملف pdf أولًا -ويمكن ذلك فقط مع الإصدار 9 من Adobe Reader أو الإصدارات الأحدث-، ثم يمكن إرسال النتائج عبر البريد الإلكتروني. يمكنك اختيار عدة أنواع من الملفات عند الحفظ مثل: النوع الوصف النوع ‎ .fdf تنسيق ملف نموذج Adobe، حيث تُحفَظ البيانات الموجودة في الحقول فقط. يجب في هذه الحالة أن يكون لدى المتلقي أيضًا نسخة من النموذج الأصلي، ثم تُضاف البيانات المرسَلة عبر البريد الإلكتروني تلقائيًا إلى النموذج. النوع ‎ .xfdf تنسيق ملف النموذج الموسَّع extended form file format القادر على إظهار مزيد من الخيارات. النوع ‎ .xml تنسيق ملف قادر على عرض البيانات في الحقول المناسبة على صفحة ويب. النوع ‎.txt تُحفَظ البيانات في هذه الحالة كملف نصي بسيط يمكن فتحه وقراءته باستخدام أي معالج أو محرّر نصوص متوفر على نظامك. النتائج تبدو النتائج كملف FDF كما يلي: نتائج النموذج تُطبَع عادةً جميع الحقول حقلًا تلو الآخر. وقد وضعنا كل حقل على سطر خاص به من أجل الوضوح في الشكل السابق، إذ يجب ترتيبها بنفس الترتيب الذي وُضِعت فيه ضمن النموذج، وإذا استخدمت ترتيبًا مختلفًا، فسينعكس ذلك على النتيجة. لا ينبغي أن يمثل ذلك مشكلةً كبيرةً جدًا بسبب إضافة أسماء الحقoول أيضًا إلى الملف، وهذا سبب وجيه لتسمية الحقول الخاصة بك بعناية وعدم استخدام الأسماء المعيارية. يمكن تغيير ترتيب الحقول في بيئة سكريبوس، وهنا استخدم تبويب X وY وZ في نافذة الخصائص لتغيير الترتيب باستخدام قسم مستوى Levels، كما في الشكل السابق. سترى رقم الحقل بالتناوب عند تحديد الحقل، ويمكن أيضًا العثور على اسم الحقل ضمن هذا التبويب في الجزء العلوي، إذ يمكنك تغيير الاسم من هنا أيضًا. ترجمة -وبتصرّف- للمقال A Brief Tutorial on Forms لصاحبه Gerrit Bruijnes. اقرأ أيضًا كيفية بدء استخدام برنامج سكريبوس Scribus كيفية إنشاء أشكال معقدة ذات زوايا دائرية في برنامج سكريبوس Scribus خط الشبكة الأساسي Baseline Grid في برنامج سكريبوس كيفية إنشاء رمز RSS Feed في برنامج سكريبوس Scribus كيفية إنشاء لافتة نيون Neon Sign في برنامج سكريبوس Scribus
  2. تقدّم المواصفات الجديدة في CSS3 محدّدين Selector مفيدين للغاية هما :valid و :invalid وهي أصناف زائفة pseudo-class يمكن استخدامها مع عناصر الإدخال الخاصة بالاستمارات. لنفترض أن لديك عنصر إدخال تتحقّق من خلاله فيما إذا كان ما أدخله المستخدم صحيحًا أم خاطئًا. لإجراء عملية التحقق ستحتاج إلى إضافة خاصية HTML5 required إلى الوسم الخاص بعنصر الإدخال، وبهذا يمكن الاستفادة من المحدّدين :valid/:invalid لتغيير لون حقل الإدخال ليعرف المستخدم من خلال ذلك أنّ ما أدخله صحيح أو خاطئ. فعلى سبيل المثال يتحول مربع الإدخال إلى اللون الأخضر عندما تكون العبارة صحيحة، وكما يلي: input:required { background: #AAA; } input:valid { background: #0A0; } input:invalid { background: #A00; } سننشئ في هذا الدرس استمارة بنمط Material وسننبّه المستخدم على صحة البيانات المدخلة في الاستمارة من خلال الصنفين الزائفين :valid و :invalid. تتألف الاستمارة من مربع نصّي وحيد وقد أحطنا عنصري input[type="text"] وlabel بعنصر div يحمل المحدّد .form-control من إطار عمل Bootstrap. لدينا أيضًا شريط سيتغير لونه بين الأخضر والأحمر للدلالة على صحة المعلومات المدخلة من عدمها. <div class="form-control"> <input type="text" required /> <span class="bar"></span> <label for="First Name">First Name</label> </div> في البداية سنزيل جميع الحدود المحيطة بمربّع النص باستثناء الحدّ السفلي وسنلوّنه باللون الأزرق ليكون متناسقًا مع نمط التصميم Material. .form-control { position:relative; margin-top:40px; width:400px; } input { border:none; border-bottom:3px solid #34495e; padding:10px 0; width:400px; display:block; font-size:16px; } سيؤدي العنصر label دور ماسك مكان placeholder، لذا سنجعل موقعه مطلقًا مع تعيين المسافة اليسرى والعلوية المناسبة، ليبدو العنصر بهيئة ماسك مكان اعتيادي. label { position:absolute; top:8px; left:5px; font-size:16px; color:#333; transistion: 0.3s ease all; -webkit-transition:0.3s ease all; } والآن عندما يضغط المستخدم أو يجعل التركيز على مربّع النص سنقوم بإلغاء الحدّ السفلي، وسنغير موقع ماسك المكان ليصبح فوق مربع النص ليبدو كـ label. input:focus{ border:none; outline:none; } سيبقى الـ label فوق مربع النص إلى أن يجعل المستخدم التركيز على مربّع النص ويضيف إليه أي معلومات صحيحة. input:focus ~ label, .form-control input:valid ~ label { top:-10px; font-size:12px; left:2px; color:#111; } لن يظهر المحدّد .bar بصورة تلقائية، بمعنى أن عرضه سيكون صفرًا، وإن قمنا بالتركيز على مربع النص فإن عرض المحدّد .bar سيزداد. كما ستلاحظ فقد حدّدنا العرض ضمن الصنفين الكاذبين (:after و :before) حيث سيزداد العرض 50% لكل عنصر زائف، بمعنى أن الزيادة الكلية ستكون 100%، وهكذا سنحصل على تأثير توسّع جميل. .bar:before, .bar:after { content:''; height:3px; width:0; bottom:1px; position:absolute; transition:0.2s ease all; -moz-transition:0.2s ease all; -webkit-transition:0.2s ease all; } .bar:before { left:50%; } .bar:after { right:50%; } input:focus ~ .bar:before, input:focus ~ .bar:after { width:50%; } سنغيّر الآن لون خلفية الشريط حسب صحة أو عدم صحة البيانات المدخلة، وذلك باستخدام الصنفين الزائفين :valid و :invalid. input:valid ~ .bar:before, input:valid ~ .bar:after{ background:#2ecc71; } input:invalid ~ .bar:before, input:invalid ~ .bar:after{ background:#e74c3c; } تعمل هذه الطريقة على متصفحات (+Chrome(10 و (+Firefox(4 و (+Safari(5 و (+Opera(10 و (+IE(10، ولكن لا تعمل على الإصدار التاسع وما دونه من متصفح IE. وجدير بالذكر أنّه لن يتم التحقّق من صحة البيانات بأي شكل من الأشكال، ويمكن استخدام هذه الطريقة في مجال تجربة المستخدم فقط. ترجمة - وبتصرّف - للمقال Form validation in pure css لصاحبه Arkaprava Majumder.
  3. سنبدأ في هذا الدرس من سلسلة برمجة تطبيقات الأجهزة المحمولة باستخدام Xamarin بالتعرّف على بنية التطبيق ضمن الحل Solution في Visual Studio 2015، بالإضافة إلى إنشائنا لتطبيق بسيط نتعرّف من خلاله على آلية عمل التطبيقات المبنية بواسطة Xamarin والتي تشبه في العديد من الجوانب مثيلاتها المنشأة باستخدام التقنيّات الأساسيّة المعتمدة في إنشاء تطبيقات أندرويد (لغة جافا مع Android Studio). بنية التطبيق المنشأ باستخدام Xamarin شغّل برنامج Visual Studio 2015، وبعد ظهور النافذة الرئيسيّة انتقل إلى القائمة File ومنها إلى New ثم اختر من القائمة الفرعيّة التي ستظهر الخيار Project. وكما فعلنا في الدرس السابق، اختر من الجهة اليسرى للنافذة التي ستظهر Cross-Platform، ثمّ اختر المشروع (Blank App (Xamarin.Forms Portable من القسم الأوسط للنافذة. امنح هذا المشروع الاسم SimpleTextApp ثم انقر الزر OK. سنبني تطبيقًا بسيطًا يوضّح كيفيّة استخدام لُصيقة Label وحيدة في إظهار النص في التطبيقات المبنيّة باستخدام Xamarin. من مستكشف الحل Solution Explorer الذي يوجد عادةً في الجهة اليمنى لنافذة بيئة التطوير Visual Studio، أبقِ فقط على المشروعين SimpleTextApp.Droid و (SimpleTextApp (Portable لأنّنا سنتعامل مع تطبيقات أندرويد فحسب (كما اتفقنا أيضًا من الدرس السابق). احذف باقي المشاريع الإضافيّة، يجب أن تحصل على شكل شبيه بما يلي: يحتوي المشروع (SimpleTextApp (Portable على معظم الشيفرة البرمجيّة، وهذا سلوك عام في المشاريع ذات النمط PCL. حيث تُعتبر الشيفرة الموجودة ضمن المشروع (الذي يحمل المقطع Portable بالإضافة لاسمه) مشتركة لجميع أنواع التطبيقات العاملة على أيّ نظام تشغيل بما فيه أندرويد. نلاحظ الملف App.cs الأساسي الذي سيكون موجودًا في أيّ تطبيق Xamarin وقد تحدثنا عنه في الدرس السابق ورأينا كيف يحتوي على الصنف App الذي يرث من الصنف Application، وكيف أنّ بانية هذا الصنف هي المسؤولة عن إنشاء الصفحة الرئيسيّة للتطبيق. انشر العقدة References لترى المراجع الخاصّة بهذا المشروع. ستلاحظ وجود عدّة مكتبات يهمّنا منها: Xamarin.Forms.Core و Xamarin.Forms.Platform و Xamarin.Forms.Xaml هذه هي المكتبات الرئيسيّة المشكّلة لـ Xamarin.Forms. بالنسبة للمشروع SimpleTextApp.Droid فهو يحتوي على مجلّدين هما: Assets و Resources. بالنسبة للمجلّد Resources فيحتوي على ملفات الصور وملفات معلومات التخطيطات layouts descriptions وغيرها من الملفات التي تُعتبر بمثابة المصادر resources لتطبيقك. انشر المجلّد Resources لترى بنيته. أمّا بالنسبة للمجلّد Assets فتُوضَع ضمنه الملفات العامّة الأخرى التي ترغب بتضمينها مع تطبيقك. يحتوي هذا المشروع أيضًا على الملف MainActivity.cs الذي يحوي ضمنه صنف له نفس الاسم MainActivity وهو يمثّل الفعاليّة Activity الأساسيّة لتطبيق أندرويد. افتح هذا الملف لتجد أنّ هذا الصنف يحتوي على التابع OnCreate الذي يُنفَّذ عند بدء تشغيل تطبيق أندرويد. لاحظ العبارة البرمجيّة التالية ضمن هذا التابع: LoadApplication(new App()); من الواضح أنّها تنشئ كائنًا جديدًا من الصنف App الموجود ضمن المشروع (SimpleTextApp (Portable، ثم تمرّره إلى التابع LoadApplication مباشرةً ليعمل على تحميل التطبيق وإظهاره للمستخدم. إذًا فعند تشغيل تطبيق أندرويد، سينفّذ التابع OnCreate الموجود في الصنف MainActivity أولًا، حيث يعمل هذا التابع على إنشاء كائن جديد من الصنف App فينفّذ بانيته وهي المسؤولة عن إنشاء الصفحة الرئيسيّة للتطبيق كما أشرنا. على أيّة حال ستتوضّح الفكرة بشكل جيّد بعد أن نبدأ بكتابة الشيفرة البرمجيّة. كتابة الشيفرة البرمجية انقر بزر الفأرة الأيمن على اسم المشروع (SimpleTextApp (Portable في مستكشف الحل Solution Explorer لتظهر قائمة سياق، اختر منها Add ثمّ من القائمة الفرعيّة اختر Class. ستظهر النافذة الخاصّة بإضافة صنف جديد. من حقل الاسم Name من الأسفل اكتب الاسم التالي لهذا الصنف الجديد وهو MainPage، ثم انقر Add. سيعمل Visual Studio على إضافة ملف جديد إلى المشروع اسمه MainPage.cs يحتوي على صنف بنفس اسمه ومحتواه شبيه بما يلي: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SimpleTextApp { class MainPage { } } لن نحتاج إلى معظم نطاقات الأسماء الموجودة في الشيفرة السابقة في هذا البرنامج، سنحتاج حاليًا إلى نطاق الاسم Xamarin.Forms. وسنجعل الصنف MainPage يرث من الصنف ContentPage كما سنضيف البانية إليه. عدّل الشيفرة السابقة لتصبح على الشكل التالي: using Xamarin.Forms; namespace SimpleTextApp { class MainPage : ContentPage { public MainPage() { } } } لاحظ أنّني تخلصت من جميع نطاقات الأسماء غير الضرورية (على أية حال سيظهر أي نطاق اسم غير مُستَخدَم في الشيفرة البرمجيّة بلون باهت في بيئة التطوير Visual Studio 2015). سيلعب الصنف MainPage دور صفحة محتوى content page رئيسيّة للتطبيق SimpleTextApp. سنضع ضمن بانية هذا الصنف الشيفرة البرمجيّة اللازمة لإنشاء لُصيقة واحدة Label تحوي نصًّا بسيطًا. ثم سنجري بعض التجارب البسيطة على هذه اللُّصيقة. يُعتبر هذا البرنامج بسيطًا في الواقع، ومهمته جعلك أكثر تآلفًا مع Xamarin. سنبدأ بإنشاء لُصيقة من الصنف Label وذلك ضمن بانية الصنف MainPage. تُستخدم اللُصيقات عادةً لعرض النصوص إلى المستخدم. انظر إلى الشيفرة البسيطة التالية: Label lblMain = new Label(); lblMain.Text = "Welcome to Hsoub Academy!"; ننشئ لُصيقة كما ننشئ أيّ كائن من صنف ما. أنشأنا في الشيفرة السابقة كائنًا جديدًا من الصنف Label وأسندناه إلى المتغيّر lblMain. ثم أسندنا النص "!Welcome to Hsoub Academy" إلى الخاصيّة Text من المتغيّر lblMain. تُستَخدم الخاصية Text لضبط وقراءة المحتوى النصيّ للُّصيقة. كي نستطيع عرض اللُّصيقة السابقة على الصفحة الرئيسيّة للتطبيق، علينا إسناد المتغيّر lblMain إلى الخاصيّة Content من الصنف ContentPage. وبما أنّ الصنف MainPage يرث من ContentPage فستكون الخاصيّة Content موجودة تلقائيًّا ضمنه أيضًا. ستكون عمليّة الإسناد على الشكل التالي: this.Content = lblMain; تكون عمليّة الإسناد السابقة ممكنة لأنّ الصنف Label يرث من الصنف View الذي يمثّل واجهة عرض view بمفهومها العام. وبما أنّ الخاصيّة Content هي من النوع View أيضًا فتكون عمليّة الإسناد هذه ممكنة. ستكون محتويات الملف MainPage.cs شبيهة بما يلي: using Xamarin.Forms; namespace SimpleTextApp { class MainPage:ContentPage { public MainPage() { Label lblMain = new Label(); lblMain.Text = "Welcome to Hsoub Academy!"; this.Content = lblMain; } } } هذا كلّ شيء! علينا الآن القيام بخطوة صغيرة أخيرة، وهي في جعل تطبيقنا يُنشئ كائن من صنفنا الجديد MainPage وذلك ضمن الملف App.cs. انتقل إلى هذا الملف (موجود ضمن المشروع (SimpleTextApp (Portable واحرص على أن تكون بانية الصنف App على الشكل التالي: public App() { // The root page of your application MainPage = new MainPage(); } اضغط الآن المفتاح F5 لتنفيذ التطبيق، لتحصل على شكل شبيه بما يلي: ملاحظة يمكنك وصل جهازك المحمول الذي يعمل بنظام أندرويد إلى الحاسوب لتجريب تشغيل التطبيق عليه مباشرةً. ولكن في هذه الحالة ينبغي أن تتوفّر واجهة برمجيّة API منصّبة على حاسوبك مناسبة لنسخة أندرويد الموجودة على الجهاز المحمول. على أية حال يمكنك تنصيب هذه الواجهة في حال عدم وجودها من خلال Android SDK Manager كما أشرنا في الدرس السابق. كما أنصح بوصل الجوال قبل تشغيل بيئة التطوير Visual Studio، أو أن تعيد تشغيلها إذا كانت تعمل من قبل. تنسيق الشيفرة البرمجية بشكل أفضل في الحقيقة لا تُعتبر الشيفرة البرمجيّة الموجودة ضمن الملف MainPage.cs مثاليّةً رغم بساطتها. ربما لا تشعر بمشكلة الآن، ولكن عندما تصبح برامجك أكبر، ستقع في مشاكل حقيقيّة لأنّ الأسلوب السابق بكتابة الشيفرة يجعلها كبيرة جدًّا. سأستخدم ميّزة الإسناد المباشر للخصائص أثناء إنشاء الكائنات. تفيد هذه الميزة في الاستغناء عن معظم المتغيّرات في البرنامج، التي ينحصر دورها في لعب دور الوسيط المؤقّت. سنعيد صياغة الشيفرة الموجودة في الملف MainPage.cs بشكل أنيق وعمليّ أكثر: using Xamarin.Forms; namespace SimpleTextApp { class MainPage : ContentPage { public MainPage() { this.Content = new Label{ Text = "Welcome to Hsoub Academy!" }; } } } لاحظ أنّني استغنيت عن المتغيّر lblMain لأنّنا أسندنا كائن اللُّصيقة مباشرةً إلى الخاصيّة Content. مزايا إضافية على التطبيق ستلاحظ من التطبيق السابق أنّ اللُّصيقة تظهر في الزاوية اليسرى العليا من النافذة. سنجعلها تظهر في مركز الشاشة. ينبغي ضبط خاصيّتين من خصائص اللُّصيقة لهذا الغرض، وهما HorizontalOptions (لخيارات المحاذاة الأفقيّة) و VerticalOptions (لخيارات المحاذاة الرأسيّة). كل من هاتين الخاصيّتين من النوع LayoutOptions، وهي بنية struct موجودة ضمن نطاق الاسم Xamarin.Forms. تحتوي هذه البنية على عدّة حقول جاهزة تُفيد في خيارات التموضع الأفقيّة والرأسيّة للُّصيقة، وهي خيارات مهمّة للغاية كما سنرى لاحقًا في هذه السلسلة. لنجري الآن التعديل المطلوب على اللُّصيقة الموجودة ضمن بانية الصنف MainPage. ستصبح محتويات الملف MainPage.cs على الشكل التالي: using Xamarin.Forms; namespace SimpleTextApp { class MainPage : ContentPage { public MainPage() { this.Content = new Label{ Text = "Welcome to Hsoub Academy!", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }; } } } لاحظ إسناد القيمة LayoutOptions.Center لكل من الخاصّتين HorizontalOptions و VerticalOptions وذلك للتوسيط الأفقي والرأسي على الترتيب. نفّذ البرنامج مرّة أخرى ستلاحظ أنّ اللُّصيقة أصبحت في مركز الشاشة كما هو واضح من الشكل التالي: أمّا إذا أحببت أن يكون النص ضمن اللُّصيقة بلون آخر، وليكن الأحمر مثلًا، فعليك في هذه الحالة إسناد القيمة Color.Red للخاصيّة TextColor لكائن اللُّصيقة، علمًا أنّ Color هو بنية موجودة ضمن نطاق الاسم Xamarin.Forms أيضًا. انظر كيف نفعل ذلك في الشيفرة: this.Content = new Label{ Text = "Welcome to Hsoub Academy!", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center, TextColor = Color.Red }; نفّذ البرنامج مرّة أخرى، لترى النص وقد أصبح لونه أحمر. الخلاصة تعرّفنا في هذا الدرس على البنية العامة لتطبيق Xamarin ضمن بيئة التطوير Visual Studio 2015. كما قمنا ببناء تطبيق بسيط للغاية أسميناه SimpleTextApp. تنحصر وظيفة هذا التطبيق في التّعرف أكثر على Xamarin. سنبدأ اعتبارًا من الدرس القادم ببناء تطبيقات متدرّجة في الصعوبة، وذات مزايا إضافيّة من الممكن أن تستفيد منها كمبرمج تطبيقات محمولة في حياتك العمليّة.
  4. هنالك عدّة طرق لجمع عناوين البريد الإلكتروني على موقع ما، لكن ما هو أكثر الخيارات فعاليّة من بين السّلايدر Sliders، النّوافذ المنبثقة Lightboxes والتبويبات Tabs، ونماذج الاشتراك العاديّة؟ ولماذا؟ سنتعرّف على تقنيات بناء القوائم الخاصة بثلاث خدمات معروفة. رغم كلّ هذه الخيارات، هنالك خيار واحد فقط يمكن لمصمّمي المواقع ومدراء المواقع اختياره. لذا، ومن أجل فهم أفضل لكلّ نوع من النماذج، جمعنا 3 أشخاص يعملون ضمن أشهر نماذج التسجيل المُدمجة بالنسبة لنا وهم: Claudiu Murariu من خدمة PadiAct، Noah Kagan من خدمة AppSumo وMatt Farmer من خدمة Anchor Tab، لنطلب منهم شرح الخدمات الأفضل والسّبب الذي يجعلها كذلك. 3 أنواع من النماذج والهدف واحدعند تقرير نوع النموذج التي يجدر بك استخدامه على موقعك، سيوافق معظم النّاس غالبًا على أنّ الهدف واحد، وهو جمع أكبر عدد ممكن من التّسجيلات الجديدة في قوائم اشتراكك، لكن هنالك أشياء يجب أخذها بعين الاعتبار خلال هذه العملية، منها: ألّا تزعج هذه العمليّة أو تقاطع زوّار الموقع، خصوصًا الذين يزورون الموقع عبر جهاز محمول أو الذين سجّلوا بالفعل.ألّا يتمّ إرغام النّاس على التّسجيل من أجل الحصول على ما يريدونه.ألّا تؤثّر هذه العمليّة على سرعة الموقع بشكل مفرط.دعونا نستعرض كيفيّة عمل كل نموذج مع أخذ هذه المتطلّبات بعين الاعتبار. السلايدرز: Claudiu Murariu من PadiAct مبدأ العمل: كلّما ذهبت إلى متجر بيع الملابس المفضّل لديك وبدأت بالبحث عن شيء لشرائه ولا تجد ما يناسب مقاساتك بشكل مثالي، تصبح المساعدة التي سيقدّمها لك موظّف المتجر الودود –الحاضر دائمًا- محلّ ترحيب، وهو نفس الشّيء الذي تفعله السّلايدرز، فمثل موظف المتجر، إذا ظهرت نموذج في نفس الوقت الذي يدخل فيه زائر إلى موقعك، ستجد غالبًا أنك تفقد الزّوار قبل تصفّحهم لموقعك حتّى، لكن في حال ظهور السلايدر في الوقت المناسب وبالمحتوى المناسب، فلن يرى معظم الزوار السلايدر وإنما الرسالة التي يحملها لهم، في هذه الحالة، يكون تقديم عنوان البريد الإلكتروني إجراءً شكليًّا حيث يودّون البقاء على اتصال بك. ما مدى جودتها: يمكن للسّلايدرز زيادة معدل الاشتراكات بنسبة 15% فما فوق، حيث جمعنا 3.5 مليون بريد إلكتروني من خلالها بفضل ظهورها في الوقت المناسب مع رسالة مخصّصة حسب سلوك الزّوار، دون أي تأثير على أداء مقاييس مثل معدّلات التّحويل، نسبة الخروج من الموقع، الوقت الذي تمّ قضاؤه على الموقع وعدد الصّفحات التي تمّ زيارتها. تكون السّلايدرز فعّالة للغاية عندما تكون مستهدفة، لأنّها لا تضع جميع المستخدمين في نفس الكفّة، بل تتيح للمستخدمين تكوين فكرة عن الموقع قبل أن يقرروا الاشتراك، كما تقدّم السّلايدرز سهولة كبيرة للمستخدمين كونهم لا يحتاجون للبحث عن نموذج الاشتراك بأنفسهم. النوافذ المنبثقة: Noah Kagan من SumoMe مبدأ العمل:أعتقد أنّ نوافذ البريد الإلكتروني المنبثقة التي تظهر على المواقع مزعجة للغاية، لكنّها تعتبر كذلك أنجع طريقة للحصول على اشتراكات بريد إلكتروني جديدة. دعونا نسقط هذه النوافذ المنبثقة على أرض الواقع. لنقل أنّك ذهبت إلى مطعم ولم يعجبك الطعام المقدم هناك، ثم طُلب منك إدخال بريدك الإلكتروني من أجل نشرة المطعم البريدية، فأدخلت بريدك الإلكتروني وبدؤوا بمراسلتك يوميًّا لأسابيع، هل سيكون لبريدهم الإلكتروني تأثير عليك باستثناء زيادة كرهك تجاههم؟ طبعًا لا، فأنت لن تعود أبدًا إلى ذلك المكان ولن توصي غالبًا أشخاصًا آخرين بالذّهاب إليه. لنقل الآن أنّ هنالك مطعمًا يعجبك، وستعود له غالبًا، لكنك تنسى أحيانًا الذّهاب إليه، هنا سيكون تذكير ودّي بالذّهاب إلى المطعم مفيدًا لك. هذه هي فكرتي حول نوافذ البريد الإلكترونيّ المنبثقة، يكون تذكّر موقعك من طرف الزّوار أو العملاء صعبًا أحيانًا وسط كلّ الخيارات الأخرى المتوفّرة، وقد لا يرون طريقة أخرى لإعطائك عناوين بريدهم الإلكتروني، عندها تكون النّوافذ المنبثقة أكثر الطّرق فعاليّة حسب ما وجدت. أشجّع النّاس على تجربة هذا الخيار مادامت منتجاتهم رائعة ومحتوى مدوناتهم ممتاز. ما مدى جودتها: هذا هو عدد الاشتراكات التي حصل عليها موقع Okdork باستخدام النّوافذ المنبثقة لخدمة بناء القائمة على موقع SumoMe.com (موضحة في الجدول أدناه). لا أحاول تحسين الخدمة للحصول على أكبر قدر ممكن من الاشتراكات البريديّة لكنني أقترحها بودّ على الزّوار للاشتراك في نشرتي البريديّة. التاريخ المشتركون النّوافذ التي ظهرت معدّل التّحويل 04/10 26 754 3.45% 04/11 31 950 3.26% 04/12 14 568 4.46% 04/13 19 578 3.29% 04/14 24 1,005 2.39% التبويبات: Matt Farmer من AnchoTabمبدأ العمل:عندما يأتي زائر إلى موقعك، يكون هدفه غالبًا محدّدًا بالفعل، حيث يكون هدف معظم الزّوار الحصول على معلومة ما حول منتجك أو قراءة محتوى مدونتك، من جهة أخرى، فأنت كذلك كمدير موقع لديك هدف معيّن؛ تحويل الزّائر إلى قارئ منتظم أو عميل تستفيد منه مادّيًّا، وهكذا تكون في مواجهة معضلة لطالما عانى منها الباعة لعقود من الزمن، لنأخذ مثال بائع السيّارات، تجد البائع الانتهازيّ الذي يكون دائمًا على استعداد لفعل أي شيء باستطاعته من أجل تحقيق هدفه ببيع سيارة، إذ أنّه لا يأبه إن كان أسلوبه مريحًا أو غير مريح لك، وسيستمرّ باللّحاق بك والحديث وفعل أي شيء لجعلك تشتري. ويعدّ هذا شبه مثاليّ لاستراتيجيّة جلب عناوين البريد الإلكترونيّ التي تشتمل على إظهار نافذة منبثقة شكليّة تتمركز فوق محتواك وتجبر الزّائر على أن يقرّر ما إذا كان يودّ الاشتراك أم لا، لكنّ التّبويبات تحقّق توازنًا نسمّيه بالبائِع المُفيد، حيث لا تظهر التّبويبات أمامك مباشرة، أو تتحدّث إليك طوال الوقت الذي تكون فيه منكبًّا في محاولة تحقيق هدفك، لكنّها تكون متواجدة هنالك دائمًا. ما مدى جودتها: تمّ تحسين التّبويبات بشكل خاص للمدوّنات التي تحتوي على الكثير من المحتوى النّصي، فعند الصعود لأعلى الصّفحة من الأسفل، سيلاحظ القرّاء ظهور التّبويبة لكنّهم غير ملزمين بالتّوقف عن القراءة من أجل التّفاعل معها، كما أن عينهم تتحرّك طبيعيًّا نحو التبويبة التّالية عند انتهائهم من قراءة المقال. هذه الاستراتيجية تتيح لك الموازنة بين الرّغبة في ظهور النموذج بشكل بارز وإخفائها ضمنيًّا بحيث يكاد القرّاء لا يشعرون بها، وبالتّالي تكون قادرًا على تحقيق هدفك بالحصول على اشتراكات لبريدك الإلكتروني دون الاستعانة بتقنيّات تعرقل وصولك إلى هدفك. لاحظنا باستخدام هذه الطّريقة الأقلّ تطفّليّة معدّلات تحويل متواصلة بنسبة 1.25%، ما يجعلنا قريبين من الحلول الأخرى المنافِسة. مع التّحديث الكبير المنتظر لخدمة Anchor Tab، سيحصل "مساعِدنا المفيد" على أدوات أكثر لمساعدة عملائنا على رفع ذلك الرقم أكثر. أيها تستخدم؟بعد اطّلاعنا على الخيارات الأخرى المتاحة غير الخيارات المعهودة، حان وقت اختيارك للخدمة التي تناسبك، فأيّ نوع من نماذج الاشتراك ستختار أو أيّ نوع استخدمته وحقّق لك نجاحًا على موقعك؟ ترجمة -وبتصرّف- للمقال Subscribe form showdown: Do sliders, lightboxes or tabs work best? لصاحبته ROS HODGEKISS. حقوق الصورة البارزة: Designed by Freepik.
  5. بعد أن انتهينا من إعداد قواعد البيانات والطرق (routes)، سوف نتحدث في هذا الجزء عن المتحكِّمات (Controllers)، النماذج (مع العلاقات)، والعروض views. (بما في ذلك نظام blade ومخططات المحتوى). مساعدات النماذج Form Helpers في Laravelبعد كل هذه الإعدادات، إذا ذهبنا الآن (في المتصفح) إلى projects/ فسوف نحصل على صفحة فارغة فما هو السبب؟ حسنا، لنكتشف ذلك، قم بتنفيذ الأمر php artisan route:list على سطر الأوامر مرة أخرى وأنظر إلى هذا السطر: +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+ | | GET|HEAD | projects | projects.index | App\Http\Controllers\ProjectsController@index | | +--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+يبدو أن رابط projects/ يقوم بتحميل الوظيفة Index الخاصة بـ ProjectsController، لذلك سنقوم بفتح app/Http/controllers/ProjectsController.php/ وسنقوم بتحديث التابع (method) لنقوم بربطه إلى عرض سوف نقوم بإنشائه. قم بإضافة السطر ;('return view('projects.index إلى الوظيفة ()index كالتالي: public function index() { return view('projects.index'); }بما أننا نستخدم في هذا الدرس نظام Blade للقَوْلَبة سنقوم بإنشاء ملف resources/views/projects/index.blade.php/ وسنكتب نص قصير داخله، ثم سنقوم مرة أخرى بالذهاب إلى projects/ في المتصفح، إذا كان كل شيء يعمل جيدا فسوف تجد النص الذي كتبته بالأعلى. والآن قُم بنفس الشيء لتابع المتحكِّم create عن طريق إضافة السطر ;('return view('projects.create إلى التابع ()create كالتالي: public function create() { return view('projects.create'); }إن إظهار محتويات العرض view هو أمر رائع، لكن ماذا لو كنا نملك أكثر من صفحة واحدة في موقعنا ؟ في هذه الحالة، سوف نحتاج إلى قالب ثابت لجميع الصفحات، أي أننا نحتاج إلى عرض محتويات العرض view داخل قالب HTML بسيط، وسنقوم بهذا عن طريق مخططات المتحكِّمات. من أجل عمل مخططات المتحكِّمات سنقوم بالخطوات التالية: إنشاء مخطط العرض، وبما أن Laravel توفر لنا واحدة جيدة تدعى app.blade.php لذلك سنوفر الوقت وسنقوم بإستخدامها. لاحظ أن قرب أسفل المخطط هنالك سطر ('@yield('content وهذه دالة ستقوم بتحميل محتوانا الحالي.الإشارة إلى مخططك في عرضك view باستخدام ('extends('app@ ولفها عن طريق كتلة ('section('content@، مثل التالي: @extends('app') @section('content') This is my /resources/views/projects/index.blade.php file! @endsection سنقوم الآن بتنفيذ هذه الخطوات بإنشاء عروض show.blade.php و create.blade.php و index.blade.php في مجلد resources/views/projects/ مع الشيفرات (markup) المذكورة أعلاه وقُم بتغيير اسم الملف إذا كان الأمر ضروريا، ثم قُم بعمل تحديث للصفحة projects/ في متصفحك، وسوف ترى هيكل app.blade.php حول محتويات عرضك (view). الربط بين الطريق (route) والنموذجسيوفر Laravel بشكل افتراضي معرف رقمي ID للعديد من توابع متحكِّمات الموارد مثل ()show و ()edit و ()update و ()destroy، وهذا الأمر سيضيف العديد من الشيفرات الجاهزة (boilerplate) التي نحتاج إلى كتابتها، مثل الحصول على مثيل النموذج والتأكد من وجودها وغيرها. ولهذا سوف نستخدم إحدى مميزات Laravel والتي تدعى الربط بين الطريق و النموذج route model binding، فبدل من توفير متغير id$، سوف نقوم بإعطاء الوظيفة (method) كائن project$ أو task$. قُم بفتح app/Http/routes.php/ وأضف هذين السطرين (أول سطرين بعد التعليق): // Provide controller methods with object instead of ID Route::model('tasks', 'Task'); Route::model('projects', 'Project'); // Use slugs rather than IDs in URLs Route::bind('tasks', function($value, $route) { return App\Task::whereSlug($value)->first(); }); Route::bind('projects', function($value, $route) { return App\Project::whereSlug($value)->first(); }); Route::resource('projects', 'ProjectsController'); Route::resource('projects.tasks', 'TasksController'); وفي TasksController و ProjectsController (ملفات app/Http/Controllers/ProjectsController.php/ و app/Http/Controllers/TasksController.php/) قُم باستبدال كل وظيفة (method) مُعرف بمرجع id$ بـ task$ أو project$ مثل التالي: // public function edit($id) public function edit(Project $project)لا تنسَ إضافة use App\Task و use App\Project في أعلى المتحكِّمات حتى نشير إلى هذه النماذج. لا تقلق إذا لم تفهم هذه التغييرات، فسنقوم بعرض الشيفرة البرمجة الكاملة لـ TasksController و ProjectsController لاحقا. وفي هذه المرحلة يمكنك تمرير الكائن (object) إلى عرضه في كل متحكِّم لوظيفة (method) الإظهار والتعديل والتحديث حتى نستطيع استخدامهم لاحقا: public function edit(Project $project) { return view('projects.show', compact('project')); }سوف يحتاج TasksController إلى بضعة تعديلات طفيفة أخرى، وبما أننا نستخدم الموارد المضمّنة nested resources، سيخبرنا php artisan route:list أن جميع طرق task تحتوي على قناع {projects} بالإضافة إلى أن بعضها يستقبل قناع {tasks} أيضا. و كنتيجة لذلك، سيتم تمرير مثيل Project كمُعامل أول لتوابع المتحكِّمات (controller methods)، لذلك قُم بتحديثها وقٌم بتمرير متغير project$ الجديد. إذا لم تفهم خطوات الإضافة لـ TasksController و ProjectsController فهذه هي الشيفرة الكاملة للملفين بعد كل التعديلات: // /app/Http/Controllers/ProjectsController.php <?php namespace App\Http\Controllers; use App\Project; use App\Http\Requests; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class ProjectsController extends Controller { /** * Display a listing of the resource. * * @return Response */ public function index() { $projects = Project::all(); return view('projects.index', compact('projects')); } /** * Show the form for creating a new resource. * * @return Response */ public function create() { return view('projects.create'); } /** * Store a newly created resource in storage. * * @return Response */ public function store() { // } /** * Display the specified resource. * * @param \App\Project $project * @return Response */ public function show(Project $project) { return view('projects.show', compact('project')); } /** * Show the form for editing the specified resource. * * @param \App\Project $project * @return Response */ public function edit(Project $project) { return view('projects.edit', compact('project')); } /** * Update the specified resource in storage. * * @param \App\Project $project * @return Response */ public function update(Project $project) { // } /** * Remove the specified resource from storage. * * @param \App\Project $project * @return Response */ public function destroy(Project $project) { // } } // /app/Http/Controllers/TasksController.php <?php namespace App\Http\Controllers; use App\Project; use App\Task; use App\Http\Requests; use App\Http\Controllers\Controller; use Illuminate\Http\Request; class TasksController extends Controller { /** * Display a listing of the resource. * * @param \App\Project $project * @return Response */ public function index(Project $project) { return view('tasks.index', compact('project')); } /** * Show the form for creating a new resource. * * @param \App\Project $project * @return Response */ public function create(Project $project) { return view('tasks.create', compact('project')); } /** * Store a newly created resource in storage. * * @param \App\Project $project * @return Response */ public function store(Project $project) { // } /** * Display the specified resource. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function show(Project $project, Task $task) { return view('tasks.show', compact('project', 'task')); } /** * Show the form for editing the specified resource. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function edit(Project $project, Task $task) { return view('tasks.edit', compact('project', 'task')); } /** * Update the specified resource in storage. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function update(Project $project, Task $task) { // } /** * Remove the specified resource from storage. * * @param \App\Project $project * @param \App\Task $task * @return Response */ public function destroy(Project $project, Task $task) { // } }لاحظ أنه إذا قمت بتحديث صفحة projects/project-1/ سيبقى كل شيء يعمل. عرض نماذجناصفحة عرض قائمة المشاريع، حان الآن وقت البدء بعرض المشاريع والمهام، قٌم بفتح projects/ في متصفحك. وبالاعتماد على php artisan route:list، ستكون هذه الصفحة هي صفحة عرض المشاريع، لذلك قُم بفتح resources/views/projects/index.blade.php/ وأضف التالي: @extends('app') @section('content') <h2>Projects</h2> @if ( !$projects->count() ) You have no projects @else <ul> @foreach( $projects as $project ) <li><a href="{{ route('projects.show', $project->slug) }}">{{ $project->name }}</a></li> @endforeach </ul> @endif @endsectionسوف أشرح بعض النقاط في هذه الشفرة البرمجية: استخدمنا في هذه الشفرة لغة Blade للقَوْلَبة، لذلك فإن if و foreach تتحكم في تدفق flow الدوال بإضافة إلى أنها دالة طباعة (الأقواس المعقوفة المزدوجة).تأكدنا إن كان هنالك أي مشروع لعرضه، إن كان هنالك أية مشاريع فسيقوم بعرضها وإن لم يكن تظهر رسالة تخبرك بذلك.استدعينا مساعد ()route مع طريق ذا اسم (يمكنك رؤية قائمة الطرق ذات الاسم عن طريق php artisan route:list) لربط كل مشروع مع صفحة تفاصيله.سوف تحتاج أيضا إلى تمرير متغير projects$ لهذا العرض view وإلا ستحصل على خطأ متغير غير معرف undefined variable error. قُم بفتح app/Http/controllers/ProjectsController.php/ وقُم بتحديث الوظيفة ()index إلى: public function index() { $projects = Project::all(); return view('projects.index', compact('projects')); }قُم بتحديث الصفحة (Refresh) وستجد قائمة من مشاريعك. علاقات النموذج - صفحة تفاصيل المشروعفي صفحة تفاصيل المشروع نحتاج إلى عرض قائمة من مهام المشاريع، وللقيام بذلك نحتاج إلى تعريف علاقة "واحد إلى الكثير one-to-many" في نموذج Project للسماح له بالحصول على المهام tasks. قُم بفتح app/Project.php/ وأضف التابع ()tasks كالتالي: public function tasks() { return $this->hasMany('App\Task'); }بشكل عكسي، يمكننا إضافة علاقة "الكثير إلى واحد many-to-one" لنموذج المهام Task: public function project() { return $this->belongsTo('App\Project'); }للتأكد من أنها تعمل اكتب الأمر: $ php artisan tinkerوستكون النّتيجة كالتي حسب المدخلات: >App\Project::whereSlug('project-1')->first()->tasks->count(); 5 >App\Project::whereSlug('project-2')->first()->tasks->count(); 2 >App\Task::first()->project->name; Project 1ممتاز، يمكننا الآن تحديث عرض resources/views/projects/show.blade.php/: @extends('app') @section('content') <h2>{{ $project->name }}</h2> @if ( !$project->tasks->count() ) Your project has no tasks. @else <ul> @foreach( $project->tasks as $task ) <li><a href="{{ route('projects.tasks.show', [$project->slug, $task->slug]) }}">{{ $task->name }}</a></li> @endforeach </ul> @endif @endsectionاضغط على أي مشروع في صفحة عرض قائمة المشاريع في متصفحك وسوف يتم عرض المشروع مع جميع المهام المرتبطة به. وأخير تَبقى لدينا صفحة عرض المهام (resources/views/tasks/show.blade.php/)، وهذه سهلة للغاية: @extends('app') @section('content') <h2> {!! link_to_route('projects.show', $project->name, [$project->slug]) !!} - {{ $task->name }} </h2> {{ $task->description }} @endsectionملاحظة: كُن حذرا عندما تستخدم علاقات النماذج (models)، فإنه من السهل إنشاء عدد كبير من استعلامات SQL، وتسمى هذه المشكلة بـ "مشكلة N+1". الخاتمةاليوم تعلمنا الكثير من الأشياء الجديدة مثل: الربط بين الطريق (route) و النموذجالنماذج (مع علاقة واحد إلى الكثير one-to-many)المتحكِّمات (مع الربط بين الطريق و النموذج)العروض (مع لغة blade للقَوْلَبة والمخططات)أصبحت الصفحة تعرض لنا قائمة من المشاريع والمهام، وفي الدرس القادم سوف نركز على تعديل وإضافة وحذف المشاريع والمهام. ترجمة -وبتصرّف- للمقال Creating a Basic ToDo Application in Laravel 5 – Part 2. حقوق الصورة البارزة: Designed by Freepik.
  6. حتى الآن تعلمنا كيفية تثبيت وإعداد Laravel، بالإضافة إلى أننا قمنا بـإعداد بعض موارد المشاريع والمهام وعرضهم للمستخدم. في هذا الدرس، سنتعلم كيفية إنشاء وتعديل وحذف الصفحات والإجراءات. إضافة روابط التصفحقبل أن نفعل أي شيء، سنقوم بإضافة روابط create/edit/delete/back إلى صفحات المشاريع والمهام: <!-- /resources/views/projects/index.blade.php --> @extends('app') @section('content') <h2>Projects</h2> @if ( !$projects->count() ) You have no projects @else <ul> @foreach( $projects as $project ) <li> {!! Form::open(array('class' => 'form-inline', 'method' => 'DELETE', 'route' => array('projects.destroy', $project->slug))) !!} <a href="{{ route('projects.show', $project->slug) }}">{{ $project->name }}</a> ( {!! link_to_route('projects.edit', 'Edit', array($project->slug), array('class' => 'btn btn-info')) !!}, {!! Form::submit('Delete', array('class' => 'btn btn-danger')) !!} ) {!! Form::close() !!} </li> @endforeach </ul> @endif <p> {!! link_to_route('projects.create', 'Create Project') !!} </p> @endsection <!-- /resources/views/projects/show.blade.php --> @extends('app') @section('content') <h2>{{ $project->name }}</h2> @if ( !$project->tasks->count() ) Your project has no tasks. @else <ul> @foreach( $project->tasks as $task ) <li> {!! Form::open(array('class' => 'form-inline', 'method' => 'DELETE', 'route' => array('projects.tasks.destroy', $project->slug, $task->slug))) !!} <a href="{{ route('projects.tasks.show', [$project->slug, $task->slug]) }}">{{ $task->name }}</a> ( {!! link_to_route('projects.tasks.edit', 'Edit', array($project->slug, $task->slug), array('class' => 'btn btn-info')) !!}, {!! Form::submit('Delete', array('class' => 'btn btn-danger')) !!} ) {!! Form::close() !!} </li> @endforeach </ul> @endif <p> {!! link_to_route('projects.index', 'Back to Projects') !!} | {!! link_to_route('projects.tasks.create', 'Create Task', $project->slug) !!} </p> @endsectionهذه الشفرة البرمجية مفهومة، الصعوبة تكمن في رابط الحذف، متحكِّمات الموارد تتطلب إرسال وظيفة HTTP DELETE، وهذا لا يمكن أن يتم مع رابط عادي، لذلك يتطلب نموذج يتم تقديمه إلى طريق route محدد. للمزيد من المعلومات قُم بزيارة إجراءات يتم التحكم بها عن طريق متحكِّمات الموارد. إنشاء صفحات الإضافة والتعديلبعد الانتهاء من صفحات عرض قائمة المشاريع، نحتاج إلى إمكانية إضافة وحذف المشاريع والمهام. استمارات الإضافة والحذف ستكون متشابهة كثيرا، لذلك بدلا من تكرارهم، سنقوم بوراثتهم من نموذج واحد. سوف نبدأ مع عروض create/edit للمشروع: <!-- /resources/views/projects/create.blade.php --> @extends('app') @section('content') <h2>Create Project</h2> {!! Form::model(new App\Project, ['route' => ['projects.store']]) !!} @include('projects/partials/_form', ['submit_text' => 'Create Project']) {!! Form::close() !!} @endsection <!-- /resources/views/projects/edit.blade.php --> @extends('app') @section('content') <h2>Edit Project</h2> {!! Form::model($project, ['method' => 'PATCH', 'route' => ['projects.update', $project->slug]]) !!} @include('projects/partials/_form', ['submit_text' => 'Edit Project']) {!! Form::close() !!} @endsectionقُم بعمل نفس الشيء مع المهام لكن لا تنسَ تحديث الطرق (routes): <!-- /resources/views/tasks/create.blade.php --> @extends('app') @section('content') <h2>Create Task for Project "{{ $project->name }}"</h2> {!! Form::model(new App\Task, ['route' => ['projects.tasks.store', $project->slug], 'class'=>'']) !!} @include('tasks/partials/_form', ['submit_text' => 'Create Task']) {!! Form::close() !!} @endsection <!-- /resources/views/tasks/edit.blade.php --> @extends('app') @section('content') <h2>Edit Task "{{ $task->name }}"</h2> {!! Form::model($task, ['method' => 'PATCH', 'route' => ['projects.tasks.update', $project->slug, $task->slug]]) !!} @include('tasks/partials/_form', ['submit_text' => 'Edit Task']) {!! Form::close() !!} @endsectionالآن توجد عدة مفاهيم جديدة: إضافة جزئيةالاستمارة تتطلب عدة وسوم، وبدلا من ذلك سنقوم بتقسيمها من جزئية _form ونضعها مباشرة في العرض، استمارة Add هي من نوع POST ترسل البيانات إلى طريق projects.store واستمارة Edit هي من نوع PATCH وترسل البيانات إلى projects.update. قد يبدوا هذا معقدا ومبهم لكن هذه هي الطريقة التي تعمل بها المتحكِّمات. لاحظ أننا استخدمنا ()Form::model، وتسمى هذه نموذج الاستمارة الملزمة و ليس لدى هذه أهمية كبيرة الآن، فهي تُستخدم للتعبئة التلقائية وسوف نحتاجها في وقت لاحقا عندما نضيف الحقول باستخدام ()Form::input.الحماية من CSRF:مساعدي الاستمارة (Form helpers) توفر العديد من الوظائف مجانا، فإذا ذهبت إلى projects/create/ ورأيت مصدر الصفحة ستجد شيئا مشابها لهذا: <form method="POST" action="http://l4todo.localhost.com/projects" accept-charset="UTF-8"> <input name="_token" type="hidden" value="Y8uOo7SeD5tQZExezDf5a7UwiYR4P6qIHEUKJNxI"> </form>هل ترى حقل token_ ؟ هذا هو الرمز المميز لـ CSRF مُنشئ تِلقائيا بواسطة استدعاء {{ ()Form::model }} الذي يمنع ثغرة CSRF. يكفي أن نقول أن هذا شيئ مفيد وأننا لم نقم بأي شيئ للحصول عليه. إنشاء استمارة التعديلنحن بحاجة إلى ترميز (markup) الاستمارة للمشاريع والمهام، وبفضل نموذج الاستمارة الملزمة يمكننا فقط استخدام مساعدي الاستمارة في Laravel لإخراج كافة الحقول التي نحتاجها. <!-- /resources/views/projects/partials/_form.blade.php --> <div class="form-group"> {!! Form::label('name', 'Name:') !!} {!! Form::text('name') !!} </div> <div class="form-group"> {!! Form::label('slug', 'Slug:') !!} {!! Form::text('slug') !!} </div> <div class="form-group"> {!! Form::submit($submit_text, ['class'=>'btn primary']) !!} </div> <!-- /resources/views/tasks/partials/_form.blade.php --> <div class="form-group"> {!! Form::label('name', 'Name:') !!} {!! Form::text('name') !!} </div> <div class="form-group"> {!! Form::label('slug', 'Slug:') !!} {!! Form::text('slug') !!} </div> <div class="form-group"> {!! Form::label('completed', 'Completed:') !!} {!! Form::checkbox('completed') !!} </div> <div class="form-group"> {!! Form::label('description', 'Description:') !!} {!! Form::textarea('description') !!} </div> <div class="form-group"> {!! Form::submit($submit_text) !!} </div>هذا كل شيئ، سوف تستطيع الأن التصفح في صفحات الإضافة والتعديل، الأمر كان سهلا للغاية. جعل الاستمارات تعمللدينا استمارات الإضافة والتعديل للمشروع و المهام، بالإضافة إلى استمارة مُضللة لحذفهم، الآن يجب علينا أن نجعلهم يعملون لأداء مهامهم. أولا، أضف هذا في أعلى المتحكِّمات: use Input; use Redirect;والآن لوظائف store و update و destroy: // ProjectsController public function store() { $input = Input::all(); Project::create( $input ); return Redirect::route('projects.index') ->with('message', 'Project created'); } public function update(Project $project) { $input = array_except(Input::all(), '_method'); $project->update($input); return Redirect::route('projects.show', $project->slug) ->with('message', 'Project updated.'); } public function destroy(Project $project) { $project->delete(); return Redirect::route('projects.index')->with('message', 'Project deleted.'); } // TasksController public function store(Project $project) { $input = Input::all(); $input['project_id'] = $project->id; Task::create( $input ); return Redirect::route('projects.show', $project->slug) ->with('message', 'Task created.'); } public function update(Project $project, Task $task) { $input = array_except(Input::all(), '_method'); $task->update($input); return Redirect::route('projects.tasks.show', [$project->slug, $task->slug]) ->with('message', 'Task updated.'); } public function destroy(Project $project, Task $task) { $task->delete(); return Redirect::route('projects.show', $project->slug)->with('message', 'Task deleted.'); }الشفرة البرمجية في الأعلى مفهومة ولا داعي لشرحها. إذا قمت الآن بتقديم إحدى الاستمارات فسوف تحصل على خطأ MassAssignmentException: _token، فالإحالة الكتلية تحدث عندما تقوم بتمرير مصفوفة بيانات إلى ()Model::create أو ()Model::update من المتحكِّمات بدل من وضع حقل واحد في نفس الوقت، ولإصلاح هذا، قم ببساطة بإضافة خاصية guarded إلى كل نموذج. class Project extends Model { protected $guarded = []; class Task extends Model { protected $guarded = [];رسائل الفلاشسوف تلاحظ من الشفرة السابقة أننا استخدمنا دالة ()with، وهذه الدالة تقوم بتمرير متغير فلاش (يستخدم لمرة واحدة) للجلسة session والتي يمكن قراءتها عند تحميل الصفحة التالية. والآن نحتاج إلى التأكد من تلك الرسالة وعرضها على المستخدم. قُم بفتح resources/views/app.blade.php/ وأضف التالي: ... <div class="content"> @if (Session::has('message')) <div class="flash alert-info"> <p>{{ Session::get('message') }}</p> </div> @endif @yield('content') </div> ...حاول إنشاء مشروع، هذه الرسالة ستظهر مهما حدّثت الصفحة وستذهب بعد فترة. خاتمةاليوم قمنا بأشياء مثيرة للغاية، فلقد أضفنا استمارات الإضافة والتعديل والحذف وتعلمنا حول CSRF و نموذج الاستمارة الملزمة بالإضافة إلى تعلمنا المزيد حول blade و الدوال. كل شيئ الآن يعمل، يمكن تجربة التطبيق وإنشاء وتعديل وحذف المهام والمشاريع، وفي أي وقت يمكنك كتابة الأمر: php artisan migrate:refresh –seed وسوف يتم إعادة تعيين قواعد البيانات. في المرحلة القادمة والتي ستكون النهائية سوف نقوم بالتحقق من الاستمارات. ترجمة -وبتصرّف- للمقال Creating a Basic ToDo Application in Laravel 5 – Part 3. حقوق الصورة البارزة: Designed by Freepik.
  7. هل قمت مسبقًا بتعبئة نموذج ما على الويب وطُلب منك إدخال نفس البيانات مرّتين؟ هذا ما يسمى بالإدخال المزدوج (double entry) يدعى أيضًا "إعادة الإدخال" (re-entry) أو "التأكيد" (confirm) ، ومن المؤكَّد أنّك قد صادفت هذا الشيء في العديد من المواقع المشهورة مثل Google (يتم طلب إدخال كلمة المرور مرّتين) و Facebook (يتطلب إدخال البريد الإلكتروني مرّتين. أُنظر الشكل 1). الشّكل 1: نموذج التسجيل لموقع Facebook يتطلب إدخال البريد الإلكتروني مرَّتين. لماذا يطلب منك إدخال نفس المعلومات مرتينكل حقل إضافي في النّموذج يعني عملًا وجهدًا إضافيًا على من سيقوم بتعبئة هذا النّموذج، وهذا يعني زيادة محتملة في الأخطاء ونقصًا في معدَّل إكمال النماذج. إذاً لماذا يتم إضافة حقل إضافي يحتوي على معلومات تمت تعبئتها مسبقًا في حقل آخر؟ يهدف الإدخال المزدوج إلى منع الأخطاءالهدف الرئيسي من الإدخال المزدوج (double entry) هو منع الأخطاء. فعندما يُطلَب من المستخدم إعادة كتابة بريده الإلكتروني أو كلمة المرور فإنّ ذلك يعطينا القُدرة للتّأكد بأنّ معلومات الحقلين متطابقة. أمّا إذا لم تتطابق الحقول، فهذا يعني احتمالية وجود خطإ مطبعي/إملائي (بسبب الإستعجال في الكتابة مثلًا أو عدم الإنتباه). الشّكل 2 يحتوي على لقطة من نموذج التسجيل الخاص بشركة Google وكيف يظهر الخطأ بسبب عدم تطابق الحقلين. الشّكل 2: نموذج تسجيل Google وكيف يظهر الخطأ في حالة عدم تطابق الحقلين. (كلمة احتمالية مهمة هنا لأن الخطأ قد يكون في حقل إعادة الإدخال وليس في الحقل الأصلي. وفي هذه الحالة، سيُطلب من المستخدم إعادة إدخال الحقلين معًا). الإدخال المزدوج يمنع الأخطاء ولكنه يسبب المشاكل أيضاعند استخدام الإدخال المزدوج في أحد النماذج، فإنّنا نطلب من جميع المستخدمين القيام بجهدٍ إضافي مقابل منع ما قد يكون عددًا صغيرًا من الأخطاء. قبل الشُّروع في بناء نماذج الإدخال المزدوج، يجب عليك أن تحدّد حجم المشكلة الّتي تحاول منعها وأن تُقرِّر فيما إذا كانت تستحق التضحية المحتملة بعدد النماذج التي سيتم إكمالها. حتى وإن قمت باستخدام الإدخال المزدوج، فالبشر أذكياء وسيقومون بالبحث عن أفضل الوسائل لتقليل العمل المطلوب منهم. ومن أحد السلوكيات الشائعة نسخ البريد الإلكتروني وكلمة المرور من الحقل الرئيسي وإلصاقه في الحقل الآخر، وهذا التصرف بكل تأكيد ينافي الفائدة المرجوَّة من الإدخال المزدوج. يمكنك أن تبرمج النموذج بحيث يتم منع النسخ واللصق داخل تلك الحقول. ولكن قد يسبب هذا التصرف الإرباك والحيرة لبعض الأشخاص، فقد لا يستطيعون إدارك السبب الكامن وراء توقف اللصق عن العمل. وقد لا يمنع ذلك المستخدمين من نسخ ولصق المعلومات من مصادر أخرى (أحد برامج إدارة كلمة المرور على سبيل المثال). قد يَستخدم بعض الأشخاص أدوات مبرمجة تقوم بتعبئة النماذج بشكل آلي. وقد تكون هذه الأدوات مبنية في المتصفّح أو على شكل إضافة يتم تحميلها وإضافتها للمتصفّح. لهؤلاء المستخدمين، ستكون النماذج المزدوجة معدومة الفائدة (بالنّسبة لحقل البريد الإلكتروني على الأقل). قد يجد بعض المستخدمين في الإدخال المزدوج نوعًا من التعالي عليهم أو الإستهانة بهم. فقد يُفهَمُ من وجود الإدخال المزدوج بأنَّ صاحب النّموذج لا يثق بقدرات المستخدم على إكمال النموذج بشكل صحيح. وبالتالي، فقد يُهَدِّدُ الإدخال المزدوج الثقة المبنية بين المستخدم وصاحب النّموذج والتي تعتبر مُهِمَّة في زيادة نسبة التّحويل (conversion) ومعدلات إكمال النّماذج. لماذا يستخدم الإدخال المزدوج في أغلب الأحيان لعناوين البريد الإلكتروني وكلمات المرور فقط؟مع وجود كل هذه العيوب، فقد يتساؤل أحدكم عن سبب استخدام الإدخال المزدوج. بكل تأكيد، تعتبر هذه العيوب السبب الرئيسي في نُدرة استخدام الإدخال المزدوج وسببًا لتواجدها في حقول البريد الإلكتروني وكلمة المرور فقط. لمَ هذه الحقول فقط؟ لأنه بالنّسبة للعديد من الأنظمة والخدمات، يُعتبر البريد الإلكتروني وكلمة المرور المفاتيح الرّئيسية التي تمنح المستخدم حق الوصول واستخدام العديد من الخدمات. لذلك، فإن الأثر المترتب على وجود خطأ ما في أحد هذه الحقول سيكون أكبر من الأثر المترتب على اختيار خاطئ لعنوان (title) أو كتابة اسمك بشكل خاطئ. قد يجادل بعض الأشخاص بأنّ هناك حقولًا لا تقل أهمية عن البريد الإلكتروني وكلمة المرور كرقم البطاقة الإئتمانية مثلًا. مع ذلك، فإن عمليّة التّحقق من صحة رقم بطاقة الإئتمان تتم في أغلب الأحيان عند نقطة الإدخال. علاوة على ذلك، فإن رقم بطاقة الإئتمان لا تعدّ من معلومات الإتّصال، فإذا تمَّ إدخال الرّقم بطريقة خاطئة فيمكننا التواصل مع المستخدم وإعلامه بذلك، أمّا إذا كانت معلومات الإتصال غير صحيحة فسيكون من الصعب تدارك الموقف. سيقول أولئك الذين يفكرون بطريقة منطقية بأنَّ الإدخال المزدوج سيكون مناسبًا لأرقام الهواتف. وممّا لا شكَّ، أنّه إذا كان رقم الهاتف هو الوسيلة الوحيدة (أو الأساسية) للتواصل مع المستخدم، فسيكون استخدام الإدخال المزدوج أمرًا مناسبًا. وإن كان رقم التّواصل عبارة عن رقم هاتف محمول فيمكننا التّحقق من هويّة المستخدم عن طريق إرسال رسالة نصّيَّة قصيرة تطلب منه القيام بأمرٍ ما لإتمام العملية. طرق أخرى للتأكد بأن البريد الإلكتروني صحيحإن الطريقة المذكورة بالأعلى للتحقق من أرقام الهواتف يمكن أن تُستخدم أيضاً للتأكد من البريد الإلكتروني. فبالإضافة إلى التّحقق من صحَّة البريد الإلكتروني، فإنَّه يجب التحقق أيضاً بأنّ المستخدم يمكنه الدخول إلى ذلك البريد واستعماله. ويتم ذلك بإرسال "رابط تفعيل" إلى ذلك البريد، فإذا تم زيارة وفتح الرابط المُرسل (يكون هذا الرابط فريدًا ومتغيرًا لكل مستخدم) فسوف تتم العمليَّة بشكل جيد، وإذا لم يتمَّ زيارة الرابط فإن عملية التسجيل، البيع أو الخدمة لن تتم. إذا كان عنوان البريد هو اسم المستخدم، فإنَّ طريقة التحقق هذه تعتبر-نوعًا ما- أفضل من الإدخال المزدوج. فبينما يضمن الإدخال المزدوج تطابق البريدين المدخلين في كلا الحقلين، فإنّ عملية المصادقة تضمن بأنّ يكون البريد الإلكتروني صحيحًا ومستعمَلًا. ومما لا شك فيه، فإن طريقة المصادقة هذه تُبعِد المستخدم عن النموذج وتعتمد بشكلٍ رئيسي على وصول رسالة البريد إلى بريد المستخدم وتفاعله معها. كل هذه الأمور قد تدفع المستخدم إلى ترك الموقع أو الخدمة وبالتالي الفشل. لتقليل الأثر السَّلبي المترتب على عملية المصادقة فإنها يجب أن تكون مصمّمة ومبنيّة بعناية وحذر (يمكنك على سبيل المثال أن تُبلغ المستخدم بما يجب عليه فعله وأن تعطيه الوقت الكافي ليقوم بتفعيل الرَّابط). وإذا كان من اللازم أن يكون البريد الإلكتروني صحيحًا، فإن مزايا عملية المصادقة هذه ستتغلب على عيوبها. لقد وُجِدَ في دراسة أجراها موقع Smashing Magazine في عام 2008 على أفضل 100 موقع إلكتروني بأن 18% فقط من تلك المواقع تتطلب من المستخدمين الإدخال المزدوج لعناوين بريدهم الإلكتروني مقارنة مع 72% من المواقع تتطلب الإدخال المزدوج لكلمات المرور. لم يعتبر الإدخال المزدوج لكلمات المرور شائعا أكثر من البريد الإلكتروني؟هناك العديد من الأسباب التي تكمن وراء وجود عدد أكبر من المواقع التي تتطلب الإدخال المزدوج لكلمة المرور أكثر من المواقع التي تتطلب الإدخال المزدوج للبريد الإلكتروني. أحد أهمِّ الأسباب -وعلى عكس البريد الإلكتروني- فإنّه عند إدخال كلمات المرور في الحقول المخصَّصة لها (وعلى افتراض أنّه تمَّ تكويد هذه الحقول بشكلٍ صحيح) ، فإنّها تكون مخفيَّة أو "محجوبة" بشكلٍ افتراضي (على شكل نقاط سوداء دائريّة، كما في الشَّكل 3). وتهدف عمليَّة الحجب هذه إلى منع الأشخاص من استراق النظر ورؤية كلمة المرور التي يدخلها المستخدم. الشكل 3: حجب كلمة المرور. تمَّ كتابة كلمة "testing" في الحقل ولكنها ظهرت على شكل نقاط سوداء. ولأنّ المستخدم لن يتمكنّ من رؤية الرّموز التي يدخلها، فستكون نسبة حدوث الأخطاء أكبر، وبالتالي وجود حاجة أكبر إلى الإدخال المزدوج. علاوة على ذلك، فإنّ كلمات المرور في أغلب الأحيان تكون "عشوائية" أكثر من عناوين البريد الإلكتروني. فعناوين البريد تحتوي في الغالب على اسم الشَّخص، اسم الشَّركة، مزود خدمة البريد أو مزود خدمة الانترنت، وكلُّ هذه الأشياء يُمكن تذكُّرها بسهولة. في المقابل، قد تكون كلمات المرور مزيجًا من رموزٍ وأرقام عشوائية (ليس بالضرورة أن يكون هذا أفضل خيار من ناحية أمنيّة، ولكن بشكلٍ عام، فإن كلمات المرور الطويلة والغامضة تكون آمنة أكثر). بدائل الإدخال المزدوج لكلمات المروريُعتبر الإدخال الوحيد/الفرديّ أحد بدائل الإدخال المزدوج. وقد تعمل هذه الطريقة بشكل مناسب إذا ما افترضنا أنّه تم تزويد المستخدم بطريقة سهلة لِتَذكُّر كلمة المرور أو إعادة ضبطها إذا ما نسيها (يُفضَّل إضافة هذه الخاصيّة في جميع الأحوال، فقد ينسى أيّ شخصٍ كلمة المرور خاصته). ومن المثير للإهتمام بأنّ نماذج التسجيل الموجودة في Facebook ،LinkedIn وTwitter تتطلب إدخال كلمة المرور مرّة واحدة فقط. الشكل 4: لا يوجد إدخال مزدوج في نماذج التسجيل الخاصّة بشركة LinkedIn. و بديل آخر للإدخال المزدوج هو إعطاء المستخدم القدرة على تعطيل خاصيّة الحجب في حقل كلمة المرور. يُعطي هذا للمستخدم الحريّة الكافية لإظهار كلمة المرور إن كان يشعره ذلك بالرّاحة. هناك العديد من الطّرق لفعل هذا ولكنّ الطّريقة التي يوصى بها موضّحة بالشّكل 5. حيث يفضّل إضافة زر "Show password" على إضافة مربّع اختيار (checkbox) أو زوج من أزرار الرّاديو (radio buttons) لأنّه يُسهّل عمليَّة إظهار أو حجب كلمة المرور. الشكل 5: إظهار أو حجب كلمة المرور عند النَّقر على "Show password" قد يواجه المستخدم صعوبة في تفسير مربّع الاختيار، وقد يكون من الصَّعب مَوضَعَة أزرار الرّاديو وترتيبها بشكلٍ فعّال. فقد تأخذ أزرار الرّاديو حَيِّزًا أكبر من السؤال ذاته إذا ما وضعت فوق بعضها البعض، وإذا وُضعت بجانب بعضها قد تسبب لك المشاكل في استعمال ما يسمى بالمجاورة (proximity) لتوضيح أيّ إجابة ترتبط بأيّ زرّ. إنّه لمن الصّعب أيضًا أن تربط حقل كلمة المرور بمربّع اختيار أو زوجٍ من أزرار الرّاديو مقارنة مع ربطه برزٍّ واحد. فكر مليا قبل استخدام الإدخال المزدوجيُعتبر منع الأخطاء في أيّ نموذج من الأمور المحبَّبة، ولكن من المهمّ جدًا أن توجد حاجة ملحّة لاستخدام الإدخال المزدوج وذلك يعود إلى النقاط التالية: أنّها تزيد العبء والجهد على كل المستخدمين.يمكن تجاوزها عن طريق النّسخ واللصق أو باستخدام أدوات تعبئة النماذج بشكل آلي.تضمن فقط أنّ الحقلين متطابقين ولا تضمن احتواء هذه الحقول على معلومات صحيحة.يمكن أن تُرى كنوعٍ من الاستخفاف والإستهانة بالآخرين.إذا كان البريد الإلكتروني أو اسم المستخدم هما الطّريقة الوحيدة للتّواصل مع المستخدم، فيمكنك حينئذ استخدام الإدخال المزدوج. وبطريقة مشابهة، إذا لم تكن ترغب في تمكين المستخدم من إظهار كلمة المرور، فقد يكون الإدخال المزدوج ملائمًا في هذه الحالة. حتّى في الحالات المذكورة في الأعلى، فإنّ البحث عن بدائل للإدخال المزدوج (مثل المصادقة أو بعض الطرق البسيطة لإعادة الضبط والاسترداد) يستحقُّ النَّظر فيه بِجدِّيَّة. ترجمة -وبتصرّف- للمقال Double entry of form fields.
  8. يبدو أن الأسئلة المتعلقة بالمحاذاة تظهر بانتظام. ولكن لسوء الحظ، فحتى مع وجود أبحاث معتبرة تقدم رؤية واضحة فيما يتعلق بالمشكلة، فإن معظم نتائج النقاشات التي تدور حولها تكون مبنية على تفضيلات وتكهنات شخصية. في هذا المقال، سنقدم لكم ملخص الأبحاث لإعطائكم توصيات محددة وسهلة الاستعمال لهذا الجانب المهم من تصميم النماذج. مختلف أنواع المحاذاة (alignment)بالنسبة للمحاذاة، هناك العديد من الأبعاد المختلفة التي تؤخذ بعين الإعتبار، منها: كيفية محاذاة الأسئلة بالنسبة لبعضها البعض.كيفية محاذاة نص السؤال (أعلى أم يسار حقل الإجابة؟).في الأسئلة المغلقة مع فئات استجابة متعددة، كيف يتم محاذاة هذه الفئات.كم عدد الحواف (edges) الموجودة في النموذج لمختلف أنواع المحاذاة.قبل أن نتكلم عن هذه الأبعاد كل على حدة (مع استخدام بعض الرسومات لجعل الصورة أوضح)، ضع في الحسبان أن التوصيات المقدمة في هذا المقال: ستكون خاصة بالنماذج التي لها سياق اللغة الإنجليزية أو ما يشابهها من ناحية نمط القراءة (أي اللغات التي تقرأ من اليسار إلى اليمين). وبالتالي، فإنك قد تحتاج إلى تعديل هذه التوصيات لتتناسب مع الثقافات التي تقرأ من اليمين إلى اليسار (كاللغة العربية). تقدم نهجا افتراضيا لتصميم النماذج. وبما أنه يوجد دائما بعض الاستثناءات لأي قاعدة، فإنه من المهم جدا أن تضبط الأمور لتتناسب مع السياق الخاص بك.1. كيف تقوم بمحاذاة الأسئلة بالنسبة لبعضها البعضعلى افتراض أن البشر يقرؤون من الأعلى إلى الأسفل، فإنه يفضل وضع الأسئلة فوق بعضها (بشكل عمودي) بدلا من وضعها بجانب بعضها البعض (بشكل أفقي). يخلق هذا إيقاعا عموديا متناسقا ويساهم في إيجاد "مسار واضح للإستكمال" كما أسماه Luke Wroblewski. الشكل 1: محاذاة الأسئلة عموديا كما يوضحه السهم الأزرق. قد يكون من المغري رص سؤالين إلى بعضهما لتقليل المساحة العمودية اللازمة. قد يؤدي ذلك إلى حصول بعض الأجزاء في النموذج على سطر كامل لسؤال واحد فقط وترك بقية الأجزاء تحتوي على عدة أسئلة في سطر واحد. وقد يؤدي عدم التناسق هذا إلى: إعاقة من يريد تعبئة النموذج عن معرفة الطريقة التي سيتحرك بها خلال عملية التعبئة، وبالتالي إبطاء عمله.زيادة احتمالية عدم قدرة الشخص على رؤية وإجابة واحد أو أكثر من الأسئلة (وهو ما لا نريده بكل تأكيد).يبين الشكل 2 نموذجا يحتوي على أسئلة مرتبة/متراصة بشكل أفقي حيثما كان ذلك ممكنا. من المحتمل في مثل هذه الحالة أن يتم إهمال الحقول الموجودة في الجزء الأيمن من الصفحة خصوصا إذا لم يقم المستخدم بملئ الحقل السابق إلى نهايته (لأقصى يمين الحقل). الشكل 2: محاذاة الأسئلة أفقيا. يمكن استغلال المساحة في النموذج بشكل أفضل وذلك بفصله إلى عمودين (كما في الشكل 3). فإذا ما فصلت الصفحة إلى عمودين، فسوف تتم محاذاة الأسئلة في كلا العمودين، وهذا يعني أن الأسئلة ستبدأ من الأعلى إلى الأسفل للعمود الأول، ومن الأعلى إلى الأسفل للعمود الثاني وبعدها إلى الصفحة التالية. ولعدد من الأسباب سنذكرها في مقال آخر، فإنه من غير المحبذ استخدام أعمدة متعددة في نموذج إلكتروني (electronic form) خصوصا في النماذج الموجودة على شبكة الإنترنت. الشكل 3: صفحة تحتوي على نموذج مزدوج الأعمدة. 2. كيفية محاذاة نص السؤالافتراضيا، إن أفضل موقع لنص السؤال يكون في أعلى حقل السؤال، كما هو موضح في الشكل 4. الشكل 4: نص السؤال يظهر أعلى حقل السؤال. يوصي مصمم النماذج الاسترالي الشهير Robert Barnett بهذه الطريقة، وقد أثبتت فعالتيها -من حيث عدد مرات إنهاء النموذج- مقارنة بوضع النص إلى يسار حقل الإجابة (أنظر "موضعة التسمية (label) في النماذج" لكاتبه Matteo Penzo). هناك فائدتان أخريان من وضع نص السؤال فوق الحقل: الفائدة الأولى، هي أنها تسهل عملية ترجمة نص السؤال إلى لغات أخرى، لأنه بهذه الحالة لن يهمنا طول أو قصر النص المترجم.الفائدة الثانية، أنها تمكن من يعانون عسر القراءة أو ممن لديهم إعاقة إدراكية أو حتى مستخدمي قارئات الشاشة (screen readers) من تفادي المشاكل التي قد يواجهونها مع النص الموضوع إلى يسار الحقل (سوف نتكلم عن هذا بعد قليل).إن من أحد المساوئ الرئيسية لوضع نص السؤال أعلى حقل الإجابة هو الزيادة الملحوظة في حجم المساحة العمودية التي يحتاجها النموذج. هذا يعني زيادة عدد الصحفات في النماذج الورقية وتمرير(scrolling) أكثر في النماذج الإلكترونية. لذلك، وعلى فرض أنه تم استخدام المحاذاة المناسبة، فقد يكون من الأفضل في بعض الحالات وضع نص السؤال إلى يسار الحقل. محاذاة النصهناك أربع خيارات لمحاذاة النص وهي دفع لليسار (flush left)، دفع لليمين (flush right)، ضبط من الطرفين (justify) وتوسيط (أنظر الشكل 5). قد تجد أيضا من يستخدم كلمتي "ranged" و "ragged" بدلا من كلمة "flush". الشكل 5: أربع طرق رئيسية لمحاذاة النص. إذا وضع نص السؤال فوق حقل الإجابة، فإنه يجب دفعه إلى اليسار للأسباب التالية: تعتبر المحاذاة لليسار من أفضل الممارسات (best practice) ومناسبة لأغلب المواد المقروءة.تعتبر-بشكل عام- أسهل للقراءة مقارنة بالنصوص المدفوعة لليمين (flush right) أو المتوسطة.قابل للقراءة كالنص المضبوط من الطرفين (justified text) ولكنه وعلى عكس النص المضبوط من الطرفين (justified text) فإنه لا يتطلب تدخلا يدويا لإصلاح مشاكل تباعد الكلمات.يعزز المسار العمودي للإنهاء.عند وضع نص السؤال إلى يسار حقل الإجابة، يفضل -على عكس ما قد يتوقعه البعض- أن يكون ذلك النص مدفوعا لليمين. وقد أشار Matteo Penzo في البحث الذي ذكرناه مسبقا بأن الدفع لليمين يعمل بشكل أفضل من الدفع لليسار. (لسوء الحظ، قد لا يكون هذا صحيحا بالنسبة لمن يعانون عسر القراءة. ولهذا السبب فإن الطريقة الأفضل والتي ينصح بها هي وضع التسمية (label) فوق الحقل). الشكل 6: محاذاة نص السؤال إلى يسار حقل الإجابة ودفعه لليمين. يقول البعض بأنه يجب دفع النص إلى اليسار بدلا من اليمين لأن ذلك يسهل عملية تصفح النموذج للأسفل. قد يكون هذا صحيحا، ولكن ما نريده حقا من التصميم هو تعبئة النموذج وليس قراءة الأسئلة بشكل سريع بحثا عن كلمة أو عبارة معينة. كما أن ما نريده هو اختيار أسلوب التصميم الذي يدعم الهدف الرئيسي (أي تعبئة النموذج)، وهو ما يوفره الدفع لليمين. شيء مهم أيضا، وهو أن جعل النص مدفوعا لليسار، يجعل عملية ربطه مع حقل الإجابة الخاص به أمرا صعبا خصوصا لمن يستخدم مكبرات الشاشة (screen magnifiers) أو لمن يعاني من صعوبات في الإدراك. يعود ذلك إلى أن اختلاف أطوال نص السؤال قد يعني في بعض الحالات وجود فجوة/مساحة كبيرة بين نهاية نص السؤال وبداية حقل الإجابة. قد يكون ذلك أحد الأسباب التي دفعت المنظمة العالمية للمعايير (ISO) والمعايير الوطنيّة الأمريكية HFES200 (هندسة العومل البشريّة لواجهات استخدام البرامج) أن توصي بأن يكون نص السؤال مدفوعا لليمين إلا إذا تساوت أطوال جميع الأسطر. 3. كيفية محاذاة فئات الإستجابةإذا كان مصطلح فئات الإستجابة غير مألوف بالنسبة لك، فقد ترغب في الإطلاع على هذا المقال. لنفس الأسباب التي ذكرناها بالنسبة للأسئلة، فإنه يجب محاذاة فئات الإستجابة عموديا (أي وضع الفئة "ب" أسفل الفئة "أ"). الشكل 7: محاذاة فئات الإستجابة عموديا. كما ذكرنا سابقا، فإنه من المغري وضع الأسئلة بجانب بعضها (بشكل أفقي). ينطبق نفس الأمر على فئات الإستجابة، خصوصا إذا كانت التسميات (labels) قصيرة. غالبا ما تكون الأسئلة المتعلقة بالمسميات title (مثل "Mr" أو "Mrs") أحد العناصر الرئيسية للجوء البعض إلى استخدام المحاذاة الأفقية، لأن ذلك قد يؤدي إلى حفظ الكثير من المساحة العمودية. عندما تحدثنا عن الأسئلة، رأينا بأن وضع العناصر إلى جانب بعضها قد يؤدي إلى إبطاء من سيقوم بتعبئة النموذج وإلى ارتفاع معدل الأخطاء. وعند استخدام هذه الطريقة في فئات الإستجابة فإن مشكلة إضافية ستظهر وهي ضعف الرابطة بين مسمى فئة الإستجابة والحقل الخاص به. وكما هو موضح في الشكل 8، فإن المسافة بين المسمى والحقل هي نفسها في كلتا الحالتين. مع ذلك، ففي حالة محاذاة الفئات عموديا يكون من الواضح جدا معرفة أي مسمى يرتبط بأي حقل، على عكس المحاذاة بشكل أفقي. الشكل 8: إذا استخدمنا المحاذاة العمودية (يمين الصورة) بدلا من المحاذاة الأفقية (يسار الصورة)، فسيكون من السهل على من سيقوم بتعبئة النموذج أن يربط مسميات فئات الإستخدام بما يقابلها من حقول. في بعض الحالات، يمكن تعديل المسافة الأفقية للتخفيف من هذه المشكلة. كما يمكن أيضا تلافي هذه المشكلة نهائيا وبأقل جهد، وذلك بمحاذاة فئات الإستجابة عموديا بدل محاذاتها أفقيا. محاذاة النّص لفئات الإستجابةكما هو الحال بالنسبة لنص السؤال، يجب علينا أن نقرر فيما إذا كانت المسميات الخاصة بفئات الإستجابة المختلفة (يطلق عليها أيضا اسم "عناوين فرعية" أو "تعقيبات") مدفوعة لليمين، مدفوعة لليسار، مضبوطة من الطرفين (justified) أو متوسطة. يعتبر هذا أحد أكثر الجوانب جدالا في تصميم النماذج، ويرجع ذلك بشكل جزئي إلى اختلاف الممارسات الشائعة في نماذج شبكة الإنترنت عنها في تلك الموجودة في مجال الطباعة. عندما يتعلق الأمر بالنماذج الورقية (بما في ذلك النماذج الإلكترونية التي يمكن طباعتها وتعبئتها وملفات الـ pdf لأحد النماذج الورقية) فإنه من الواضح بأن أفضل طريقة هي وضع مسميات الفئات إلى يسار الحقول الخاصة بها ودفعها إلى اليمين. الشكل 9: وجود مسميات فئات الإستجابة إلى يسار الحقول ومدفوعة لليمين. قبل 25 سنة، أثبتت Patricia Wright بأن هذه الطريقة هي الأفضل، وقد كانت الأبحاث التي قام بها Robert Barnett على مدى عقود مضت متوافقة مع ما جاءت به Patricia Wright. عندما يتعلق الأمر بالتصميم في العالم الواقعي، فلن يكون الجواب بتلك البساطة. فبالنسبة لمسألة المحاذاة لمسميات وحقول فئات الإستجابة، فسيظهر بعض التعقيد بسبب وجود الإنترنت (the web). تاريخيا، كانت النماذج على شبكة الإنترنت تضع المسميات على يمين الحقل (كما هو الحال في الشكل 7 الموجود في الأعلى)، ويعود ذلك إلى بعض الأسباب البرمجية. على شبكة الإنترنت، يكون من الصعب محاذاة حقول الإستجابة عبر اسئلة متعددة بشكل عمودي. وعلى الرغم من صعوبة تحديد هذه الأمور، فإنه من المعقول قول بأن هذه الطريقة في وضع المسميات أصبح متعارفا عليها بشكل افتراضي (تحديدا كما أصبح نهج شركة مايكروسوفت (Microsoft) في تصميم برامج سطح المكتب أمرا متعارفا عليه افتراضيا). لهذه الأسباب، سوف تستمر مسميات فئات الإستجابة في نماذج الويب بالظهور إلى اليمين من الحقول الخاصة بها. توقع أيضا بعض الأوقات عندما تتصادم الهيمنة التاريخية للنماذج الورقية مع الشعبية المتزايدة النماذج الإلكترونية. 4. عدد الحواف (edges) في النموذجمن آخر جوانب المحاذاة التي سنتحدث عنها في هذا المقال هو عدد الحواف لمختلف طرق المحاذاة الموجودة في النموذج. إن بداية أو نهاية أي كتلة نصية (block of text) أو مساحة بيضاء/فارغة (white space) يخلق ما يسمى "الحافة". قد تكون هذه الحافة هي نهاية حقل الإجابة أو حدود أحد الأعمدة أو المسافات البادئة (indentations) لجميع نصوص الأسئلة. بمقارنة الشكلين 10 و11 في الأسفل، يظهر الشكل 10 نموذجا يحتوي على الكثير من الحواف، أما الشكل11 فيظهر نموذجا بعدد قليل من الحواف، فأيهما تفضل؟ الشكل 10: نموذج بعدد كبير من الحواف. الشكل11: نموذج بعدد قليل من الحواف. عند مقارنة التصاميم ذات الحواف الكثيرة مع التصاميم ذات الحواف القليلة، سنلاحظ بأن الأخيرة تعتبر أكثر جمالا وأسهل في الإستعمال. كما ينصح بأن يتم محاذاة العناصر المتوافقة بشكل عمودي ومتناسق. بعبارة أخرى، يجب على نص مربعات الأسئلة ذات الأطوال المتشابهة أن تبدأ وتنتهي بنفس النقطة العمودية، ويجب أيضا أن تبدأ جميع الأسئلة من نفس النقطة العمودية وهكذا دواليك. ملخص التوصياتكخلاصة لكل ما ذكرناه في هذا المقال، فإن الطرق الواجب اتباعها والتي ننصح بها هي: محاذاة الأسئلة عموديا.وضع نص السؤال فوق حقل الإجابة ودفعه لليسار.محاذاة فئات الإستجابة عموديا.للنماذج الورقية: وضع مسميات فئات الإستجابة إلى يسار الحقول الخاصة بها ودفعها لليمين.لنماذج الإنترنت: وضع مسميات فئات الإستجابة إلى يمين الحقول الخاصة بها ودفعها لليسار.تقليل عدد الحواف العمودية في النموذج على قدر المستطاع.ترجمة -وبتصرّف- للمقال Alignment.
  9. على الرغم من وجود بعض الانتقادات لواجهات المُستخدم المُنبسِطة ووصفها بأنّها مجرد موضة، أو أنها رد على التصميم المُحاكي للواقع (skeuomorpic)، فإن كثيرًا من المصممين تبنّوا فكرة التصميم المُنبسط بسبب أنّ التخفيف من حدّة التّصميم المرئي (مثل التدرج اللّوني، تأثيرات الظل، والحواف) ينتج عنه واجهات أبسط وأنظف. تكمن المشكلة في أنه تم بناء أغلب واجهات المستخدم المنبسطة بشكل يُركّز على توفير المحتوى، أما المكونات التي يتفاعل معها المستخدم (transactional components) مثل النماذج، فلم تحظَ سوى بالقليل من الاهتمام. ماذا سيحدث عندما يتعارض التصميم المُنبسط مع النماذج؟ يُمكن أن يُواجه المُستخدم مشاكل لدى استخدامه للموقع، وهذا أمر واردٌ جدًا. الاهتمام بالنّماذجالمقصود بالنّماذج هنا هو أي تفاعُل (interaction) يتم فيه تبادل للمعلومات لاستقبال منتج أو خدمة. هذا يتضمن عدّة أمور بدءًا بالبنوك الإلكترونية (internet banking) وصولًا إلى التجارة الإلكترونية على الهواتف الذّكيّة (mobile commerce)، ومرورًا بكلٍ من التّسجيل لاستخدام تطبيق على جهاز لوحي والقيام بعملية بحث على الويب. احتياجات المستخدمين إلى تصميم النماذج يختلف كثيرًا عن احتياجهم إلى تصميم المحتوى، كما هو ملخَّص في الجدول التالي: النماذج المحتوى إتمام المهمة الاستكشاف وإتمام المهمة يركِّز المستخدمون على الحقول لا يركز المستخدمون على الحقول عادة ما يكون هناك نقطة دخول واحدة ونقطة خروج واحدة إمكانية وجود عدة نقاط دخول وخروج مفاهيم النجاح والفشل معرَّفة بشكل صارم ودقيق تختلف مفاهيم النجاح والفشل تستخدم لمرّة واحدة تستخدم لعدة مرات على الأرجح، فإن النماذج تُستخدم لإنجاز مهمة معينة. وأنا على يقين أنني واحد من الناس القليلين في العالم الذين يدرسون النّماذج من أجل المُتعة، أما الأشخاص الأسوياء فإنّ جُلّ ما يرغبون به هو تعبئة النموذج لتسجيل سياراتهم أو لشراء ذلك الحذاء الجديد. ولكن لما يتعلّق الأمر بالمُحتوى فإن إنهاء مهمة معينة ليس بالضّرورة أولوية. أحيانًا قد نتصفّح الإنترنت من دون أن يكون لدينا هدف مُحدّد نرغب في الوصول إليه، (كمن يتصفّح موسوعة Wikipedia لساعات). ينظر الناس إلى "إنهاء مهام محددة" بطرق مختلفة عن الاستكشاف والتّعرُّف. لاحظ شخصًا يملأ نموذجًا، وسترى بنفسك تركيزه على الحقول، رجوعه إلى التعليمات، الخطوات وحتى إلى مسميات الحقول، ويسأل فقط عند ما يكون هناك داعٍ. هناك ترتيب: مكان للبدء ومكان للإنهاء، وعند الانتهاء سيعرف ما إذا كان قد نجح أو فشل في إنجاز المهمة. بالمقابل فإنه يتّم الوصول إلى المحتوى عبر مسارات ومن مصادر مُختلفة، ويعمد الناس إلى استعراض والتركيز على المحتوى بعدة طرق مُختلفة. فكرة النَّجاح لا تزال صحيحة هنا، ولكنّها مُختلفة بسبب اختلاف حالات الاستخدام. التركيز على إنهاء المهمة يعني أنَّ على المستخدم ملء النموذج مرة واحدة فقط، بينما يتم زيارة المحتوى أكثر من مرة. إذًا، هناك فرصة ضئيلة أن يتعلّم المُستخدم اللغة البصرية للنموذج (مثال، أن يكون النموذج بدون أزّرار ويتم استبدالها بروابط فقط). التصميم المُنبسِط يعني معلومات أقلكقاعدة أساسية فإنَّ النَّماذج والمحتوى مختلفان. لكن قد تتساءل، ما علاقة هذا الأمر بواجهات المستخدم المُنبسطة flat UI؟ المشكلة الأساسيّة هو أنه في مجال واجهات المُستخدم المُنبسطة تم الدّفع بالتبسيط بشكل يُمكن وصفك بالمُبالغة. لمّا يتعلّق الأمر بالمُحتويات فإنه يُمكن اعتبار كل من تأثيرات الظلّ، التدرُّجات والحواف مجرد زخرفة embellishments، فعند قراءة مقال مكوّن من أكثر من صفحة، فإنه لا يُهم ما إذا كانت آلية الانتقال إلى الصفحة التالية تتم عبر رابط نصّي أو زِّر. أما في النماذج فالأمر يختلف، فالتّفريق ما بين الزِّر والرابط النصّي أمر مُهم. كمثال على ذلك لنلق نظرة على حدثي الإرسال submit والإلغاء cancel في النماذج. كما هو معروف فإن لكل من هذين الحدثين نتائج مختلفة تمامًا، ونُريد من المستخدم أن يختار الحدث الذي يتوافق مع احتياجه بشكل سريع وسهل في آن واحد. لهذا أنصح أنا وغيري من المُصمّمين أن يتمّ التفريق بينهما وأن يكون الحدث الرئيسي (الإرسال أو الموافقة) كزّر، أما الحدث الثانوي (الإلغاء) فيكون كرابط نصّي. التصميم المرئي ليس مجرّد تحسينات جمالية، ولكنّه يُعبّر بشكل صريح عن الاختلاف الوظيفي ما بين العناصر وعن ترتيبها حسب أولويّاتها. في المُقابل، فإن نموذج Klout التالي، يُوضّح كيف يُمكن للمعلومة أن تضيع جرّاء المُبالغة في تبسيط الواجهات المُسطّحة. وضع الزّر "إلغاء cancel" قبل الزّر "إرسال submit " يعتبر نمطًا خبيثًا (dark pattern) سيّئًا جدًا (يستخدم هذا النوع من التصميم في خداع المستخدم لفعل شيء معين)، لكن لندع هذا الأمر جانبًا . لنركز على جانب التّصميم، لاحظ كيف أنّه تمّ تنسيق الحدثين الرئيسي والثانوي كروابط نصّيّة، بنفس اللون وبنفس الخلفية، مما سيُقلّل من سرعة المُستخدم ويدفعه إلى التّركيز أكثر قبل أن يتخذ القرار. تخيّل معي كيف سيكون هذا النموذج أكثر قابلية للاستخدام إذا ما تمًّ التَّفّريق بين الأحداث والتّوضيح بشكل بصري عن ذلك (ومرة أخرى لنترك نمط التصميم الخبيث جانبًا): الطُرق الثلاثة المُؤدّية إلى فشل النماذج المُنبسطةالمثال السابق يوضّح هذه الطُرق والتي تؤدي إلى فشل نماذج الواجهات المُنبسطة في توفير تجربة استخدام سهلة: ضُعف الجانب الإيحائي (affordance): يُقصد بذلك أن المُنتج سواء كان حسّيّا أو غير حسّي فإنّه يُفترض به أن يوحي إليك بطريقة استخدامه. كأن يتبادر إلى ذهنك مفهوم الجلوس بمُجرد أن ترى كُرسيًّا. عدم وجود فروق كافية وواضحة بين عناصر النموذج (مثال، الحقول ومسمياتها والتعليمات والأزرار). عدم وجود تسلسل كافٍ في داخل أصناف عناصر النموذج (مثال، الأزرار الأساسية والأزرار الثانوية). يفتقد حدثا "الإرسال" و "الإلغاء" في واجهة Klout إلى الإيحائية، لأنَّ التصميم لا يدعوك إلى التّفاعل معه (interaction) بشكل صحيح. كان بإمكان هذه الأحداث أن تبدو قابلة للنّقر إذا تم إعطاؤها شكل الزّر (فهي أحداث actions) أو على الأقل لو تم وضع خطّ تحتها حيث أن ذلك ما يُميّز الرّابط من النّصّ العادي على الويب. كما أنّه لم يتم التفريق ما بين عناصر النموذج بشكل جيّد، فالفرق الوحيد الذي يفصل بين الرّابط القابل للنّقر وغير القابل للنّقر هو لون النّص. أما بالنسبة لترتيب الروابط، فمثال Klout مُثير للانتباه بشكل خاص. فوضع زّر "إلغاء" أولًا يُعطيه أهمية وقيمة أكبر مُقارنة بزر "الإرسال" (وهنا حجر زاوية نمط تصميم الخبيث- حيث أن ما اُتّفق عليه هو أنّ ما يأتي أوّلا هو الخيار القياسي). وفوق ذلك، فإن لكلي الرابطين نفس التنسيق، رغم أنّها مُختلفان، وسواءً نظرت إلى الأمر من وجهة نظر Klout أو من وجهة نظر المُستخدم. كيف يمكن تجنب هذه الأخطاء مع الإبقاء على الواجهات مُنبسطة؟ ببساطة، كل ما تحتاج القيام به هو إضافة بعض المؤثّرات البصرية التي توحي بطبيعة كل عنصر وبالعلاقة التي بينها. يُمكن القيام بذلك عبر التركيز على أهم العناصر في النموذج: وهي الحقول والأزرار، والتي تعتبر نواة التّفاعل مع المُستخدم. تعديل تصميم الحقول والأزّراريكون تصميم النماذج المُنبسطة ناجحًا إذا كانت الحقول تبدو مُقعّرة (hollow) والأزرار تكون بارزة. فمثل هذا التصميم يوحي بكيفية استخدام مُختلف عناصر النموذج ويظهرها مختلفة عن بعضها البعض. الصورة التالية مأخوذة من صفحة شراء سماعات Lowdi وتُظهِر نتيجة إغفال القاعدة السابقة (الحقول مُقعّرة والأزرار بارزة). فتصميم كلا من حقل الكمية وزِّر الشراء له نفس درجة التسطُّح أو الانبساط، فلا يوجد أي دعوة للمستخدم للتفاعل مع الحقل أو الزّر. إذا لم يركّز المستخدم فإنه لن يُدرك بأنّه بإمكانه تغيير الكمية، ويصعب عليهم أيضًا معرفة المكان الذي يجب أن ينقر عليه (الزِر) لكي ينتقل إلى الخطوة التالية. إليك كيفية التَّفريق بين الحقول والأزرار وكذلك كيفية إضفاء الإيحائية اللّازمة عليها: ما يمكن فعله كيفية التنفيذ جعل الحقول غائرة أضف حواف للحقول أو ظل داخلي، على الأقل تكون الحواف بعرض 1px، أزل لون الخلفية جعل الأزّرار بارزة أضف تأثيرات الظل للزّر، زوايا دائرية، تدرُّج لوني، أو حواف، حتّى ولو كان الأمر بسيطًا جدًا استعمل لون خلفيّة الزّر مغاير للّون المستخدم في الصفحة أو الحقول إصلاح الحقولدعنا نلقي نظرة على الحقول قبل وبعد إصلاحها، مع التركيز على الحقول أولًا. تظهر شاشة التسجيل في موقع Hipstamatic's Oggl المُخصّصة للهواتف كما في الصورة الأولى (على اليسار) من مجموع الصورة الثلاث في الأسفل. نلاحظ أن إيجاد مكان إضافة عنوان البريد الإلكتروني أشبه بلعبة الغُمّيضة هنا. قارن هذه الصورة مع صور التّصميمين البديلين الذين اقترحتهما (الصورة الثانية والثالثة). في التصميم الثاني تمّت إضافة حواف للحقل، مما يجعله يبدو كعنصر مختلف عن الباقي. في التصميم الثّالث تمّت إضافة الحواف والتّخلّص من لون الخلفية المُستخدم في الصفحة. استخدام هذا النّموذج أصبح أسهل، رغم أن التصاميم البديلة تستخدم واجهات مُنبسطة لكنّها أفضل بكثير خاصّة من حيث إيحائية العناصر التي نلحظها في النّسخة الثّالثة. عندما أطلقت فيس بوك graph search اِكتشفت بأسوأ طريقة مُمكنة أهمية استخدام الحقول المُقعّرة. بداية، لم يكن لحقل البحث أي لون في الخلفية (كانت خلفية حقل البحث بنفس اللّون الأزرق المُستخدم في الشريط العلوي). وماذا كانت النتيجة؟ لم يتمكّن الكثير من المستخدمين من إيجاد هذه الميزة. بعد اختبار أربع نُسخ مختلفة من حقل البحث، توصّلت فيس بوك إلى أنّ الخلفية البيضاء والظل الداخلي الخفيف- مثل الحقل الذي يظهر مُقعّرًا- هو الحل الأمثل. الاتّزان في تصميم الأزراروالآن سنركّز على الأزرار، مع مثال آخر قبل وبعد التعديل. في مثال مُحرّك البحث التّالي، لدينا على اليسار النّسخة الأصلية، والنّسخة المٌحسّنة والأفضل استخدامًا على اليمين. الزّر في التصميم الأصلي كان مُنبسطًا بشكل كبير جدًا، يظهر للمستخدم بشكل مماثل للتّرويسة، لذيل الصّفحة، أو لأي كُتلة من كتل الصّفحة. إنقاص عرض الزِّر وإضافة الزوايا الدائرية، يعطي إيحائية أفضل (affordance) مع المحافظة على وجود مساحة كافية للَّمس/النّقر. الأحداث الرئيسية والأحداث الثانوية.أخيرًا، لا تنسَ أن تُنسّق الأحداث الرئيسية بشكل مُختلف عن الأحداث الثانوية في النموذج. هناك طريقتان للقيام بذلك: استخدم الأزّرار مع الأحداث الرئيسية والروابط النّصّيّة مع الأحداث الثانوية استخدم تنسيق يُبرِز الأزرار المُخصصة للأحداث الرئيسية، مُقارنة مع تنسيق الأزرار المُخصصة للأحداث الثانوية. مثال عن استخدام الروابط النّصّيّة مع الأحداث الثّانوية في نموذج تسجيل الدخول. ويُمكن الذّهاب إلى أبعد من ذلك، مثلما شرحه Riki Tanone حول كيفية التَّفريق بين الأزرار الرئيسية والثانوية في مدونته المتخصصة بقوالب واجهات الاستخدام على Dribble. معلومات أكثر تعني قابلية وصول أفضلقد تلاحظ أنّ النماذج في واجهات الاستخدام المُنبسطة الأكثر قابلية للاستخدام تحتوي على نوع من التكرار. لا تحتوي عادةً على مُكون مرئي واحد (كاللّون مثلا) لتوضيح الفرق. عوضًا عن ذلك فإنه قد يتم استخدام اللّون والشّكل معًا أو اللّون والحجم معًا. هذا التكرار يجعل الواجهة أكثر قابلية للوصول لِطيفٍ واسع من المستخدمين، لأن التصميم لا يَفترض بأنّ المستخدم قادر على رؤية أو فهم الاختلاف البصري الوحيد الذي يدلّ على نوعيّة التّفاعل. يُعتبر اللّون مثالًا رائعًا، فهناك نحو 12 بالمئة من البشر من يُعاني من مشاكل مع الألوان. إذا كان اللّون هو الفرق الوحيد بين النص القابل للنَّقر والنص العادي، كما في مثال Klout، فإنك -بهذه الطريقة- تُصعّب المهمّة على نسبة 12 بالمئة من المستخدمين على الأقل. قارن هذا مع التوصيات التي طرحتها أو تلك التي طرحها Luke Wroblewski وآخرون، والتي تنصّ على أنه يجب تعليم الحقول المطلوبة بنجوم حمراء (كما في يسار الصّورة التّالية). في هذا المثال تقوم الألوان والأشكال معًا على إيصال فكرة مُعيّنة للمُستخدم، لهذا يُعد النموذج قابلًا للاستخدام حتّى من قبل المستخدمين الذين لديهم مشاكل مع الألوان (قد يظهر لديهم النموذج كما في الجزء الأيمن من الصورة). خاتمةكمُصمّمين نريد أن ننشئ تجربة استخدام رائعة من خلال البساطة والوضوح. فما هي البساطة وما هو الوضوح؟ هي معرفة المُستخدم ما يجب فعله بالضبط، وكيفية القيام بذلك دون بذل جهد كبير. الحصول على هذا النوع من تجربة الاستخدام يعني إيجاد توازن فعلي، بمعنى أنّ استخدام التّصميم المُنبسط ليس غاية في حدّ ذاته. لمّا نتعامل مع النّماذج فإنّه يجب أن نعلم بأنّ التّقليل ليس بالضرورة تبسيطًا. ترجمة -وبتصرّف- للمقال Flat UI and Forms لصاحبته Jessica Enders
×
×
  • أضف...