1 điểm bởi GN⁺ 2025-11-13 | 1 bình luận | Chia sẻ qua WhatsApp
  • Hướng dẫn đề xuất các cách nhập đơn giản và có khả năng truy cập cao thay cho bộ chọn ngày JavaScript phức tạp
  • Tận dụng phần tử nhập liệu mặc định của trình duyệt (date, time, datetime-local) để tự động có được khả năng truy cập, hiệu năng và hỗ trợ quốc tế hóa
  • Có thể đơn giản hóa UI phức tạp bằng các trường nhập tách biệt, nhập có mặt nạ hoặc nhóm nút radio
  • Ngay cả trong các framework như React, bạn vẫn có thể dùng trực tiếp các phần tử nhập HTML mặc định; khả năng tùy biến kiểu dáng có hạn nhưng giữ được UI hệ thống quen thuộc với người dùng
  • Mọi bộ chọn ngày đều có vấn đề về khả năng truy cập, vì vậy cấu trúc nhập liệu đơn giản và kiểm thử với người dùng thực là chìa khóa để thiết kế biểu mẫu thành công

Có thực sự cần bộ chọn ngày JavaScript không

  • Trong đa số trường hợp, bộ chọn ngày JavaScript riêng là không cần thiết
    • UI phức tạp dễ gây lỗi và khiến người dùng bỏ dở biểu mẫu
    • Có những cách nhập ngày dễ hơn cả widget lịch
  • Mục đích của hướng dẫn này là đưa ra các phương án thay thế cho giao diện thân thiện với người dùng

Nhập ngày và giờ mặc định của trình duyệt

  • Mọi trình duyệt hiện đại đều hỗ trợ các kiểu nhập mặc định date, time, datetime-local
    • date dùng để chọn ngày, time để nhập giờ và phút, datetime-local kết hợp cả hai
  • Trường nhập mặc định có thể được triển khai chỉ với một dòng mã, và trình duyệt sẽ xử lý khả năng truy cập, hiệu năng và quốc tế hóa
    • Hỗ trợ nhập bằng bàn phím, cung cấp UI lịch mặc định
    • Không hoàn hảo, nhưng ổn định hơn phần lớn thư viện JavaScript
  • Tuy vậy, vẫn còn tồn tại một số vấn đề về khả năng truy cập

Trường nhập tách biệt và phần tử chọn

  • So với một bộ chọn ngày duy nhất, tách riêng năm, tháng, ngày thành các trường nhập sẽ cải thiện khả năng sử dụng
    • Đưa ra ví dụ về component nhập ngày của GOV.UK
  • Khi tập giá trị hợp lệ bị giới hạn, nên dùng phần tử select
    • Giúp tránh lỗi nhập liệu, giảm tương tác
    • Cần lưu ý việc trình đọc màn hình có thể đọc sai khi tháng được biểu thị bằng số
  • Với các khoảng thời gian cố định như đặt chỗ du lịch (ví dụ: từng 15 phút), cách biểu đạt ngày tương đối như hôm nay, ngày mai sẽ hữu ích

Nhập có mặt nạ và kiểm tra hợp lệ

  • Trường nhập có mặt nạ là một phương án thay thế giúp định hướng định dạng ngày mà không cần lịch
    • Có thể dùng JavaScript để kiểm tra hợp lệ và định dạng ở phía client
    • Ví dụ: thông báo lỗi “Hãy nhập ngày hợp lệ của tháng 2 (1~28)”
    • Dùng API Intl để tự động định dạng ngày
  • Tuy nhiên, nếu cập nhật giá trị nhập bằng JavaScript thì chức năng undo/redo có thể bị hỏng
  • Có thể dùng CSS để kết hợp nhiều trường nhập, giúp chúng trông như một trường duy nhất về mặt thị giác

Chọn phạm vi và các tùy chọn giới hạn

  • Bộ chọn ngày theo phạm vi dùng hai lịch rất khó thao tác và bất tiện khi dùng mà không có con trỏ
    • Thay vào đó có thể đơn giản hóa bằng hai trường nhập liệu
  • Nếu chỉ cần các ngày có thể chọn sẵn, có thể thay bằng nhóm nhập radio
    • Thay UI phức tạp bằng các bước tác vụ đơn giản
    • Có thể mở rộng biểu mẫu nhiều bước thành tương tác một trang bằng JavaScript

Nhập tự do và tính năng gợi ý

  • Khi không cần ngày hoặc giờ chính xác, trường nhập văn bản cơ bản sẽ hữu ích
  • Dùng phần tử datalist để cung cấp gợi ý nhập liệu
    • Cũng hoạt động cùng với các kiểu nhập date, time

Câu hỏi thường gặp

Khi dùng framework JavaScript

  • Tất cả framework lớn đều có thể dùng phần tử HTML mặc định
    • Không cần tạo thành component tùy chỉnh
    • Có thể ràng buộc trạng thái hai chiều bằng thuộc tính value

