Build validation using VanillaJS for Form Submit
Xây dựng bắt lỗi form bằng VanillaJS để gửi biểu mẫu
Chuẩn bị:
- VSCode
- Kiến thức HTML/CSS/JS
Để bắt lỗi form trước khi gửi tới server xử lý ta làm như sau:
Cấu trúc source:
- Validation.js: xây dựng các hàm bắt lỗi trong đối tượng Validation
- Main.js: xử lý dữ liệu được lấy từ form để submit
Giao diện được xây dựng:
Form:
Thông báo:
file index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Java Doc Fast</title>
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body>
<form action="success.html" method="GET">
<table>
<tr>
<th>Tài khoản:</th>
<td><input type="text" name="username" id="username"></td>
<td><span id="errorUsername"></span></td>
</tr>
<tr>
<th>Họ và tên:</th>
<td><input type="text" name="fullName" id="fullName"></td>
<td><span id="errorFullName"></span></td>
</tr>
<tr>
<th>Email:</th>
<td><input type="text" name="email" id="email"></td>
<td><span id="errorEmail"></span></td>
</tr>
<tr>
<th>Mật khẩu:</th>
<td><input type="password" name="password" id="password" autocomplete></td>
<td><span id="errorPassword"></span></td>
</tr>
<tr>
<th>Xác Nhận Mật khẩu:</th>
<td><input type="password" name="retryPassword" id="retryPassword" autocomplete></td>
<td><span id="errorRetryPassword"></span></td>
</tr>
<tr>
<th>Ngày bắt đầu làm:</th>
<td><input type="date" name="startDate" id="startDate"></td>
<td><span id="errorStartDate"></span></td>
</tr>
<tr>
<th>Lương cơ bản:</th>
<td><input type="text" name="salary" id="salary"></td>
<td><span id="errorSalary"></span></td>
</tr>
<tr>
<th>Chức vụ:</th>
<td>
<select name="position" id="position">
<option value="">--- Chọn ---</option>
<option value="0">Giám đốc</option>
<option value="1">Trưởng phòng</option>
<option value="2">Nhân viên</option>
</select>
</td>
<td><span id="errorPosition"></span></td>
</tr>
<tr>
<th>Sở thích:</th>
<td>
<input type="checkbox" name="hobbies" value="Coder">Coder
<input type="checkbox" name="hobbies" value="Đọc sách">Đọc sách
<input type="checkbox" name="hobbies" value="Thể thao">Thể thao
</td>
<td><span id="errorHobbies"></span></td>
</tr>
<tr>
<th>Giờ làm:</th>
<td><input type="text" name="workTime" id="workTime"></td>
<td><span id="errorWorkTime"></span></td>
</tr>
<tr>
<th></th>
<td><button type="submit" id="btnSubmit">Xác nhận</button></td>
</tr>
</table>
</form>
<script src="assets/js/Common.js"></script>
<script src="assets/js/Validation.js"></script>
<script src="assets/js/Main.js"></script>
</body>
</html>
file success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Java Doc Fast</title>
</head>
<body>
<h1>Thành công!</h1>
</body>
</html>
file styles.css
th {
text-align: left;
}
Giao diện xảy ra lỗi được xây dựng:
file Common.js
// Tạo hàm getElement cho ngắn gọn
function getElement(id) {
return document.getElementById(id);
}
// Tạo hàm querySelectorAll cho ngắn gọn
function querySelectorAll(selector) {
return document.querySelectorAll(selector);
}
file Validation.js
function Validation() {
// Hàm kiểm tra rỗng
this.isBlank = function (input, id, msg) {
if (!Object.is('', input.trim())) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
}
// Hàm check độ dài từ min - max
this.isLength = function (input, id, msg, min, max) {
if (input.length >= min && input.length <= max) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra Tiếng Việt
this.isVietnamese = function (input, id, msg) {
var pattern =
'^[a-zA-Z_ÀÁÂÃÈÉÊẾÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶ' +
'ẸẺẼỀỀỂưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợ' +
'ụủứừỬỮỰỲỴÝỶỸửữựỳỵỷỹ\\s]+$';
if (input.match(pattern)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra Email
this.isEmail = function(input, id, msg) {
var pattern = '^\\w{1,}@\\w{2,}(\\.\\w{2,}){1,2}$';
if (input.match(pattern)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra mật khẩu: (chứa ít nhất 1 ký tự số, 1 ký tự in hoa, 1 ký tự đặc biệt)
this.isPasssword = function (input, id, msg) {
var pattern = '^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@$!%*#?&])[0-9a-zA-Z@$!%*#?&\\s]+$';
if (input.match(pattern)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra xác nhận mật khẩu
this.isRetryPasssword = function (input, retryInput, id, msg) {
if (Object.is(input, retryInput)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra MM/dd/yyyy
// Tips: dd/MM/yyyy: ^((0?[1-9]|[12][0-9]|3[01])[/](0?[1-9]|1[012])[/](19|20)?[0-9]{2})*$
// Tips: yyyy/MM/dd: ^((19|20)?[0-9]{2}[/](0?[1-9]|[12][0-9]|3[01])[/](0?[1-9]|1[012]))*$
// Tips: thay / -> - để có yyyy/MM/dd -> yyyy-MM-dd
this.isDateMMddyyyy = function (input, id, msg) {
var pattern = '^((0?[1-9]|1[012])[/](0?[1-9]|[12][0-9]|3[01])[/](19|20)?[0-9]{2})*$';
if (input.match(pattern)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra number
this.isNumber = function(input, id, msg) {
var pattern = '^[+-]?([0-9]*[\\.])?[0-9]+$';
if (input.match(pattern)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra giá trị
this.isValue = function(input, id, msg, min, max) {
if (input >= min && input <= max) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra regex
this.isRegex = function(input, id, msg, regex) {
if (input.match(regex)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
};
// Hàm kiểm tra select có điều kiện
this.isSelected = function(input, id, msg, condition) {
if(!Object.is(condition, input)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
}
// Hàm kiểm tra checkbox
this.isChecked = function(input, id, msg) {
if(!Object.is(0, input.length)) {
getElement(id).innerHTML = '';
return true;
}
getElement(id).innerHTML = msg;
getElement(id).style.color = 'red';
return false;
}
}
file Main.js
// Tạo đối tượng Validation để sử dụng
var validation = new Validation();
// Hàm validate các dữ liệu trong form
function validateForm() {
// Khai báo các biến và get value từ form
var username = getElement('username').value;
var fullName = getElement('fullName').value;
var email = getElement('email').value;
var password = getElement('password').value;
var retryPassword = getElement('retryPassword').value;
var startDate = getElement('startDate').value;
var salary = getElement('salary').value;
var position = getElement('position').value;
var workTime = getElement('workTime').value;
var hobbies = querySelectorAll('input[name="hobbies"]:checked');
// Tạo biến isValid để kiểm tra lỗi
var isValid = true;
// Kiểm tra username: Tài khoản tối đa 4 - 6 ký số, không để trống
isValid &=
validation.isBlank(username, 'errorUsername', '(*) Tài khoản không để trống') &&
validation.isLength(username, 'errorUsername', '(*) Tài khoản tối đa 4 - 6 ký số', 4, 6);
// Kiểm tra fullName: Họ tên phải là chữ, không để trống
isValid &=
validation.isBlank(fullName, 'errorFullName', '(*) Họ tên không để trống') &&
validation.isLength(fullName, 'errorFullName', '(*) Họ tên tối đa 4 - 20 ký tự', 4, 20) &&
validation.isVietnamese(fullName, 'errorFullName', '(*) Họ tên phải là chữ');
// Kiểm tra email: Email phải đúng định dạng, không để trống
isValid &=
validation.isBlank(email, 'errorEmail', '(*) Email không để trống') &&
validation.isEmail(email, 'errorEmail', '(*) Email không đúng định dạng');
// Kiểm tra password: Mật khẩu từ 6-10 ký tự (chứa ít nhất 1 ký tự số, 1 ký tự in hoa, 1 ký tự đặc biệt), không để trống
isValid &=
validation.isBlank(password, 'errorPassword', '(*) Mật khẩu không để trống') &&
validation.isLength(password, 'errorPassword', '(*) Mật khẩu tối đa 6 - 10 ký tự', 6, 10) &&
validation.isPasssword(password, 'errorPassword', '(*) Mật khẩu chứa ít nhất 1 ký tự số, 1 ký tự in hoa, 1 ký tự đặc biệt');
// Kiểm tra retryPassword: Mật khẩu xác nhận phải khớp
isValid &=
validation.isRetryPasssword(password, retryPassword, 'errorRetryPassword', '(*) Mật khẩu xác nhận không đúng');
// Kiểm tra startDate: Ngày làm không để trống, định dạng mm/dd/yyyy
isValid &=
validation.isBlank(startDate, 'errorStartDate', '(*) Ngày làm không để trống');
// Kiểm tra salary: Lương cơ bản 1 000 000 - 20 000 000, không để trống, phải là số
isValid &=
validation.isBlank(salary, 'errorSalary', '(*) Lương cơ bản không để trống') &&
validation.isNumber(salary, 'errorSalary', '(*) Lương cơ bản phải là số') &&
validation.isValue(salary, 'errorSalary', '(*) Lương cơ bản 1000000 - 20000000', 1_000_000, 20_000_000);
// Kiểm tra position: Chức vụ phải chọn chức vụ hợp lệ
isValid &=
// validation.isBlank(position, 'errorPosition', '(*) Chức vụ phải được chọn');
validation.isSelected(position, 'errorPosition', '(*) Chức vụ phải được chọn', '');
// Kiểm tra hobbies: Sở thích phải được chọn
isValid &=
validation.isChecked(hobbies, 'errorHobbies', '(*) Sở thích phải được chọn');
// Kiểm tra workTime: Số giờ làm trong tháng 80 - 200 giờ, không để trống
isValid &=
validation.isBlank(workTime, 'errorWorkTime', '(*) Số giờ làm không để trống') &&
// validation.isNumber(workTime, 'errorWorkTime', '(*) Số giờ làm phải là số') &&
validation.isRegex(workTime, 'errorWorkTime', '(*) Số giờ làm phải là số', '^[+-]?([0-9]*[\\.])?[0-9]+$') &&
validation.isValue(workTime, 'errorWorkTime', '(*) Số giờ làm 80 - 200', 80, 200);
return isValid;
}
// Click submit
getElement('btnSubmit').addEventListener('click', function(event) {
if(!validateForm()) {
event.preventDefault();
}
});
Muốn lỗi hiển thị như giao diện trên ta cần thêm vào HTML các đoạn code sau:
<span id="errorUsername"></span>
<span id="errorFullName"></span>
<span id="errorEmail"></span>
<span id="errorPassword"></span>
<span id="errorRetryPassword"></span>
<span id="errorStartDate"></span>
<span id="errorSalary"></span>
<span id="errorPosition"></span>
<span id="errorHobbies"></span>
<span id="errorWorkTime"></span>
Full code:
Nhận xét
Đăng nhận xét