screen_rotation
Copied to Clipboard
<html> <head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <form @submit.prevent="submitForm"> <h3>Vue Form Validation</h3> <label for="name">Name</label> <input id="name" v-model="name" @input="validateName" :class="{ 'is-invalid': nameError }"> <div v-if="nameError" class="invalid-feedback">{{ nameError }}</div> <label for="email">Email</label> <input id="email" v-model="email" @input="validateEmail" :class="{ 'is-invalid': emailError }"> <div v-if="emailError" class="invalid-feedback">{{ emailError }}</div> <label for="password">Password</label> <div class="password-wrapper"> <input id="password" :type="passwordFieldType" v-model="password" @input="validatePassword" :class="{ 'is-invalid': passwordError }"> <button type="button" class="show-hide-btn" @click="togglePasswordVisibility">{{ passwordVisible ? 'Hide' : 'Show' }}</button> </div> <div v-if="passwordError" class="invalid-feedback">{{ passwordError }}</div> <button type="submit" :disabled="formInvalid">Submit</button> </form> </div> <script type="module"> const app = new Vue({ el: "#app", data() { return { name: '', email: '', password: '', nameError: '', emailError: '', passwordError: '', passwordVisible: false, }; }, methods: { validateName() { const nameRegex = /^[a-zA-Z\s]*$/; if (this.name === '') { this.nameError = 'Name is required'; } else if (!nameRegex.test(this.name)) { this.nameError = 'Name can only contain letters and spaces'; } else { this.nameError = ''; } }, validateEmail() { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (this.email === '') { this.emailError = 'Email is required'; } else if (!emailRegex.test(this.email)) { this.emailError = 'Email is invalid'; } else { this.emailError = ''; } }, validatePassword() { const passwordRegex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,}$/; if (this.password === '') { this.passwordError = 'Password is required'; } else if (!passwordRegex.test(this.password)) { this.passwordError = 'Password must contain at least 8 characters, one uppercase letter, one lowercase letter, and one number'; } else { this.passwordError = ''; } }, submitForm() { // Implement form submission logic here }, togglePasswordVisibility() { this.passwordVisible = !this.passwordVisible; }, }, computed: { formInvalid() { return this.nameError || this.emailError || this.passwordError; }, passwordFieldType() { return this.passwordVisible ? 'text' : 'password'; }, }, }); </script> <style scoped> form { display: flex; flex-direction: column; gap: 1rem; max-width: 400px; margin: 0 auto; background-color: #fff; padding: 2rem; border-radius: 5px; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2); } label { font-weight: bold; font-size: 1.1rem; color: #444; margin-bottom: 0.5rem; display: block; } input { padding: 0.5rem; font-size: 1rem; border: 1px solid #ccc; border-radius: 4px; outline: none; background-color: #f5f5f5; color: #333; transition: border-color 0.2s ease; } input.is-invalid { border-color: #ff5a5a; background-color: #ffe6e6; } .invalid-feedback { color: #ff5a5a; font-size: 0.8rem; margin-top: 0.25rem; display: block; } .password-wrapper { display: flex; align-items: center; position: relative; } input[type="password"] { padding-right: 2.5rem; } .show-hide-btn { position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%); font-size: 0.8rem; border: none; background-color: transparent; cursor: pointer; color: #444; transition: color 0.2s ease; } .show-hide-btn:hover { color: #007bff; } button[type="submit"] { padding: 0.5rem 1rem; font-size: 1rem; background-color: #007bff; color: #fff; border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.3s ease; } button[type="submit"]:hover:not([disabled]) { background-color: #0062cc; } button[type="submit"][disabled] { background-color: #ccc; cursor: not-allowed; } input:focus { border-color: #007bff; } input+label { margin-top: 1rem; } .password-wrapper::before { content: ""; width: 1px; height: 75%; background-color: #ccc; position: absolute; right: 2rem; top: 50%; transform: translateY(-50%); } @media screen and (max-width: 767px) { form { padding: 1rem; } input+label { margin-top: 0.5rem; } .password-wrapper::before { right: 1rem; } } </style> </body> </html>