Tùy biến kiểu dáng cho bộ chọn ngày mặc định

  • Chỉ có thể style một phần của phần tử input, phần còn lại thì không
    • Đây cũng là một lợi thế để giữ UI hệ thống quen thuộc cho người dùng
    • Thiết kế sẽ khác nhau tùy hệ điều hành, phương thức nhập và trình duyệt
    • Không cần thiết phải ép thống nhất thiết kế thêm

Cách phản hồi với các bên liên quan yêu cầu bộ chọn ngày JavaScript

  • Mục tiêu là gửi biểu mẫu thành công, còn UI phức tạp sẽ làm tăng lỗi
    • Mọi bộ chọn ngày đều tồn tại vấn đề về khả năng truy cập
    • Tổ hợp các trường nhập mặc định thân thiện với người dùng hơn
    • UI JavaScript chưa được kiểm chứng có thể vi phạm các quy định như Đạo luật Khả năng tiếp cận Châu Âu (EAA)
    • Sự đơn giản là chìa khóa của thành công

Kiểm thử và bảo đảm khả năng truy cập

  • Cần hiểu rõ các hướng dẫn về khả năng truy cập như WCAG
    • Tận dụng tiêu chuẩn web để tránh lỗi từ UI tùy chỉnh
  • Có thể phát hiện lỗi bằng các tính năng hỗ trợ truy cập trong công cụ dành cho nhà phát triển của trình duyệt
    • Không có công cụ nào hoàn hảo, và kiểm thử với người dùng thực là cách xác thực duy nhất
  • Rất không khuyến khích dùng accessibility overlay, vì có thể làm vấn đề tệ hơn

Tài liệu tham khảo về khả năng truy cập

  • Collecting dates in an accessible way — Graham Armfield
  • What makes an accessible date picker? — Russ Weakley
  • Maybe You Don’t Need a Date Picker — Adrian Roselli
  • Date Picker Dialog Example — ARIA Authoring Practices Guide
  • Designing The Perfect Date And Time Picker — Vitaly Friedman

Câu trả lời cho yêu cầu đề xuất bộ chọn ngày JavaScript

  • Không có giải pháp phổ quát, mọi bộ chọn ngày đều có giới hạn
  • Hướng dẫn này nhằm giúp bạn tự đánh giá yêu cầu của mình
  • Khuyến nghị đạt mục tiêu bằng cách đơn giản nhất có thể
  • Có thể bạn không thực sự cần bộ chọn ngày

Kết luận

  • Kiểm thử với người dùng thực và thu thập phản hồi là điều bắt buộc
  • Hướng dẫn này vẫn đang tiếp tục được hoàn thiện và luôn hoan nghênh phản hồi

