-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
333 lines (285 loc) · 10.4 KB
/
app.js
File metadata and controls
333 lines (285 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
const form = document.getElementById("form");
const username = document.getElementById("username");
const email = document.getElementById("email");
const password = document.getElementById("password");
const confirmPassword = document.getElementById('confirm-password');
const showPassword = document.getElementById("show-password");
const failureIcon = document.getElementsByClassName('failure-icon');
const successIcon = document.getElementsByClassName('success-icon');
const toggleEye = document.querySelector('.toggle-icon')
let isRequired = value => value === '' ? false : true;
let isBetween = (length, min, max) => length < min || length > max ? false : true;
// function that show the error message
const setError = (input, message) => {
// get the form-field element
const inputControl = input.parentElement;
console.log(inputControl);
// add the error class
inputControl.classList.add('error');
inputControl.classList.remove('success');
// console.log(inputControl);
// show the error message
const errorDisplay = inputControl.querySelector('.error')
errorDisplay.innerText = message;
}
// function that show the success message
const setSuccess = input => {
const inputControl = input.parentElement;
console.log(inputControl);
inputControl.classList.remove('error');
inputControl.classList.add('success');
const errorDisplay = inputControl.querySelector('.error');
errorDisplay.innerText = '';
}
// Function to set opacity for success and failure icons
const setIconOpacity = (index, successOpacity, failureOpacity) => {
if (successIcon[index]) {
successIcon[index].style.opacity = successOpacity;
}
if (failureIcon[index]) {
failureIcon[index].style.opacity = failureOpacity;
}
}
// To check the email is valid
const isValidEmail = email => {
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
// To check if a password is strong
const isPasswordSecure = password => {
const re = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})");
return re.test(password);
};
// 1. check if username match the given regex
const checkUsername = () => {
let valid = false;
const min = 3,
max = 25;
const usernameValue = username.value.trim();
if (!isRequired(usernameValue)) {
setError(username, 'Username cannot be blank.')
setIconOpacity(0, 0, 1);
} else if (!isBetween(usernameValue.length, min, max)) {
setError(username, `Username must be between ${min} and ${max} characters.`);
setIconOpacity(0, 0, 1);
} else {
setSuccess(username);
setIconOpacity(0, 1, 0);
valid = true;
}
return valid;
}
// 2. Check emial validity
const checkEmail = () => {
let valid = false;
const emailValue = email.value.trim();
if (!isRequired(emailValue)) {
setError(email, 'Email cannot be blank.')
setIconOpacity(1, 0, 1);
} else if (!isValidEmail(emailValue)) {
setError(email, 'Please enter a valid email');
setIconOpacity(1, 0, 1);
} else {
setSuccess(email);
setIconOpacity(1, 1, 0);
valid = true;
}
return valid;
}
// 3. check if password is secure enough or not using regEx()
const checkPassword = () => {
let valid = false;
const passwordValue = password.value.trim();
if (!isRequired(passwordValue)) {
setError(password, 'Password cannot be blank.')
setIconOpacity(2, 0, 1);
} else if (!isPasswordSecure(passwordValue)) {
if (passwordValue.length < 8) {
setError(password, 'Password must have at least 8 characters');
} else if (!passwordValue.match(/[a-z]/)) {
setError(password, 'Password must include at least 1 lowercase character');
} else if (!passwordValue.match(/[A-Z]/)) {
setError(password, 'Password must include at least 1 uppercase character');
} else if (!passwordValue.match(/[0-9]/)) {
setError(password, 'Password must include at least 1 number');
} else if (!passwordValue.match(/[!@#$%^&*]/)) {
setError(password, 'Password must include at least 1 special character from (!@#$%^&*)');
} else {
// Password meets all criteria
setError(password);
}
setIconOpacity(2, 0, 1);
} else {
setSuccess(password);
setIconOpacity(2, 1, 0);
valid = true;
console.log(`pass: ${passwordValue}`);
}
return valid;
}
// Show password confirmation
toggleEye.addEventListener('click', () => {
const icon = toggleEye.querySelector('i');
if (password.type === 'password') {
password.type = 'text';
confirmPassword.type = 'text'
toggleEye.type = 'hide';
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
toggleEye.setAttribute("aria-label", "hide password");
toggleEye.setAttribute("aria-checked", "true");
} else {
password.type = 'password';
confirmPassword.type = 'password';
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
toggleEye.setAttribute("aria-label", "show password");
toggleEye.setAttribute("aria-checked", "false");
}
})
// Function to clear the error message and hide the error icon
const clearError = (element) => {
const inputControl = element.parentElement
inputControl.classList.remove('error', 'success'); // Remove error and success classes
element.nextElementSibling.textContent = '' // Clear the error message
}
// 4. check confirm password matches password
const checkConfirmPassword = () => {
let valid = false;
const confirmPasswordValue = confirmPassword.value.trim();
const passwordValue = password.value.trim();
if (confirmPasswordValue === '') {
setError(confirmPassword, 'Confirm password cannot be blank');
setIconOpacity(3, 0, 1);
clearError(confirmPassword)
} else if (confirmPasswordValue !== passwordValue) {
setError(confirmPassword, 'Confirm password does not match');
setIconOpacity(3, 0, 1);
} else {
setSuccess(confirmPassword);
setIconOpacity(3, 1, 0);
valid = true;
console.log(`confirm pass: ${confirmPasswordValue}`);
}
return valid;
}
// Function to check if all form fields are filled out
const isFormValid = () => {
// Iterate over each form field
const inputs = [username, email, password, confirmPassword];
for (let input of inputs) {
// Check if the value of the input field is empty
if (input.value.trim() === '') {
return false; // Return false if any field is empty
}
}
return true; // Return true if all fields are filled out
};
// Event listeners to trigger validation on input
password.addEventListener('input', () => checkPassword());
confirmPassword.addEventListener('input', () => checkConfirmPassword());
// Reset icons on form submission
const resetIcons = () => {
for (let i = 0; i < failureIcon.length; i++) {
failureIcon[i].style.opacity = '0';
}
for (let i = 0; i < successIcon.length; i++) {
successIcon[i].style.opacity = '0';
}
}
const formReset = () => {
// Clear the value of each form field
username.value = ''
email.value = ''
password.value = ''
confirmPassword.value = ''
// Clear error messages and reset styling
clearError(username)
clearError(email)
clearError(password)
clearError(confirmPassword)
// Reset Icons
resetIcons()
}
form.addEventListener("submit", e => {
e.preventDefault();
let isUsernameValid = checkUsername(),
isEmailValid = checkEmail(),
isPasswordValid = checkPassword(),
isConfirmPasswordValid = checkConfirmPassword();
let isFormValid = isUsernameValid &&
isEmailValid &&
isPasswordValid &&
isConfirmPasswordValid;
if (typeof isFormValid === 'function' && isFormValid()) {
// Submit the form to the server if it's valid
submitToServer();
} else {
// Handle the case where the form is not valid
const emptyFields = findEmptyFields();
if (emptyFields.length > 0) {
// Display error message for empty fields
emptyFields.forEach(field => {
const fieldName = field.id.replace('-', ' ');
console.log(`Please fill out ${fieldName}.`);
});
} else {
alert('Thank you for filling out your information! ...') }
}
// Reset the form after submission
formReset();
})
// Function to find empty fields in the form
const findEmptyFields = () => {
const emptyFields = [];
const inputs = [username, email, password, confirmPassword];
for (let input of inputs) {
if (input.value.trim() === '') {
emptyFields.push(input);
}
}
return emptyFields;
};
// Function to submit form data to the server
const submitToServer = () => {
// Construct data object to send to the server
const formData = {
username: username.value.trim(),
email: email.value.trim(),
password: password.value.trim(),
confirmPassword: confirmPassword.value.trim()
// Add more fields if needed
}
};
// Add Instant feedback feature
// using Debounce function is =>
// a debounce function makes sure that your code is only triggered once per user input
const debounce = (fn, delay = 500) => {
let timeoutId;
return (...args) => {
// cancel the previous timer
if (timeoutId) {
clearTimeout(timeoutId);
}
// setup a new timer
timeoutId = setTimeout(() => {
fn.apply(null, args)
}, delay);
};
};
form.addEventListener('input', debounce(function (e) {
switch (e.target.id) {
case 'username':
checkUsername();
break;
case 'email':
checkEmail();
break;
case 'password':
checkPassword();
break;
case 'confirmPassword':
checkConfirmPassword();
break;
}
}));