אנשים עושים הרבה טעויות. אין מה לעשות עם זה. ליתר דיוק, אפשר לתת להם שוקים חשמליים, אבל זה פאסה. לכן חלק גדול מהעבודה של אנשי ממשק היא להתמודד עם הטעויות העתידיות של המשתמשים שלהם. זה חשוב. ולהתמודדות שלנו עם טעויות המשתמשים יש שני היבטים – מניעת טעויות והתאוששות מטעויות. הראשון אומר שעד כמה שאפשר, צריך להשתדל למנוע מהמשתמש לבצע את הטעות, והשני אומר שאם הוא כבר ביצע אותה, אז צריך שהיא לא תעלה לו יותר מדי ביוקר ושיוכל לתקן אותה בקלות.
לדוגמא, ניקח טופס הרשמה לשירות כלשהו. נגיד שהטופס מכיל עשרה שדות, ובסוף יש כפתור "שלח". אני יכול לתת למשתמש להזין את כל השדות, להגיש את הטופס, ואח"כ לבדוק האם השדות עומדים בכללי התקינות שהגדרתי (למשל, ששדה כתובת האימייל אינו מכיל רווחים וכן מכיל את התו @). אם כל השדות בסדר, אני ממשיך, ואם אחד מהם לא בסדר, אני צועק קצת על המשתמש עם הודעת שגיאה, ומחזיר אותו למלא את הטופס מחדש, כשכל השדות ריקים. כאן לא מנעתי טעויות, וגם לא ממש נתתי לו דרך התאוששות טובה.
לתת דרך התאוששות טובה זה להחזיר אותו לטופס כשרק השדות הבעייתיים ריקים, ורק הם דורשים מילוי מחדש. דרך התאוששות עוד יותר טובה היא לא להחזיר אותו בכלל, אלא לרכז לו את השדות הבעייתיים במסך הודעת השגיאה – ככה המשתמש ירגיש שהוא מתקדם, ושהוא לא חוזר אחורה.
למנוע את הטעות זה להסתכל לו מעל הכתף כשהוא ממלא את השדות, וברגע שאני רואה שהוא מנסה לשים רווח בשדה המייל, או שהוא עבר לשדה הבא מבלי לשים שם שטרודל, להגיד לו שזה לא הולך, ושהכתובת לא יכולה להכיל רווחים אבל היא כן חייבת להכיל @.
כשמדובר בטעות ספציפית, לעיתים קרובות שני ההיבטים האלה שוללים זה את זה. כלומר, אם אני יודע למנוע מהמשתמש לבצע טעות, אז אין לי מה לתכנן את דרכי ההתאוששות ממנה, כי הוא לעולם לא יבצע אותה. ובמקרים כאלה עולה הדיון לגבי מה עדיף – מניעה או התאוששות.
ובעיקרון קיימת הסכמה די גורפת שעדיף למנוע טעות מאשר לנסות לתקן אותה לאחר שנעשתה, כפי שיספר לכם כל רופא נשים.
הבעיה, כמו תמיד, מתחילה כשעושים את זה באופן קיצוני. למשל בדוגמת המייל, אני יכול לתכנת את השדה כך שהוא פשוט לא יקבל הקשת רווח – המשתמש ילחץ על המקש, ושום דבר לא יקרה. כל עוד אני מלווה את זה בהודעה בולטת שמסבירה מדוע אני לא מקבל רווחים, זה בסדר. אבל מה נעשה עם כלל השטרודל? לא נאפשר לו לצאת מהשדה לפני שקיים שם @? נתעלם מלחיצות בשדות אחרים? יש כללים שמאוד קשה לאכוף, ומבחינת חוויית המשתמש אמצעי האכיפה שנדרשים לזה מתקרבים במהירות לתחום השוקים החשמליים.
גם בכללים שקל לאכוף, לא תמיד קל לעשות את זה טוב.
באתר חברת התעופה Air Asia החליטו למנוע טעויות בחיפוש טיסה. Air Asia פיתחו אתר באמת מאוד מושקע, אבל גם הם לא קוסמים, והם לא יכולים לשים אותך על טיסה שיצאה אתמול. לכן ברכיב חיפוש הטיסה הם החליטו לבוא לקראת המשתמש ולמנוע ממנו את הטעות של לבחור תאריך מן העבר. מדובר בבעיה נפוצה, שבערך כל חברות התעופה והתחבורה מתמודדים איתה, ובאופן כללי כל אתר שבוחרים בו תאריך עתידי.
לרוב, לא מדובר בבעיה גדולה. פותחים רכיב תאריכון, חוסמים בו את הימים שכבר עברו, וזהו. כך עושים את זה באל-על:
שימו לב שאין דרך אחרת להזין את התאריך, וההצגה הנומרית היא לתצוגה בלבד.
אבל באייר אסיה כן יש דרך אחרת:
אני כותב את זה בחמישי לנובמבר. תפריט הימים באתר מתחיל מהמספר 5. זה אומר שאם אני רוצה לחפש טיסה שיוצאת בתחילת דצמבר, ינואר או כל חודש אחר, אין לי אפשרות כזאת. אני חייב קודם ללכת לתפריט החודשים ולבחור כל חודש מלבד נובמבר – ואז ימים 1-4 יופיעו לי בתפריט הימים. מה שיוצא זה שקודם כל אני אנסה את השדה הראשון שמוצע לי, אראה שאין שם את היום הרצוי, אנסה להבין למה רשימת הימים מתחילה מחמש, אפתח ואסגור את התפריט שוב ליתר ביטחון, אוודא שלא גללתי בטעות למטה ברשימה, אגיע למסקנה שזה בגלל החודש, אלך לשדה הבא, אחליף חודש, אחזור לשדה הקודם, ואז אבחר את היום הרצוי. לא תהליך יעיל במיוחד.
בואו נראה כמה דברים שאפשר לעשות.
1. אם אתם יוצרים תלות בין שדות, כדאי לשים אותם בסדר שבו פועלת התלות שהגדרתם. במקרה הזה – קודם חודשים ואחר-כך ימים. הבעיה היא שזה פחות סטנדרטי, אבל יש בעיה יותר גדולה, ווהיא שגם אם שמתם אותם בסדר הנכון, אף אחד לא מבטיח שזה הסדר שבו המשתמש ימלא אותם. לכן,
2. אפשר לשקול לחסום את השדה התלוי עד שתתבצע בחירה בשדה השולט. ספציפית כאן לא כדאי לעשות גם את זה, כי זה יאלץ אותנו לוותר על ערכי ברירת המחדל הקיימים בשדות, וחבל. ערכי ברירת מחדל זה דבר חשוב.
3. יש גם אפשרות לפתח תלות דו-כיוונית – לא משנה באיזה שדה מתחיל המשתמש, השדה השני משתנה בהתאם. אבל גם זה עובד טוב רק בשדות ללא ערכי ברירת מחדל, כי אחרת הבחירה כבר נעשתה למעשה.
4. אפשרות נוספת היא לעשות את זה בדיוק כפי שעשו ב-Air Asia, אבל לא להוריד את הימים שעברו, אלא רק לחסום אותם (לסמן ויזואלית – בד"כ באפור, ולא לאפשר לבחור בהם). זה הופך את המנגנון לברור יותר, והמשתמש מבין יותר מהר שיש סיבה לכך שהימים האלה חסומים. אבל זה עדיין מכריח אותו ללכת קדימה ואחורה.
עברתי כאן על כמה פתרונות לרכיב הזה, ואני לא מרגיש שמשהו מהם באמת נותן מענה טוב יותר ממה שיש היום. אבל מה שיש היום הוא לא טוב. מילא אם מדובר בתחילת החודש, וחסרים לנו רק כמה ימים מהרשימה. אבל אם היום ה-31 לחודש, אז יש לי רק יום אחד בשדה הראשון, ואני בוודאות אצטרך להזין את החודש לפני שאני מזין את היום.
פתרון טוב הוא מה שעשו באל-על. שימוש בתאריכון חוסך את כל הבעיות האלה, אבל לא בטוח שהוא מתאים לאנשים בעלי היכרות נמוכה עם המחשב, כי מדובר ברכיב יחסית מתקדם.
הפתרון, אם רוצים להיצמד לרעיון הטופס, הוא פשוט לוותר על מניעת הטעות ולהשקיע בההתאוששות ממנה. הניסיון למנוע אותה גורם לנו לפתח לוגיקות שמבלבלות את המשתמש, מכריחות אותו לחשוב צעד אחד קדימה, או גורמות לו ללכת הלוך וחזור בין השדות. וזה יהיה נכון לכל המשתמשים שנחשפים לרכיב הזה – גם אלה שהיו עשויים לבצע את הטעות, וגם אלה שלא. זה פוגע בחוויית השימוש לכולם.
לעומת זאת, אם נשאיר את כל הימים ואת כל החודשים זמינים תמיד, אז המשתמשים היחידים ש"ייפגעו" מזה יהיו אלה שבאמת הזינו בטעות תאיריכים מן העבר, ומדובר באחוזים די קטנים. והפגיעה תתבטא בזה שנראה להם הודעת שגיאה שאומרת "התאריך שהזנת כבר עבר – אנא בחר תאריך חדש".
"אם אני יודע למנוע מהמשתמש לבצע טעות, אז אין לי מה לתכנן את דרכי ההתאוששות ממנה"
אוי ואבוי. ירחם הג'ובס עליך ועל מי שקורא את העצה הזו.
מה קורה אם המשתמש ניטרל ג'אווה-סקריפט בדפדפן שלו ומנגנון מניעת הטעות לא עובד? כרגע חשפת את הדטהבייס של החברה שלך להשחתת נתונים מהסוג הגרוע ביותר. תמיד תמיד חייבים לעשות אימות של הנתונים בצד השרת, גם אם עשית זאת כבר בצד הלקוח.
הי שי,
תודה על ההבהרה – אבל אני מדבר רק מבחינת האפיון. בגלל שאני לא מומחה בתחומים המשיקים, המטרה היא תמיד לערב את אנשי המקצוע הרלוונטיים בתהליך האפיון כמה שיותר מוקדם, ואז הם יכולים להגיד למשל את מה שאתה אמרת, אם זה מבחינת האבטחה או הביצועים או כל דבר אחר. אני אומר "_אם_ אני יודע למנוע טעויות", ואז המפתח יכול להגיד "אבל אנחנו לא יודעים למנוע טעויות ב-100 אחוז מהמקרים", ואז מאפיינים בהתאם. יש מצבים שבהם בהחלט אפשר למנוע כל טעות אפשרית, ואז באמת שאין סיבה לאפיין דרכי התאוששות 🙂
אני חושב שבדוגמא שהבאת פשוט לקחו תוכניתן טיפש שיתכנת פתרון עבור משתמש טיפש.
אך אל דאגה – בזמן שכתבת את הפוסט, אותו תוכניתן טיפש כבר קודם לדרגת מנהל זוטר 🙂
או אפשר פשוט להאדים את השדה עד שהקלט יהיה תקין
חיים – זה מאוד בעייתי כשבדיקת התקינות תלויה בצירוף של ערכי שני השדות, כי זה לא שאחד מהם מכיל ערך לא נכון. שניהם מכילים ערכים תקינים, שלא יכולים להתקיים בו-זמנית, אז שינוי בכל אחד מהם הופך את הצירוף לתקין.
כמובן שבדוגמא עם המייל אתה צודק.
רוצה לראות טופס מזעזע באתר אינטרנט מרכזי?
תכנס בבקשה ל-www.assuta.co.il ותנסה לתפעל את השאילתא של "פנייה אישית", באמצע המסך. עם כל תחילת הקשה בשדה כלשהו, נמחק התיאור של השדה, מבלי יכולת להשיבו חזרה. מעצבן ברמות בינלאומיות…
כן, זה מה שקורה כשמנסים לחסוך 20 פיקסל (שורת התוויות). ותודה על ההפניה לאתר – יש שם משהו די מדהים, אני אכתוב על זה בפוסט הבא. בתקווה אפילו היום.
דווקא לעניין הזה יש פתרון סטנדרטי ודי נפוץ, ולטפסים קצרים ובסיסיים הוא מספיק בהחלט.
למשל בטאמבלר: https://www.tumblr.com/
כתבה ממש מעניינת, תודה!
צריך תמיד לנסות ולשלב בין פתרון לטעויות לבין מניעתן, לפעמים יש טעויות שלא ניתן למנוע אך המאפיין חייב לחשוב על איך לפתור אותן.
הדוגמא הכי טובה שיש לי לפתרון לטעות הוא הפופ-אפ שהג'ימייל מקפיץ לך אם שכחת לצרף קובץ למייל (אחרי שכבת בפנים את המילה "צירפתי").
אייר אסיה בכלל הם דוגמא לחווית משתמש גרועה בצורה יוצאת מהכלל. לפני חצי שנה איכשהו הצלחתי להזמין בטעות טיסה עם קונקשן, כשהקונקשן ממריא לפני שהטיסה הראשונהה נוחתת. בשום שלב האתר לא חשב לומר לי "היי, את מזמינה פה טיסה שאין מצב שתוכלי לעלות עליה", ונתן לי להשלים את ההזמנה. מובן שאחר כך נאלצתי לשלם תוספת על השינוי הנדרש בטיסה, כששמתי לב לטעות.
תודה מיכל, שמח שאהבת! כן, הטריק של ג'ימייל די מגניב. לגבי הקונקשן – חוצפה!
[…] בתגובות לפוסט הקודם הפנה אותי דני לאתר ביה"ח אסותא. דני התעצבן מטופס הפנייה האישית במרכז המסך, שבו תוויות השדות נעלמות ברגע שנכנסים לתוך השדה, ואין דרך להחזיר אותן לבד מלרענן את העמוד. דני כמובן צודק, וזה אכן מעצבן. מי שעיצב את האתר כנראה חשב שהוא יכול לחסוך 15 פיקסל אם הוא יוריד את שורת התוויות ויכניס אותן לתוך השדות. זה כשלעצמו לא רעיון טוב, כי נעדיף שהמשתמש יוכל לקרוא את התווית תמיד, אבל אם כבר עושים זה, צריך לפחות לפרט שבמידה ויוצאים מהשדה מבלי שהוזן בו תוכן, התוויות חוזרות. […]