1 bình luận

 
GN⁺ 2025-11-13
Ý kiến trên Hacker News
  • Vài năm trước tôi từng làm một ứng dụng di động cho bệnh nhân của một bệnh viện địa phương. Trong số người dùng có rất nhiều người cao tuổi, và đã có hàng loạt phàn nàn rằng bộ chọn ngày mặc định của OS quá bất tiện
    Thực sự đã có những câu như “không thể đặt năm sinh”, “để tới ngày sinh của tôi phải bấm mũi tên về tháng trước 720 lần”
    Trên cả iOS lẫn Android khi đó, năm chỉ hiện như một tiêu đề đơn thuần nên không được nhận ra là phần tử có thể nhấp
    Tôi cảm thấy Flat Design quá thiên về thẩm mỹ đang phá hỏng UX. Tôi nghĩ vấn đề nằm ở thực tế là UI của OS được quyết định chủ yếu bởi nhà thiết kế chứ không phải các chuyên gia UX như Don Norman
    Cuối cùng, khi đổi sang dạng hộp văn bản - danh sách thả xuống - hộp văn bản (ngày-tháng-năm), các lời phàn nàn đã biến mất
    • Nghiên cứu của nhóm thiết kế Gov.uk của chính phủ Anh cũng đi đến cùng kết luận.
      Họ nói rằng ba ô văn bản riêng (ngày, tháng, năm) mang lại trải nghiệm tốt nhất.
      Cũng có hướng dẫn mẫu để triển khai
    • Tôi cũng nhớ lần đầu dùng kiểu ô nhập đó, đã chạm hơn 100 lần rồi nghĩ “cái này kỳ quá” nên đi tìm thử. Đúng là một cơn ác mộng UX
    • Nó thiếu trực quan đến mức khiến người ta phải thốt lên “năm có thể bấm được á??”
    • Tôi cũng từng loay hoay rất lâu vì không biết cách chuyển năm trong cái lịch đó
    • Mà tôi cũng thắc mắc tại sao lại nhất định dùng calendar picker cho việc nhập ngày sinh
  • Trong các trường hợp như đặt chuyến đi với lịch trình đã xác định, các biểu đạt ngày tương đối như “hôm nay”, “ngày mai” có thể tiện
    Nhưng khi đặt chuyến bay gần nửa đêm thì lại không rõ “hôm nay” là theo múi giờ của tôi, của máy chủ hay GMT
    • Các ngày tương đối như “hôm nay”, “ngày mai” nghe thì có vẻ hay nhưng phần triển khai là địa ngục.
      Có quá nhiều ngoại lệ như múi giờ, giờ mùa hè, cuối tháng (31 tháng 1 → tháng sau?), ngay sau nửa đêm.
      Trước khi thêm kiểu tính năng này thật sự phải cực kỳ thận trọng
    • Giao thông công cộng ở Montreal trước đây từng dùng đồng hồ 28 giờ. Xe buýt sau nửa đêm được hiển thị kiểu 27:30 nên rất khó hiểu
    • Tôi ghét việc máy tính định nghĩa “hôm nay” dựa trên mốc nửa đêm.
      Khi làm việc qua 12 giờ đêm, cách diễn đạt “ngày mai” không còn khớp với cảm nhận thực tế.
      Trên thực tế ý tôi là “sau sáng nay”, nhưng hệ thống lại hiểu là ngày hôm sau
    • Nhưng dù là “hôm nay” hay “12 tháng 11”, nếu múi giờ khác nhau thì vấn đề tương tự vẫn xảy ra
  • Với hơn 20 năm kinh nghiệm xử lý datepicker, tôi thấy cách tốt nhất là cứ dùng input type="text" và cho gợi ý định dạng
    Như vậy sẽ không phải vật lộn với trình duyệt, khả năng truy cập hay vấn đề locale
    Component tự làm đúng là cánh cổng dẫn xuống địa ngục. Chỉ vì muốn trông đẹp mà rơi vào 10 cái hang thỏ
    • Với ngày đã biết sẵn như sinh nhật thì ổn, nhưng khi tìm kiểu “một ngày thứ Sáu đầu tháng 4” như lúc tìm chuyến bay thì cần lịch.
      Vì khi đó phải khám phá ngày theo trực quan
    • Dù đưa gợi ý định dạng nào thì “3-9-1980” cũng không thể tin cậy được là người dùng muốn nói 9 tháng 3 hay 3 tháng 9
    • Đây là lời khuyên tệ. ISO 8601 ổn với các mốc trong quá khứ nhưng không phù hợp với đặt lịch tương lai hay lịch trình xuyên biên giới.
      Vấn đề ngày tháng thực sự rất phức tạp nên cần cách tiếp cận theo từng trường hợp sử dụng
    • Dù sao tôi vẫn nghĩ nó tốt hơn nhiều so với loại lịch trên di động không cho chọn năm
  • Nói về quốc tế hóa mà chỉ hỗ trợ định dạng ngày kiểu phương Tây thì thật buồn cười
    Nếu làm hệ thống bệnh viện ở Nepal thì phải hỗ trợ cả lịch Nepal lẫn lịch Gregory thông thường. Lịch Nepal rất phức tạp
    Ethiopia dùng lịch 13 tháng, trong đó tháng cuối chỉ có 5~6 ngày
    Nếu ai biết tài liệu tham khảo tốt về date picker quốc tế hóa thì tôi rất muốn xem
  • Ngữ cảnh của việc nhập ngày phải quyết định nên dùng loại picker nào
    Ví dụ, đặt bàn ăn tối thì lịch hữu ích để xem cuối tuần nào còn chỗ, nhưng nhập ngày sinh thì gõ số nhanh sẽ hiệu quả hơn
  • Khi luồng nhập số là quan trọng, như lúc nhập thông tin thẻ tín dụng,
    quy trình kiểu chọn tên tháng → dropdown → chọn năm sẽ phá vỡ nhịp điệu
    Cứ để người dùng nhập số đơn thuần sẽ tự nhiên hơn nhiều. Trên di động lại còn bất tiện hơn vì bàn phím cứ mở rồi đóng liên tục
  • Thấy một date picker cho phép nhập trực tiếp bằng bàn phím nên tôi thấy khá mới mẻ
    Việc ép dùng custom picker thay vì UI mặc định thật kỳ lạ.
    Đặc biệt, việc bắt chước bộ chọn thời gian dạng bánh xe xoay kiểu iOS trên web, nhất là trên Android, là tệ nhất
  • Là người Đan Mạch, tôi thấy cái tên “Pikaday” khá buồn cười. “pik” trong tiếng Đan Mạch là tiếng lóng chỉ dương vật
    • Thậm chí còn có câu đùa kiểu “thế Pokémon có nổi tiếng ở Đan Mạch không?”
  • Chỉ có picker cho Date, Time, DateTime thì vẫn chưa đủ
    Còn cần cả bộ chọn theo tháng, theo tuần, và bộ chọn khoảng thời gian tùy chỉnh nữa. Các phần tử form native quá hạn chế
    • Tôi tự hỏi ngoài việc Firefox hỗ trợ kém thì <input type="week"> hay <input type="month"> còn thiếu gì không
    • Tôi ước gì có một AI time picker mượn sức mạnh của thần thời gian Chronos trong thần thoại Hy Lạp
  • Nhân tiện, bối cảnh của cuộc thảo luận này nằm trong bài viết về Pikaday
    • Tôi cũng nhớ là trước đây từng dùng một thư viện datepicker tên Pikaday