Menu

HTML form: שדות, action, method, fieldset ואימות

איך בונים טופס ב-HTML: האלמנט form, מאפייני name, action ו-method (GET מול POST), קיבוץ עם fieldset ו-legend, אימות מובנה עם required ו-pattern, וטיפול בשליחה ב-JavaScript.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

איך יוצרים טופס ב-HTML

טופס הוא אלמנט <form> שמכיל שדות וכפתור שליחה. כל שדה צריך name: זה המפתח שתחתיו הערך נשלח. מלאו את הטופס ולחצו על Send. התצוגה המקדימה לא שולחת שום דבר לשום מקום; היא מציגה בדיוק מה הדפדפן היה שולח.

החלקים:

  • action הוא הכתובת שאליה הנתונים הולכים, ו-method הוא האופן (כאן post).
  • name על כל שדה. הערך שלו הוא מה שהקורא הקליד.
  • <label> נותן שם לכל שדה על המסך ועבור קוראי מסך (ראו HTML label).
  • required ו-type="email" גורמים לדפדפן לבדוק את השדות לפני השליחה. נסו לשלוח עם שם ריק, או עם abc בתור אימייל.
  • כפתור השליחה שולח את הטופס. גם לחיצה על Enter בשדה טקסט עושה את זה.

action ו-method: לאן ואיך הנתונים הולכים

מאפייןערכיםברירת מחדל
actionכל URLה-URL של העמוד הנוכחי
methodget, post, dialogget
enctypeapplication/x-www-form-urlencoded, multipart/form-data, text/plainapplication/x-www-form-urlencoded

עם method="get", השדות הופכים למחרוזת השאילתה של הכתובת: טופס חיפוש עם name="q" הולך אל /search?q=blue+shoes. זה נכון לחיפושים ולמסננים, כי אפשר לשמור את התוצאה בסימניות ולשתף אותה. עם method="post", השדות נשלחים בגוף הבקשה ולא מופיעים בשורת הכתובת או בהיסטוריה. השתמשו ב-POST לכל דבר שמתחבר, יוצר, משנה או מוחק משהו, ולסיסמאות.

טופס עם העלאת קובץ (<input type="file">) צריך method="post" ו-enctype="multipart/form-data", אחרת נשלח רק שם הקובץ. method="dialog" מיועד לטופס בתוך <dialog>: השליחה סוגרת את הדיאלוג במקום לשלוח בקשה.

מה נשלח

רק שדות עם name נשלחים, ורק כשהם לא disabled. לחצו על Submit והשוו את השדות למה שהטופס שולח:

הטופס שולח city, zip, source ו-action. השדה בלי שם, השדה המושבת וה-checkbox הלא מסומן נשארים בחוץ. שדות מוסתרים נשלחים אבל אף פעם לא מוצגים, וכפתור השליחה שולח את ה-name וה-value שלו כי זה הכפתור שבו השתמשו.

קיבוץ שדות עם fieldset ו-legend

<fieldset> מצייר תיבה סביב שדות קשורים, ו-<legend> הוא הכיתוב שלה. קוראי מסך מכריזים את ה-legend כשהמיקוד נכנס לקבוצה, וזה מה שהופך קבוצת כפתורי רדיו כמו אלה שלמטה למובנת: "Delivery, Standard, radio button".

disabled על fieldset משבית בבת אחת כל שדה שבתוכו, ואף אחד מהם לא נשלח. הסירו אותו ושדות המתנה יהפכו לשמישים.

אימות מובנה: required, pattern והחברים שלהם

דפדפנים בודקים את המאפיינים האלה לפני השליחה ומציגים הודעה על השדה הראשון שנכשל:

מאפייןבודק
requiredהשדה לא ריק (checkbox מסומן)
type="email", type="url"הערך נראה כמו כתובת אימייל או URL
minlength, maxlengthאורך הטקסט
min, max, stepטווח מספרים ותאריכים
patternהערך כולו תואם לביטוי רגולרי

:invalid ו-:valid מעצבים שדות לפי המצב שלהם. :user-invalid בדרך כלל עדיף: הוא חל רק אחרי שהקורא שינה את השדה ועבר הלאה, או ניסה לשלוח, כך שטופס ריק לא נפתח כשהוא מכוסה באדום.

שלושה דברים ב-pattern מכשילים אנשים. הוא חייב להתאים לערך כולו (אין צורך ב-^ או $). הוא רץ רק כשהשדה לא ריק, אז שלבו אותו עם required. והודעת השגיאה של הדפדפן כללית, אז תארו את הפורמט בטקסט גלוי ליד השדה. Chrome ו-Firefox מוסיפים את טקסט ה-title להודעה שלהם, אבל קל לפספס אותו.

