Đối với biểu mẫu nhiều bước, việc lập kế hoạch bao gồm việc sắp xếp các câu hỏi một cách hợp lý theo từng bước, nhóm các câu hỏi tương tự nhau và giảm thiểu số bước cũng như lượng thông tin cần thiết cho mỗi bước. Bất cứ điều gì làm cho từng bước trở nên tập trung và dễ quản lý đều là mục tiêu cần hướng tới.
Trong hướng dẫn này, chúng ta sẽ tạo biểu mẫu nhiều bước cho đơn xin việc. Sau đây là các thông tin chi tiết mà chúng ta sẽ yêu cầu ứng viên cung cấp ở mỗi bước:
Dựa trên các bước chúng tôi đã nêu ở trên, đây là nội dung của HTML với biểu mẫu của chúng tôi sẽ trông như thế nào. Đầu tiên, phần tử
Bước 1 là để điền thông tin cá nhân, như tên, địa chỉ email và số điện thoại của người nộp đơn:
Sau khi người nộp đơn hoàn tất bước đầu tiên, chúng tôi sẽ hướng dẫn họ đến Bước 2, tập trung vào kinh nghiệm làm việc của họ để chúng tôi có thể thu thập thông tin như công ty gần đây nhất, chức danh công việc và số năm kinh nghiệm. Chúng tôi sẽ thêm một
Bước 3 là về việc ứng viên liệt kê các kỹ năng và bằng cấp của họ cho công việc mà họ đang ứng tuyển:
Và cuối cùng, chúng tôi sẽ cho phép người nộp đơn xem lại thông tin của họ trước khi nộp:
Lưu ý: Chúng tôi đã thêm thuộc tính
Nếu bạn đang theo dõi, chúng ta có thể đưa các kiểu của Simple vào tài liệu
Và từ đó, hãy tiếp tục và tạo tệp
Bây giờ, phần duy nhất của biểu mẫu của chúng ta có thể nhìn thấy là bước đầu tiên. Để hoàn thành biểu mẫu, người dùng cần có thể điều hướng đến các bước khác. Chúng ta sẽ sử dụng một số nút để thực hiện việc này. Bước đầu tiên sẽ có nút Tiếp theo. Bước thứ hai và thứ ba sẽ có cả nút Trước và nút Tiếp theo, và bước thứ tư sẽ có nút Trước và nút Gửi.
Lưu ý: Chúng tôi đã thêm thuộc tính
Trước khi đi vào triển khai hàm
Sau đó, chúng ta sẽ cần một mảng để lưu trữ các thông báo lỗi của mình.
Ngoài ra, chúng ta sẽ cần một phần tử trong DOM nơi chúng ta có thể chèn các thông báo lỗi đó sau khi chúng được tạo. Phần tử này phải được đặt trong HTML ngay bên dưới thẻ đóng
Thêm
Và cuối cùng, chúng ta cần một biến để theo dõi bước hiện tại.
let currentStep = 1;
Bây giờ chúng ta đã có tất cả các biến tại chỗ, đây là phần triển khai hàm
Ngay khi nhấn nút Next, mã của chúng tôi sẽ kiểm tra xem người dùng hiện đang ở bước nào và dựa trên thông tin này, mã sẽ xác thực dữ liệu cho bước cụ thể đó bằng cách gọi hàm
Bất cứ khi nào hàm
Sau đây là cách hàm
Đây là cách hàm
Hàm
Hàm
Hàm
Bất cứ khi nào hàm
Tiếp theo, chúng ta cần truy vấn phần của stepper sẽ biểu diễn bước hiện tại. Đây là thẻ span có tên lớp là
Bây giờ, chúng ta cần cập nhật giá trị stepper bất cứ khi nào các nút trước hoặc nút tiếp theo được nhấp vào. Để thực hiện việc này, chúng ta cần cập nhật hàm
Dòng này được thêm vào hàm
Sử dụng
Trước khi thêm trình lắng nghe sự kiện
Bây giờ chúng ta có thể thêm trình lắng nghe sự kiện
Tiếp theo, chúng ta cần thêm một số mã để giúp chúng ta truy xuất dữ liệu người dùng sau khi nội dung DOM được tải.
Cuối cùng, một cách thực hành tốt là xóa dữ liệu khỏi
Thêm giá trị bước hiện tại vào
Nếu người dùng vô tình đóng trình duyệt, họ sẽ có thể quay lại nơi họ đã dừng lại. Điều này có nghĩa là giá trị bước hiện tại cũng phải được lưu trong
Để lưu giá trị này, hãy thêm dòng sau vào hàm
Bây giờ chúng ta có thể truy xuất giá trị bước hiện tại và đưa người dùng trở lại bất cứ nơi nào họ dừng lại bất cứ khi nào nội dung DOM tải. Thêm mã sau vào trình xử lý
Ngoài ra, đừng quên xóa giá trị bước hiện tại khỏi
Dòng trên phải được thêm vào trình xử lý gửi đi.
Để triển khai đầy đủ biểu mẫu nhiều bước này, bạn có thể truy cập mã đầy đủ trên GitHub.
Trong hướng dẫn này, chúng ta sẽ tạo biểu mẫu nhiều bước cho đơn xin việc. Sau đây là các thông tin chi tiết mà chúng ta sẽ yêu cầu ứng viên cung cấp ở mỗi bước:
- Thông tin cá nhân
Thu thập tên, email và số điện thoại của ứng viên. - Kinh nghiệm làm việc
Thu thập công ty gần đây nhất, chức danh công việc và số năm kinh nghiệm của ứng viên. - Kỹ năng & Trình độ
Ứng viên liệt kê các kỹ năng của mình và chọn bằng cấp cao nhất. - Xem xét & Nộp
Bước này sẽ không thu thập bất kỳ thông tin nào. Thay vào đó, nó cung cấp cho người nộp đơn cơ hội quay lại và xem lại thông tin đã nhập ở các bước trước của biểu mẫu trước khi gửi.
Dựa trên các bước chúng tôi đã nêu ở trên, đây là nội dung của HTML với biểu mẫu của chúng tôi sẽ trông như thế nào. Đầu tiên, phần tử
chính:
Mã:
Mã:
Bước 1: Thông tin cá nhân Họ và tên Địa chỉ email Số điện thoại
mới với các thông tin đầu vào đó:
Mã:
Bước 2: Kinh nghiệm làm việc Công ty gần đây nhất Chức danh công việc Số năm kinh nghiệm
Mã:
Bước 3: Kỹ năng và bằng cấp Kỹ năng Bằng cấp đạt được (Cao nhất) Chọn Bằng cấp Bằng Tốt nghiệp Trung học Phổ thông Bằng Cử nhân Bằng Thạc sĩ Tiến sĩ Bước 4: Xem xét & Nộp
Xem lại thông tin của bạn trước khi nộp đơn.
Nộp đơn
Mã:
Bước 4: Xem lại & Nộp
Xem lại thông tin của bạn trước khi nộp đơn.
Nộp đơn
hidden
vào mọi phần tử fieldset
trừ phần tử đầu tiên. Điều này đảm bảo rằng người dùng chỉ nhìn thấy bước đầu tiên. Sau khi hoàn tất bước đầu tiên, họ có thể tiếp tục điền kinh nghiệm làm việc của mình vào bước thứ hai bằng cách nhấp vào nút điều hướng. Chúng tôi sẽ thêm nút này sau.Thêm Kiểu
Để tập trung, chúng tôi sẽ không nhấn mạnh vào các kiểu trong hướng dẫn này. Những gì chúng ta sẽ làm để giữ mọi thứ đơn giản là tận dụng khung kiểu Simple.css để có được biểu mẫu ở dạng tốt cho phần còn lại của hướng dẫn.Nếu bạn đang theo dõi, chúng ta có thể đưa các kiểu của Simple vào tài liệu
:
Mã:
style.css
với các kiểu sau mà tôi đã gấp lại.
Mã:
View CSS body { min-height: 100vh; display: flex; align-items: center; justify-content: center; } main { padding: 0 30px; } h1 { font-size: 1.8rem; text-align: center; } .stepper { display: flex; justify-content: flex-end; padding-right: 10px; } form { box-shadow: 0px 0px 6px 2px rgba(0, 0, 0, 0.2); padding: 12px; } input, textarea, select { outline: none; } input:valid, textarea:valid, select:valid, input:focus:valid, textarea:focus:valid, select:focus:valid { border-color: green; } input:focus:invalid, textarea:focus:invalid, select:focus:invalid { border: 1px solid red; }
Điều hướng và xác thực biểu mẫu
Một cách dễ dàng để phá hỏng trải nghiệm người dùng đối với biểu mẫu nhiều bước là đợi cho đến khi người dùng đến bước cuối cùng trong biểu mẫu trước khi cho họ biết bất kỳ lỗi nào họ đã mắc phải trong quá trình thực hiện. Mỗi bước của biểu mẫu phải được xác thực lỗi trước khi chuyển sang bước tiếp theo và các thông báo lỗi mô tả phải được hiển thị để người dùng hiểu được lỗi sai và cách khắc phục.Bây giờ, phần duy nhất của biểu mẫu của chúng ta có thể nhìn thấy là bước đầu tiên. Để hoàn thành biểu mẫu, người dùng cần có thể điều hướng đến các bước khác. Chúng ta sẽ sử dụng một số nút để thực hiện việc này. Bước đầu tiên sẽ có nút Tiếp theo. Bước thứ hai và thứ ba sẽ có cả nút Trước và nút Tiếp theo, và bước thứ tư sẽ có nút Trước và nút Gửi.
Mã:
Next Previous Next Previous Next Previous Nộp đơn
onclick
vào các nút Trước và Tiếp theo để liên kết chúng với các hàm JavaScript tương ứng: previousStep()
và nextStep()
.Nút "Tiếp theo"
HàmnextStep()
được liên kết với nút Tiếp theo. Bất cứ khi nào người dùng nhấp vào nút Tiếp theo, hàm nextStep()
trước tiên sẽ kiểm tra để đảm bảo rằng tất cả các trường cho bất kỳ bước nào mà người dùng đang thực hiện đã được điền chính xác trước khi chuyển sang bước tiếp theo. Nếu các trường không được điền chính xác, nó sẽ hiển thị một số thông báo lỗi, cho người dùng biết rằng họ đã làm sai điều gì đó và thông báo cho họ biết phải làm gì để khắc phục lỗi.Trước khi đi vào triển khai hàm
nextStep
, có một số biến nhất định mà chúng ta cần xác định vì chúng sẽ cần thiết trong hàm. Đầu tiên, chúng ta cần các trường nhập từ DOM để có thể chạy kiểm tra chúng nhằm đảm bảo chúng hợp lệ.
Mã:
// Các trường ở Bước 1const name = document.getElementById("name");const email = document.getElementById("email");const phone = document.getElementById("phone");// Các trường ở Bước 2const company = document.getElementById("company");const jobTitle = document.getElementById("jobTitle");const yearsExperience = document.getElementById("yearsExperience");// Các trường Bước 3const skills = document.getElementById("skills");const highestDegree = document.getElementById("highestDegree");
Mã:
let errorMsgs = [];
fieldset
cuối cùng:
Mã:
div
ở trên vào mã JavaScript bằng cách sử dụng dòng sau:
Mã:
const errorMessagesDiv = document.getElementById("errorMessages");
let currentStep = 1;
Bây giờ chúng ta đã có tất cả các biến tại chỗ, đây là phần triển khai hàm
nextstep()
:
Mã:
function nextStep() { errorMsgs = []; errorMessagesDiv.innerText = ""; switch (currentStep) { case 1: addValidationErrors(name, email, phone); validateStep(errorMsgs); break; case 2: addValidationErrors(company, jobTitle, yearsExperience); validateStep(errorMsgs); break; case 3: addValidationErrors(skills, highestDegree); validateStep(errorMsgs); break; }}
addValidationErrors()
. Nếu có lỗi, chúng tôi sẽ hiển thị lỗi. Sau đó, biểu mẫu sẽ gọi hàm validateStep()
để xác minh rằng không có lỗi nào trước khi chuyển sang bước tiếp theo. Nếu có lỗi, người dùng sẽ không thể chuyển sang bước tiếp theo.Bất cứ khi nào hàm
nextStep()
chạy, các thông báo lỗi sẽ được xóa trước để tránh thêm lỗi từ một bước khác vào lỗi hiện có hoặc thêm lại các thông báo lỗi hiện có khi hàm addValidationErrors
chạy. Hàm addValidationErrors
được gọi cho từng bước bằng cách sử dụng các trường cho bước đó làm đối số.Sau đây là cách hàm
addValidationErrors
được triển khai:
Mã:
function addValidationErrors(fieldOne, fieldTwo, fieldThree = undefined) { if (!fieldOne.checkValidity()) { const label = document.querySelector(`label[for="${fieldOne.id}"]`); errorMsgs.push(`Vui lòng nhập ${label.textContent} hợp lệ`); } if (!fieldTwo.checkValidity()) { const label = document.querySelector(`label[for="${fieldTwo.id}"]`); errorMsgs.push(`Vui lòng nhập ${label.textContent} hợp lệ`); } if (fieldThree && !fieldThree.checkValidity()) { const label = document.querySelector(`label[for="${fieldThree.id}"]`); errorMsgs.push(`Vui lòng nhập ${label.textContent} hợp lệ`); } if (errorMsgs.length > 0) { errorMessagesDiv.innerText = errorMsgs.join("\n"); }}
validateStep()
được định nghĩa:
Mã:
function validateStep(errorMsgs) { if (errorMsgs.length === 0) { showStep(currentStep + 1); }}
validateStep()
kiểm tra lỗi. Nếu không có lỗi nào, nó sẽ tiến hành bước tiếp theo với sự trợ giúp của hàm showStep()
.
Mã:
function showStep(step) { steps.forEach((el, index) => { el.hidden = index + 1 !== step; }); currentStep = step;}
showStep()
yêu cầu bốn tập trường trong DOM. Thêm dòng sau vào đầu mã JavaScript để làm cho các fieldset khả dụng:
Mã:
const steps = document.querySelectorAll(".step");
showStep()
thực hiện duyệt qua tất cả các fieldset
trong biểu mẫu của chúng ta và ẩn bất kỳ fieldset
nào không bằng với fieldset mà chúng ta đang điều hướng đến. Sau đó, nó cập nhật biến currentStep
để bằng với bước mà chúng ta đang điều hướng đến.Nút "Trước"
HàmpreviousStep()
được liên kết với nút Trước. Bất cứ khi nào nút trước đó được nhấp, tương tự như hàm nextStep
, các thông báo lỗi cũng được xóa khỏi trang và việc điều hướng cũng được xử lý bởi hàm showStep
.
Mã:
function previousStep() { errorMessagesDiv.innerText = ""; showStep(currentStep - 1);}
showStep()
được gọi với “currentStep - 1
” làm đối số (như trong trường hợp này), chúng ta quay lại bước trước đó, trong khi chuyển sang bước tiếp theo xảy ra bằng cách gọi hàm showStep()
với “currentStep + 1
” làm đối số (như trong trường hợp hàm validateStep()
).Cải thiện trải nghiệm người dùng bằng tín hiệu trực quan
Một cách khác để cải thiện trải nghiệm người dùng cho biểu mẫu nhiều bước là tích hợp các tín hiệu trực quan, những thứ sẽ cung cấp cho người dùng phản hồi về quy trình họ đang thực hiện. Những thứ này có thể bao gồm một chỉ báo tiến trình hoặc một bước để giúp người dùng biết chính xác họ đang ở bước nào.Tích hợp một bước
Để tích hợp một bước vào biểu mẫu của chúng ta (giống như cái này từ Material Design), điều đầu tiên chúng ta cần làm là thêm nó vào HTML ngay bên dưới thẻ mở
.
Mã:
1/4
currentStep
.
Mã:
const currentStepDiv = document.querySelector(".currentStep");
showStep()
bằng cách thêm dòng sau vào hàm:
Mã:
currentStepDiv.innerText = currentStep;
showStep()
vì hàm showStep()
chịu trách nhiệm điều hướng giữa các bước và cập nhật biến currentStep
. Vì vậy, bất cứ khi nào biến currentStep
được cập nhật, currentStepDiv cũng phải được cập nhật để phản ánh thay đổi đó.Lưu trữ và truy xuất dữ liệu người dùng
Một cách chính để cải thiện trải nghiệm người dùng của biểu mẫu là lưu trữ dữ liệu người dùng trong trình duyệt. Biểu mẫu nhiều bước thường dài và yêu cầu người dùng nhập nhiều thông tin về bản thân. Hãy tưởng tượng một người dùng điền 95% biểu mẫu, sau đó vô tình nhấn nút F5 trên bàn phím và mất toàn bộ tiến trình. Đó sẽ là một trải nghiệm thực sự tệ đối với người dùng.Sử dụng
localStorage
, chúng ta có thể lưu trữ thông tin người dùng ngay khi nhập vào và truy xuất thông tin đó ngay khi nội dung DOM được tải, do đó người dùng luôn có thể tiếp tục điền vào biểu mẫu của họ từ bất kỳ nơi nào họ dừng lại. Để thêm tính năng này vào biểu mẫu của mình, chúng ta có thể bắt đầu bằng cách lưu thông tin của người dùng ngay khi nhập vào. Có thể thực hiện việc này bằng cách sử dụng sự kiện input
.Trước khi thêm trình lắng nghe sự kiện
input
, hãy lấy phần tử biểu mẫu từ DOM:
Mã:
const form = document.getElementById("jobApplicationForm");
input
:
Mã:
// Lưu dữ liệu trên mỗi sự kiện đầu vàoform.addEventListener("input", () => { const formData = { name: document.getElementById("name").value, email: document.getElementById("email").value, phone: document.getElementById("phone").value, company: document.getElementById("company").value, jobTitle: document.getElementById("jobTitle").value, yearsExperience: document.getElementById("yearsExperience").value, skills: document.getElementById("skills").value, highestDegree: document.getElementById("highestDegree").value, }; localStorage.setItem("formData", JSON.stringify(formData));});
Mã:
window.addEventListener("DOMContentLoaded", () => { const savedData = JSON.parse(localStorage.getItem("formData")); if (savedData) { document.getElementById("name").value = savedData.name || ""; document.getElementById("email").value = savedData.email || ""; document.getElementById("điện thoại").giá trị = savedData.phone || ""; document.getElementById("công ty").giá trị = savedData.company || ""; document.getElementById("tiêu đề công việc").giá trị = savedData.jobTitle || ""; document.getElementById("nămKinh nghiệm").giá trị = savedData.yearKinh nghiệm || ""; document.getElementById("kỹ năng").giá trị = savedData.kỹ năng || ""; document.getElementById("bậc cao nhất").giá trị = savedData.bậc cao nhất || ""; }});
localStorage
ngay khi không còn cần thiết nữa:
Mã:
// Xóa dữ liệu khi gửi biểu mẫuform.addEventListener('submit', () => { // Xóa localStorage sau khi biểu mẫu được gửi localStorage.removeItem('formData');});
Thêm giá trị bước hiện tại vào localStorage
Nếu người dùng vô tình đóng trình duyệt, họ sẽ có thể quay lại nơi họ đã dừng lại. Điều này có nghĩa là giá trị bước hiện tại cũng phải được lưu trong localStorage
.Để lưu giá trị này, hãy thêm dòng sau vào hàm
showStep()
:
Mã:
localStorage.setItem("storedStep", currentStep);
DOMContentLoaded
để thực hiện việc này:
Mã:
const storedStep = localStorage.getItem("storedStep");if (storedStep) { const storedStepInt = parseInt(storedStep); steps.forEach((el, index) => { el.hidden = index + 1 !== storedStepInt; }); currentStep = storedStepInt; currentStepDiv.innerText = currentStep; }
localStorage
khi biểu mẫu được gửi đi.
Mã:
localStorage.removeItem("storedStep");
Kết thúc
Việc tạo biểu mẫu nhiều bước có thể giúp cải thiện trải nghiệm của người dùng đối với mục nhập dữ liệu phức tạp. Bằng cách lập kế hoạch cẩn thận các bước, triển khai xác thực biểu mẫu ở mỗi bước và lưu trữ tạm thời dữ liệu người dùng trong trình duyệt, bạn giúp người dùng dễ dàng hoàn thành các biểu mẫu dài hơn.Để triển khai đầy đủ biểu mẫu nhiều bước này, bạn có thể truy cập mã đầy đủ trên GitHub.