日期欄位明明選好了,按「繼續」卻停在原頁。先把欄位的實際值、min、max 和 step 並排看。可見的日期格式、可接受的範圍,以及間隔規則是不同條件,不只看日曆裡有沒有選中一天。
原生 input type="date" 能提供日期輸入與瀏覽器驗證,但網站仍需要自己的服務端規則。這篇先找出欄位為何無效,不把前端通過當作預約已成立或資料已保存。
畫面上的日期與欄位值分開看
瀏覽器可依地區設定顯示不同日期順序,欄位的 value 則使用 yyyy-mm-dd。例如畫面可能顯示 05/10/2026,程式讀到的是 2026-10-05。不要把本機顯示的斜線格式直接寫進 min 或 max。
<input type="date" name="booking_date"
min="2026-10-04" max="2026-10-10" required>
範圍值要是有效的日期字串,最早日期也不能晚於最晚日期。錯誤格式可能使對應的範圍限制無效;不要看到日曆還能開啟,就認定屬性已經正確工作。
也核對真正渲染出的屬性。模板可能按目前日期動態設定範圍,或由腳本在載入後改值。設定檔寫的是這個月,輸入框最後拿到另一組日期,仍要依實際 DOM 找出產生差異的位置。
min 與 max 只處理上下限
這份示範欄位最早是 2026-10-04,最晚是 2026-10-10。前後兩個邊界本身可以接受;10 月 3 日早於 min,10 月 11 日晚於 max,則不符合這個範圍。
原生日曆通常能以可選日期協助使用者理解限制,但外觀和操作方式由瀏覽器提供。不要依賴某一種灰色日格,當作所有環境都會有相同提示。把可用範圍寫在欄位旁,訪客即使直接用鍵盤輸入,也能知道需要選哪段日期。
如果產品只允許未來預約,先定義「今天」依哪個時區計算,再由適合的位置產生 min。不要在訪客本機午夜與伺服器日期不同時,讓兩邊各自採用矛盾的界線。這篇使用固定合成日期來隔離範圍問題,不會隨當天時間改動。
範圍裡的日期,仍可能不符合 step
示範另外設定 step="2",表示以指定的基準每隔兩天為有效日期。這裡已有 min,因此以 2026-10-04 為起點:4、6、8、10 日符合;5 日雖然在上下限之間,仍不符合間隔。
<input id="booking-date" name="booking_date" type="date"
min="2026-10-04" max="2026-10-10" step="2" required>
日期欄位的 step 單位是天,預設為 1。沒有 min 時,step 基準還可能由 HTML 初始 value 屬性或預設基準決定,不能把「2」只理解成偶數日。若業務是每週特定星期開放,要先確定基準;若是節假日或不規則排程,單靠固定間隔並不足夠。
看本例的瀏覽器判斷
在自建桌機頁面中,我們依序測試最早日期之前、最早日期、間隔不符、最晚日期,以及最晚日期之後。讀取原生 validity:3 日有 rangeUnderflow,11 日有 rangeOverflow,5 日有 stepMismatch;4 日與 10 日符合這份欄位條件。
填入 5 日再按繼續,瀏覽器擋下原生提交,頁面仍停在日期表單。畫面同時顯示瀏覽器的間隔提示,以及示範頁的「不符合每隔兩天」文字。改用 6 日後,原生提交才到達合成入口。

我們也從 4 日使用鍵盤增加一天,欄位變成 5 日,原生 validity 同樣回報 stepMismatch。這說明不能只驗日曆選取:鍵盤編輯後的值仍需核對。瀏覽器可能有自己的調整或捨入行為,所以觀察的是最後欄位值與狀態,不預設每種控制方式都相同。
用 validity 找到具體原因
在自己的測試頁可以讀取幾個相關欄位:
const field = document.querySelector('#booking-date');
({
value: field.value,
min: field.min,
max: field.max,
step: field.step,
valid: field.validity.valid,
tooEarly: field.validity.rangeUnderflow,
tooLate: field.validity.rangeOverflow,
wrongStep: field.validity.stepMismatch,
missing: field.validity.valueMissing
});
同一個日期可以同時違反範圍與間隔,不能假定只會有一個 true。錯誤文字可先說最容易修正的原因,例如先提示日期晚於最晚日,再讓使用者選回範圍。文字、欄位屬性與實際值應對上同一份規則。
若程式把不合日期格式的字串指派給 value,原生日期欄位可能把它整理為空字串。本例指派斜線格式後,讀到空值,required 因而回報 valueMissing。這與「早於 min」是不同問題;要查看最後值,不只看程式原本想寫進去什麼。
前端提醒與服務端規則保持一致
HTML 驗證能幫正常操作的訪客提早修正,但請求可以直接發送,前端屬性也能改。服務端仍要解析日期、核對範圍與業務條件,並處理名額、時區或其他限制。不要因欄位的 valid 為 true,就寫成預約成功。
本例有效日期送到本機入口後,只顯示收到的查詢,不做服務端業務驗證。正式接收端若拒絕日期,保留輸入並顯示對應原因;不要用前端一直放寬 max 的方式掩蓋兩邊規則不同。
也確認表單是否有 novalidate,或按鈕有 formnovalidate。這些設定會影響原生提交時是否進行互動驗證,不能一邊停用驗證,一邊期待瀏覽器替你阻止所有無效輸入。
最後用邊界和鍵盤重試
用最早前一天、最早當天、最晚當天、最晚後一天,加一個間隔不符日期和空白,核對 value 與錯誤原因。再用鍵盤修改一次,確認狀態跟著更新。只測一個可選日期,容易漏掉真正導致訪客停住的條件。
範圍與文案對齊後,再在網站支援的瀏覽器及實際接收流程確認。若需要撤回,只還原這個欄位的屬性與相關提示,不順便更換整份日期元件或放寬正式預約規則。

評論0