Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
94 lines (89 loc) · 3.82 KB
/
Copy pathscript.js
File metadata and controls
94 lines (89 loc) · 3.82 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
const form = document.getElementById('form');
const success = document.getElementById('success');
const fields = {
username: { el: document.getElementById('username'), msg: document.getElementById('usernameMsg'),
validate: (v) => {
if (!v) return { valid: false, msg: 'Username is required' };
if (v.length < 3) return { valid: false, msg: 'Must be at least 3 characters' };
if (v.length > 20) return { valid: false, msg: 'Must be less than 20 characters' };
if (!/^[a-zA-Z0-9_]+$/.test(v)) return { valid: false, msg: 'Only letters, numbers, underscores' };
return { valid: true, msg: 'Looks good!' };
}
},
email: { el: document.getElementById('email'), msg: document.getElementById('emailMsg'),
validate: (v) => {
if (!v) return { valid: false, msg: 'Email is required' };
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) return { valid: false, msg: 'Enter a valid email' };
return { valid: true, msg: 'Valid email!' };
}
},
password: { el: document.getElementById('password'), msg: document.getElementById('passwordMsg'),
validate: (v) => {
if (!v) return { valid: false, msg: 'Password is required' };
if (v.length < 8) return { valid: false, msg: 'Must be at least 8 characters' };
return { valid: true, msg: 'Strong enough!' };
}
},
confirmPassword: { el: document.getElementById('confirmPassword'), msg: document.getElementById('confirmMsg'),
validate: (v) => {
const pwd = document.getElementById('password').value;
if (!v) return { valid: false, msg: 'Please confirm your password' };
if (v !== pwd) return { valid: false, msg: 'Passwords do not match' };
return { valid: true, msg: 'Passwords match!' };
}
},
phone: { el: document.getElementById('phone'), msg: document.getElementById('phoneMsg'),
validate: (v) => {
if (!v) return { valid: true, msg: '' };
if (!/^[\d\s+()-]{10,}$/.test(v)) return { valid: false, msg: 'Enter a valid phone number' };
return { valid: true, msg: 'Valid phone!' };
}
},
website: { el: document.getElementById('website'), msg: document.getElementById('websiteMsg'),
validate: (v) => {
if (!v) return { valid: true, msg: '' };
if (!/^https?:\/\/.+\..+/.test(v)) return { valid: false, msg: 'Enter a valid URL (https://...)' };
return { valid: true, msg: 'Valid URL!' };
}
},
};
const strengthFill = document.getElementById('strengthFill');
function checkStrength(pwd) {
let score = 0;
if (pwd.length >= 8) score++;
if (/[A-Z]/.test(pwd)) score++;
if (/[0-9]/.test(pwd)) score++;
if (/[^A-Za-z0-9]/.test(pwd)) score++;
const levels = [
{ w: '0%', c: '#e2e8f0' }, { w: '25%', c: '#ef4444' },
{ w: '50%', c: '#f59e0b' }, { w: '75%', c: '#84cc16' }, { w: '100%', c: '#10b981' },
];
const level = levels[Math.min(score, 4)];
strengthFill.style.width = level.w;
strengthFill.style.background = level.c;
}
function validateField(key) {
const field = fields[key];
const result = field.validate(field.el.value.trim());
field.el.classList.toggle('valid', result.valid);
field.el.classList.toggle('invalid', !result.valid && field.el.value.length > 0);
field.msg.textContent = result.msg;
field.msg.className = `msg ${result.valid ? 'success' : 'error'}`;
return result.valid;
}
Object.keys(fields).forEach(key => {
fields[key].el.addEventListener('input', () => {
validateField(key);
if (key === 'password') {
checkStrength(fields[key].el.value);
validateField('confirmPassword');
}
});
fields[key].el.addEventListener('blur', () => validateField(key));
});
form.addEventListener('submit', (e) => {
e.preventDefault();
let allValid = true;
Object.keys(fields).forEach(key => { if (!validateField(key)) allValid = false; });
if (allValid) { form.style.display = 'none'; success.style.display = 'block'; }
});