כדי לכבות את הבדיקות, למשל כשאתם בודקים את האימות של השרת, הוסיפו novalidate ל-<form>. כפתור שליחה יחיד יכול לדלג עליהן עם formnovalidate.

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

הודעות מותאמות עם setCustomValidity

כשאי אפשר לכתוב כלל כמאפיין, כמו "שתי הסיסמאות חייבות להיות זהות", הגדירו את ההודעה מ-JavaScript. שדה עם הודעה מותאמת לא ריקה הוא לא תקין; מחרוזת ריקה הופכת אותו לתקין שוב:

לשדה החזרה אין name, כך שרק עותק אחד של הסיסמה נשלח.

טיפול בשליחה ב-JavaScript

כדי לשלוח את הטופס בלי לעזוב את העמוד, האזינו ל-submit, קראו ל-preventDefault(), וקראו את השדות עם FormData. האזנה ל-submit ולא ל-click של כפתור תופסת כל דרך שליחה, כולל Enter, ורצה רק אחרי שהאימות המובנה עבר:

Object.fromEntries(new FormData(form)) הופך את השדות לאובייקט פשוט. לשדות שיכולים להיות להם כמה ערכים (checkboxes שחולקים שם, select מרובה) השתמשו ב-formData.getAll('name') במקום, כי האובייקט שומר רק את הערך האחרון.

טעויות נפוצות

  • שדות בלי name. הם נשארים בשקט מחוץ לנתונים שנשלחים.
  • placeholders במקום תוויות. הרמז נעלם ברגע שהקורא מקליד. השתמשו ב-<label>.
  • <button> בלי type שמשמש למשהו אחר חוץ משליחה. בתוך טופס הוא כפתור שליחה.
  • טופס בתוך טופס. קינון טפסים אינו תקין; הדפדפן מתעלם מתגית ה-<form> הפנימית.
  • האזנה ל-click על כפתור השליחה במקום ל-submit על הטופס. שליחות עם מקש Enter מתפספסות.
  • הסתמכות על אימות הדפדפן בצד השרת. אמתו שוב שם.
  • GET לסיסמאות. הן מגיעות לכתובת, להיסטוריה וללוגים של השרת.

שאלות נפוצות

איך יוצרים טופס ב-HTML?

עטפו את השדות ב-<form action="/signup" method="post">, תנו לכל שדה name ו-<label>, וסיימו עם <button type="submit">. כשהטופס נשלח, הדפדפן שולח כל זוג name=value לכתובת ה-action.

מה ההבדל בין GET ל-POST בטופס?

method="get" (ברירת המחדל) מכניס את השדות לכתובת, כמו /search?q=shoes, מה שמתאים לחיפושים ולמסננים שכדאי שאפשר יהיה לשמור בסימניות. method="post" שולח אותם בגוף הבקשה, וזה מה שרוצים בהתחברות, בהרשמה ובכל דבר שמשנה נתונים.

למה שדה בטופס שלי לא נשלח?

אין לו מאפיין name, או שהוא disabled. רק שדות עם שם ופעילים נשלחים. גם checkbox או כפתור רדיו לא מסומנים לא נכללים בכלל.

בשביל מה משמשים fieldset ו-legend?

<fieldset> מקבץ שדות קשורים ו-<legend> הוא הכיתוב של הקבוצה. קוראי מסך מכריזים את ה-legend כשהמיקוד נכנס לקבוצה, וזה מה שהופך קבוצה של כפתורי רדיו למובנת, ו-disabled על fieldset משבית כל שדה שבתוכו.

איך מאמתים טופס ב-HTML בלי JavaScript?

השתמשו במאפיינים: required, type="email", minlength, maxlength, min, max ו-pattern. הדפדפן חוסם את השליחה ומציג הודעה לשדה הלא תקין הראשון. תמיד אמתו גם בשרת, כי הבדיקות האלה רצות בדפדפן של הקורא ואפשר לעקוף אותן.

איך מונעים מטופס לטעון מחדש את העמוד?

האזינו לאירוע submit של הטופס וקראו ל-event.preventDefault(), ואז שלחו את הנתונים בעצמכם עם fetch: form.addEventListener('submit', (e) => { e.preventDefault(); fetch(form.action, { method: 'POST', body: new FormData(form) }); }).

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל