diff --git a/README.md b/README.md index 1523e52..c98f0f6 100644 --- a/README.md +++ b/README.md @@ -1 +1,17 @@ -# login-page \ No newline at end of file +# login-page + + I have created a login page that incorporates real-time validation, providing an interactive and dynamic user experience. The form is built using HTML, CSS, and JavaScript, with a focus on responsive design and usability. Additionally, I have implemented smooth animations that enhance the visual appeal of the page and contribute to a seamless user experience. These animations make the form more engaging while ensuring users can easily navigate the login process. + +# Extra points: + +Real-Time Validation: Instant feedback is provided to the user as they fill out the form, ensuring that data is correct before submission. This feature helps prevent errors and enhances the overall user experience. +Responsive Design: The form is fully responsive, ensuring it works well across various devices, including desktops, tablets, and smartphones. +Smooth Animations: The use of animations improves the visual flow, making the form feel more polished and modern. +User-Friendly Interface: With its intuitive layout and clear instructions, the form is easy to navigate, even for first-time users. +Security Focus: Although not detailed in the original description, real-time validation can help catch common input errors, contributing to a more secure login process. + + # Technologies used + + html, + css, + javascript \ No newline at end of file diff --git a/project.html b/project.html index 80c3b22..d38cf60 100644 --- a/project.html +++ b/project.html @@ -1,127 +1,63 @@ - Exam Registration - + - +
-

Exam Registration Form

- -
- - +

Exam Registration

+ +
+ + + +
- - +
+ + + +
- - +
+ + + +
- - +
+ + + +
- - +
+ + + +
+
- + +
+ - + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..339635b --- /dev/null +++ b/script.js @@ -0,0 +1,126 @@ + +const form = document.getElementById('registrationForm'); +const successMessage = document.getElementById('successMessage'); + +// Error elements +const errorElements = { + name: document.getElementById('nameError'), + email: document.getElementById('emailError'), + dob: document.getElementById('dobError'), + exam: document.getElementById('examError'), + examDate: document.getElementById('examDateError'), + terms: document.getElementById('termsError') +}; + +// Validation functions +const validators = { + name: (value) => value.trim().length >= 3, + email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value), + dob: (value) => { + const dob = new Date(value); + const today = new Date(); + return dob < today; + }, + exam: (value) => value !== '', + examDate: (value) => { + const selectedDate = new Date(value); + const today = new Date(); + today.setHours(0, 0, 0, 0); + return selectedDate >= today; + }, + terms: (checked) => checked +}; + +// Error messages +const errorMessages = { + name: 'Please enter a valid name (at least 3 characters)', + email: 'Please enter a valid email address', + dob: 'Please enter a valid date of birth', + exam: 'Please select an exam', + examDate: 'Exam date must be in the future', + terms: 'You must agree to the terms and conditions' +}; + +// Show error message +function showError(field, message) { + errorElements[field].textContent = message; + errorElements[field].style.display = 'block'; +} + +// Clear error message +function clearError(field) { + errorElements[field].textContent = ''; + errorElements[field].style.display = 'none'; +} + +// Validate field +function validateField(field, value) { + let isValid = true; + + if (field === 'terms') { + isValid = validators[field](document.getElementById(field).checked); + } else { + isValid = validators[field](value); + } + + if (!isValid) { + showError(field, errorMessages[field]); + } else { + clearError(field); + } + return isValid; +} + +// Form submission handler +form.addEventListener('submit', (e) => { + e.preventDefault(); + let isFormValid = true; + + // Validate all fields + const fields = ['name', 'email', 'dob', 'exam', 'examDate', 'terms']; + fields.forEach(field => { + const value = field === 'terms' ? + document.getElementById(field).checked : + document.getElementById(field).value; + + if (!validateField(field, value)) { + isFormValid = false; + } + }); + + if (isFormValid) { + successMessage.textContent = 'Registration successful! Redirecting...'; + successMessage.style.display = 'block'; + form.reset(); + + // Simulate API call + setTimeout(() => { + successMessage.textContent = 'Registration completed successfully!'; + }, 2000); + } +}); + +// Real-time validation +document.getElementById('full-name').addEventListener('input', (e) => { + validateField('name', e.target.value); +}); + +document.getElementById('email').addEventListener('input', (e) => { + validateField('email', e.target.value); +}); + +document.getElementById('dob').addEventListener('change', (e) => { + validateField('dob', e.target.value); +}); + +document.getElementById('exam').addEventListener('change', (e) => { + validateField('exam', e.target.value); +}); + +document.getElementById('exam-date').addEventListener('change', (e) => { + validateField('examDate', e.target.value); +}); + +document.getElementById('terms').addEventListener('change', (e) => { + validateField('terms', e.target.checked); +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..58a0125 --- /dev/null +++ b/style.css @@ -0,0 +1,158 @@ + +/* Modern CSS Reset */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + padding: 20px; +} + +.container { + background: rgba(255, 255, 255, 0.95); + padding: 2.5rem; + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + width: 100%; + max-width: 500px; + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); + transition: transform 0.3s ease; +} + +.container:hover { + transform: translateY(-5px); +} + +h1 { + font-size: 2.2rem; + color: #2b2d42; + margin-bottom: 2rem; + text-align: center; + position: relative; +} + +h1::after { + content: ''; + display: block; + width: 60px; + height: 4px; + background: #4a4e69; + margin: 0.5rem auto; + border-radius: 2px; +} + +.registration-form { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.form-group { + display: flex; + flex-direction: column; + gap: 0.5rem; + position: relative; +} + +label { + font-size: 0.95rem; + color: #4a4e69; + font-weight: 600; + margin-left: 0.2rem; +} + +input, select { + padding: 0.8rem 1.2rem; + font-size: 1rem; + border: 2px solid #e9ecef; + border-radius: 10px; + transition: all 0.3s ease; + background: #f8f9fa; +} + +input:focus, select:focus { + outline: none; + border-color: #4a4e69; + background: white; + box-shadow: 0 2px 8px rgba(74, 78, 105, 0.1); +} + +input[type="date"], select { + appearance: none; + background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 1rem center; + background-size: 1em; +} + +button { + padding: 1rem; + font-size: 1.1rem; + background: #4a4e69; + color: white; + border: none; + border-radius: 10px; + cursor: pointer; + transition: all 0.3s ease; + text-transform: uppercase; + font-weight: 600; + letter-spacing: 0.5px; + margin-top: 1rem; +} + +button:hover { + background: #2b2d42; + transform: translateY(-2px); + box-shadow: 0 5px 15px rgba(43, 45, 66, 0.2); +} + +.checkbox-group { + display: flex; + align-items: center; + gap: 0.8rem; + margin: 1rem 0; +} + +.checkbox-group input { + width: 18px; + height: 18px; + accent-color: #4a4e69; +} + +.checkbox-group label { + font-weight: normal; + color: #6c757d; +} + +.error-message { + color: #dc3545; + font-size: 0.85rem; + margin-top: 0.25rem; + display: none; +} + +.success-message { + color: #28a745; + text-align: center; + margin-top: 1rem; + display: none; +} + +@media (max-width: 480px) { + .container { + padding: 1.5rem; + } + + h1 { + font-size: 1.8rem; + } +}