עיצוב טפסים הוא משימה מורכבת. אפילו בטופס שכל מטרתו היא איסוף הפרטים האישיים של המבקר באתר, יש שפע של החלטות עיצוביות שצריך לקחת. אפשר להעביר קורס שלם בנושא, וסדרת הפוסטים הזו נוגעת בו רק באופן חלקי. אני ממליץ בחום להציץ ברשימת הקריאה בסוף הפוסט הזה, ולקרוא לפחות חלק מהקישורים.

קישורים לכל הפוסטים בסדרה:

חלק ראשון: זרימה בטופס ויישור תוויות.

חלק שני: עזרה והסברים, ובדיקות תקינוּת (וָלידציות).

חלק שלישי: פעולה ראשית ופעולות משניות, ומספר השדות בטופס.

חלק רביעי (הפוסט הזה): תלויות בין שדות, ורשימת קריאה מומלצת.

עדכון אחרון: 25/3/2010, תודה לאופיר ושגיא על ההערות.

תלויות בין שדות

ישנו מגוון רחב של תלויות אפשריות בין שדות בטופס, אבל אפשר לחלק אותן בגדול לשלושה סוגים:

  1. שינוי בשדה אחד גורם לשינוי הערכים האפשריים בשדה אחר בטופס, ולעתים גם בערך שנבחר בשדה האחר. למשל, בחירת "ישראל" בשדה "ארץ" בכתובת למשלוח, תגרום לרשימה שבשדה "סוג משלוח" להתעדכן (דואר רשום, דואר שליחים או איסוף בחנות). בחירת "ארה"ב" תעדכן את אותה רשימה שוב (דואר רשום או שילוח בינלאומי). אם "ישראל" ו"דואר שליחים" נבחרו, בחירת "ארה"ב" ב"מדינה" תשנה אוטומאטית את הבחירה של "סוג משלוח" ל"דואר רשום" – כי "דואר שליחים" לא אפשרי במשלוח לארה"ב.
  2. שינוי בשדה אחד גורם להופעה/הסתרה (show/hide) או איפשור/נטרול (enable/disable) של שדות או כפתורים אחרים בטופס. למשל, בחירת "איסוף בחנות" באותו שדה "סוג משלוח", תנטרל או תעלים את כל שדות הכתובת למשלוח – הם אינם נחוצים במקרה זה.
  3. שילוב של 1 ו-2. למשל, בחירת "ארה"ב" בכתובת למשלוח, תגרום לאיפשור של השדה "מדינה", ותמלא ברשימת הערכים האפשריים את המדינות של ארה"ב. בחירת "אוסטרליה" תשנה את רשימת הערכים ב"מדינה" למדינות של אוסטרליה. בחירת "ישראל" תנקה את רשימת הערכים האפשריים ב"מדינה", ותנטרל את השדה.

תלויות בין שדות טומנות בחובן סכנות שמאיימות על הצלחת הממשק, אותן אפרט למטה.

הסכנות לממשק רלוונטיות בעיקר בטפסים שמשמשים לעריכה של מידע קיים. גם בטפסים להזנת של מידע חדש, בהם שינוי בשדות משפיע על השדות שמעליהם (כאלה שכבר הוזן בהם מידע), תלויות עשויות לסכן את הממשק. כשההשפעה היא רק על שדות שטרם הוזן בהם מידע, הסיכון פחות גדול. רוב הסיכויים שהמשתמש עוד לא ראה את השדות שבהמשך, ושינויים בהם לא יפריעו לו. יוצא דופן בהקשר הזה הוא כפתור הפעולה הראשית ("שלח", "עדכן" וכו'). כשמנטרלים אותו, בגלל ערכים שגויים בטופס למשל, המשתמש עשוי ללכת לאיבוד – הוא לא יבין למה הוא לא יכול לסיים עם הטופס ולהמשיך הלאה.

שינויים אוטומטיים שהמשתמש לא מודע אליהם

שינויים אוטומטיים קשורים בתלות מהסוג הראשון. שינויים כאלה הופכים להיות מסוכנים כשהשדות התלויים לא נמצאים בסמוך אחד לשני, או כשהקשר בין השדות התלויים לא ברור מאליו. הכוונה לטפסים שיש בהם "חוקים עסקיים" (business logic או business rules), שגם אם הם משוקפים נכון בהתנהגות של הטופס, לא יהיו ברורים למשתמש מזדמן.

קרם ברולה. מממממ

קרם ברולה. מממממ

הנה דוגמא ל"חוקים עסקיים" כאלה. תארו לכם מערכת של קוּפָּה בבית קפה. בבית הקפה יש מנות שלא ניתן לארוז ולקחת ב-takeaway, למשל קרם ברוּלֶה שחייבים לאכול במקום. זהו "חוק עסקי": אם מזמינים קרם ברולה, אי אפשר לארוז את ההזמנה. בתחילת ההזמנה הקופאי מזין את השדה "סוג הזמנה": "לאכול במקום", או "לקחת". סוג ההזמנה ממשיך להופיע בראש הטופס לכל אורך תהליך ההזמנה. הלקוח מזמין סנדוויץ', קפה, עוגה ובסוף – קרם ברולה. כשהקופאי מזין "קרם ברולה", סוג ההזמנה משתנה אוטומטית ל"לאכול במקום", כמימוש של ה"חוק העסקי" שהזכרנו קודם. קופאי חדש לא ישים לב, לא יֵדע לעצור את ההזמנה, ולהגיד ללקוח שאי-אפשר לארוז אותה ל-takeaway. ההזמנה לא תצא כ-takeaway והלקוח יבזבז זמן יקר בהמתנה לאריזה של הסנדוויץ', הקפה והעוגה, ויאלץ לאכול את הברולה במקום (המסכן).

אז מה עושים? כדי להתמודד עם בעיות מהסוג הזה, יש כמה דרכים מוּכּרות:

  1. לא לבצע שינויים אוטומטיים. למשל, במקרה שתארנו כאן אפשר היה בסוף ההזמנה, לפני התשלום, להציג לקופאי הודעה:
    לא ניתן לקחת את ההזמנה, כי יש בה פריטים שלא ניתן לקחת: קרם ברולה. לפצל לשתי הזמנות?
    פיצול לשתי הזמנות מסרבל את התהליך של הקופאי. אם זה מקרה שימוש נפוץ במערכת, היה עדיף לאפשר לציין עבור כל פריט בנפרד האם הוא למשלוח או לא.
  2. להודיע למשתמש שיש בעיה, ולבקש ממנו להחליט מה לעשות.
    לא ניתן לקחת קרם ברולה. לשנות את סוג ההזמנה ל"לאכול במקום"?
    החסרון בהודעה כזאת הוא שהוא דורש מהמשתמש להחליט. אם אחת האפשרויות תהיה נפוצה יותר באופן משמעותי, עדיף לפעול על-פי מה שמוגדר בסעיף 3.
  3. לבצע שינוי אוטומטי, ולהודיע למשתמש על השינוי שבוצע. מיד אחרי שהקופאי הזין "קרם ברולה", היה אפשר להציג לו הודעה:
    לא ניתן לקחת קרם ברולה. סוג ההזמנה השתנה ל"לאכול במקום".
    או לחילופין:
    לא ניתן לקחת קרם ברולה. המנה לא התווספה להזמנה.
    החסרון (והיתרון) בשתי האפשרויות האלה הוא שבשתיהן אנחנו בוחרים אוטומאטית עבור המשתמש את מה ששאלנו אותו באפשרות הקודמת. חסרון – כי אנחנו לא מאפשרים לו לבחור, אלא מציבים בפניו עובדות. יתרון – כי אנחנו חוסכים ממנו את ההחלטה. במקומות שבהם יש נטיה ברורה לאחת האפשרויות, עדיף לבחור עבור המשתמש את האפשרות הנפוצה ולתת לו לשנות את הבחירה האוטומאטית בצורה ידנית בעת הצורך.
    במקרה הזה אני נוטה להניח שהמוטיבציה לקחת את ההזמנה (ולא לאכול במקום) היא חזקה מהמוטיבציה להזמין דווקא קרם ברולה, כך שעדיף להציג את ההודעה השניה – המנה לא התווספה.
  4. לשנות את סדר השדות, כך שהשדות המושפעים יהיו בסוף הטופס. היה אפשר להעביר את השדה "סוג הזמנה" לסוף, ואז הקופאי היה מגלה בסוף ההזמנה שהערך "לקחת" לא אפשרי. כדי להקל עליו, היה אפשר לרשום הערה בולטת בחשבון ליד "קרם ברולה", שמסבירה שאי-אפשר לארוז אותו למשלוח. כשהקופאי היה מוסיף את הברולה לחשבון, היה רואה מייד את ההערה ולא היה צריך לשאול למה אי אפשר לארוז את ההזמנה.

בעיני אפשרות 3 היא העדיפה, כי היא נותנת לקופאי משוב מיידי על הפעולה שלו, ומאפשרת לו להעביר מייד את אותו המשוב ללקוח שעומד מולו.

הצגה/הסתרה של חלקים מהטופס

הצגה והסתרה של חלקים מהטופס משרתות מטרה חשובה. הן מסייעות לשמור על הטופס תמציתי וממוקד, מציגים רק את מה שהמשתמש צריך להזין. אך הסתרה של חלקים מהטופס עשוייה ליצור דיסאוריינטציה – בלבול. המשתמש שראה טופס שבנוי בצורה מסויימת, רואה לפתע טופס שבנוי אחרת.

תארו לעצמכם ממשק כזה, בדף ההזמנה של אתר דמיוני למכירת מוצרי תוכנה:

משלוח

עבור האפשרות השניה והשלישית נחוצים פרטים נוספים – לצורך העניין, נניח שלשליח נחוצה כתובת פיזית, ולהורדה מהאתר כתובת אימייל. איפה נציג את הפרטים הנוספים הדרושים? אפשרות אחת היא בתוך הטופס:

שליח

כשבוחרים "הורדה מהאתר", השדות מתחת ל"שליח" נעלמים, ונוסף שדה "אימייל" מתחת ל"הורדה מהאתר":

radio4

עד כאן זה די ברור, פחות או יותר. עכשיו תדמיינו שלחצתם על "שליח", אבל התכוונתם בעצם ללחוץ על "הורדה מהאתר". כמה זמן ייקח לכם למצוא את "הורדה מהאתר" במקומו החדש? כמה זמן היה לוקח לכם לעשות את זה אם היו תחת שליח 10 שדות ולא 5 כפי שמוצגים כאן? ומה אם היו 6 אפשרויות לסוג משלוח, ולא רק 3?

אחד העקרונות החשובים בממשק משתמש הוא עקביות. כשאנחנו מסתירים חלקים מהממשק או משנים את מקומם, אנחנו פוגעים בעקרון הזה. זה לא אומר שאי-אפשר להסתיר חלקים מהממשק, אלא רק שצריך להגן על המשתמש מבלבול כשאנחנו עושים את זה.

פתרון אפשרי אחד, הוא להציג את השדות המשתנים מתחת לטופס:

radio3

מאחר והמשתמש ממלא את הטופס לפי הסדר, הוא לא יוטרד מהעלמותם של חלק מהשדות אם עוד לא מילא אותם.

פתרון אחר הוא לבקש את הפרטים הנוספים מהמשתמש בטופס נפרד, בחלק אחר של התהליך. פתרון זה מסרבל את תהליך העבודה של המשתמש, ולכן רצוי להשתמש בו רק כשאין ברירה אחרת.

ניטרול הפעולה הראשית וחלקים מהטופס

"חוקים עסקיים" כמו בדוגמא של בית הקפה עשויים להשפיע לא רק על ערכים בשדות, אלא גם על הזמינות של הפעולה הראשית בטופס, או חלקים בתוך הטופס. למשל, תארו לעצמכם שבאותה מערכת של בית הקפה, יש שתי פעולות ראשיות (כפתורים): "לאכול כאן" ו"לקחת", שמופיעים  בסוף טופס ההזמנה בקופה. אם נבחר פריט שאי אפשר לקחת, כמו קרם ברולה, הכפתור "לקחת" ינוטרל אוטומטית. לכאורה, ניטרול הכפתור "לקחת" מבטא בצורה נכונה את החוק העסקי. אבל כמו בעדכון האוטומטי של ערכי השדות שהצגתי למעלה, המשתמש לא בהכרח יבין את הקשר בין הבחירה בקרם ברולה לניטרול הכפתור.

אפשר לחשוב על שני פתרונות פשוטים לבעיה:

  1. לא לנטרל את הכפתור. כשהקופאי ינסה ללחוץ על "לקחת", תופיע הודעה שמסבירה את העניין עם קרם הברולה.
  2. לבטא בבירור את החוק העסקי כחלק מהטופס. למשל, להציג ליד כל פריט האם אפשר לקחת אותו ב-takeaway או לא.

נראה ששילוב של 1 ו-2 ייתן פתרון מלא לבעיה. לא תמיד ניתן לבטא את החוק העסקי כחלק מהטופס, בעיקר כשהחוק מורכב מאוד, או שיש חוקים רבים. במקרים אלה חשוב במיוחד לא לנטרל את כפתור הפעולה הראשית, כדי לאפשר למשתמש ללמוד מה אפשר לעשות בעזרת המערכת ומה לא.

ניטרול של חלקים מטופס עשוי להיות פתרון לבעיית הדיסאוריינטציה שהסתרה שלהם תיצור (כפי שהצגתי בכותרת הקודמת). בספריית העיצוב של blink מציגים בקצרה את ההתלבטות בין הסתרה לניטרול. גם כאן, חשוב לאפשר למשתמש להבין מה מנטרל את מה. כדי לעזור למשתמש להבין, רצוי להצמיד את השדה המנטרל לשדה המנוטרל, ולא לנטרל שדות שלא צמודים אליו. כשהניטרול האוטומטי קורה קרוב, המשתמש יכול לראות את הניטרול במבט אחד יחד עם הבחירה שגורמת לניטרול. כשהשדות המנוטרלים רחוקים המשתמש יפספס את הניטרול, וכשיגיע לשדה המנוטרל לא יבין למה אי אפשר להזין בו מידע.

כמו בכל פתרון אחר שמוצג פה, גם כאן חשוב להפעיל שיקול דעת ולחשוב על הסיטואציה הספציפית שמטפלים בה, מי קהל היעד של המערכת ומה הסביבה שהוא עובד בה. האם המשתמש מזדמן או קבוע? סביבת העבודה מאפשרת לו להתרכז במערכת שלנו, או שהיא מושכת את תשומת הלב שלו החוצה? וכן הלאה.

עוד על טפסים: רשימת קריאה מומלצת

הנושא של טפסים, כפי שראיתם בפוסט הזה ובאלה שקדמו לו, הוא מורכב ועשיר מאוד. יש נושאים שלמים שלא כיסיתי כאן, וגם בנושאים שכיסיתי, היה אפשר לרדת הרבה יותר לעומק. כדי לכסות את הנושא באופן מלא, נחוץ קורס או ספר שלם. המלצתי בפוסטים הקודמים על כמה קישורים ללימוד על טפסים, ואני מביא אותם כאן שוב במרוכז, ועוד כמה אחרים:

אתם מוזמנים ומוזמנות להוסיף כאן בתגובות עוד קישורים שימושיים שמצאתם בנושא, אני משוכנע שיש רבים שיישמחו לראות.

לכל הפוסטים בסידרה

חלק ראשון: זרימה בטופס ויישור תוויות.

חלק שני: עזרה והסברים, ובדיקות תקינוּת (וָלידציות).

חלק שלישי: פעולה ראשית ופעולות משניות, ומספר השדות בטופס.

חלק רביעי (הפוסט הזה): תלויות בין שדות, ורשימת קריאה מומלצת.