Form Validation CSS Javascript
https://github.com/jalbertomr/form-validation-css-js
Start with the html file with all the html elements neccesary for the manipulation of the user interface.
<!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>Form validation with Javascript</title>
<link rel="stylesheet" href="https://necolas.github.io/normalize.css/8.0.1/normalize.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap">
<link rel="stylesheet" href="./css/styles.css">
</head>
<body>
<main>
<form action="" class="formulary" id="formulary">
<!-- --- user group --- -->
<div class="formulary__group" id="group__user">
<label for="user" class="formulary__label">User</label>
<div class="formulary__group-input">
<input type="text" class="formulary__input" name="user" id="user" placeholder="user">
<i class="formulary_valid-state fas fa-times-circle"></i>
</div>
<p class="formulary__input-error">The user must have between 4 and 16 digits of numbers, leters and '_'.</p>
</div>
<!-- --- name group --- -->
<div class="formulary__group" id="group__name">
<label for="name" class="formulary__label">Name</label>
<div class="formulary__group-input">
<input type="text" class="formulary__input" name="name" id="name" placeholder="name">
<i class="formulary_valid-state fas fa-times-circle"></i>
</div>
<p class="formulary__input-error">The name must have between 4 and 16 digits of numbers, leters and '_'.</p>
</div>
<!-- --- password group --- -->
<div class="formulary__group" id="group__password">
<label for="password" class="formulary__label">Password</label>
<div class="formulary__group-input">
<input type="password" class="formulary__input" name="password" id="password">
<i class="formulary_valid-state fas fa-times-circle"></i>
</div>
<p class="formulary__input-error">The password must have between 4 and 12 digits..</p>
</div>
<!-- --- password2 group --- -->
<div class="formulary__group" id="group__password2">
<label for="password2" class="formulary__label">Repeat Password</label>
<div class="formulary__group-input">
<input type="password" class="formulary__input" name="password2" id="password2">
<i class="formulary_valid-state fas fa-times-circle"></i>
</div>
<p class="formulary__input-error">Both passwords must be the same.</p>
</div>
<!-- --- email group --- -->
<div class="formulary__group" id="group__email">
<label for="email" class="formulary__label">email</label>
<div class="formulary__group-input">
<input type="text" class="formulary__input" name="email" id="email" placeholder="email@email.com">
<i class="formulary_valid-state fas fa-times-circle"></i>
</div>
<p class="formulary__input-error">The email must have between 4 and 16 digits of numbers, leters and '_'.</p>
</div>
<!-- --- telephone group --- -->
<div class="formulary__group" id="group__telephone">
<label for="telephone" class="formulary__label">Telephone</label>
<div class="formulary__group-input">
<input type="text" class="formulary__input" name="telephone" id="telephone" placeholder="1234567890">
<i class="formulary_valid-state fas fa-times-circle"></i>
</div>
<p class="formulary__input-error">The telephone must have max 16 digits.</p>
</div>
<!-- --- Terms and Conditions --- -->
<div class="formulary__group formulary__group-terms">
<label class="formulary__label">
<input class="formulary__checkbox" type="checkbox" name="terms" id="terms">
I´m accept terms and conditions.
</label>
</div>
<div class="formulary__message" id="formulary__message">
<p><i class="fas fa-exclamation-triangle"></i> <b>Error</b> Please, check your data and accept terms.</p>
</div>
<div class="formulary__group formulary__group-btn-submit">
<button type="submit" class="formulary__btn">Submit</button>
<p class="formulary__message-success" id="formulary__message-success">Data send Successfully!.</p>
</div>
</form>
</main>
<script src="./js/forms.js"></script>
<script src="https://kit.fontawesome.com/2c36e9b7b1.js" crossorigin="anonymous"></script></body>
</html>
This html file look like this with any css style
The messages ans icons will appear and dissapear by conditional adding or removing in the javascript by manipulation of add/remove css classes.
Applying the first css style
* {
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serif;
background: #E5E5E5;
}
main {
max-width: 800px;
width: 90%;
margin: auto;
padding: 40px;
}
browser output
.formulary {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.formulary__label {
display: block;
font-weight: 700;
padding: 10px;
cursor: pointer;
}
.formulary__input {
width: 100%;
background: white;
border: 3px solid transparent;
border-radius: 3px;
height: 45px;
line-height: 45px;
padding: 0 40px 0 10px;
transition: .3s ease all;
}
browser output
Setting the focus color and the paragraph´s error of the input to hide using display: none; to show it when programatically the .formulary__input-error-active allow it to be showed. and the icon is repositioned by the use of position:relative of the parent and position:absolute of the icon and hidden it by opacity:0;
.formulary__group-input {
position: relative;
}
.formulary__input:focus {
border: 3px solid #0075ff;
outline: none;
box-shadow: 5px 10px 5px rgba(163,163,163, 0.7);
}
.formulary__input-error {
font-size: 12px;
margin-bottom: 0;
display: none;
}
.formulary__input-error-active {
display: block;
}
.formulary_valid-state {
position: absolute;
right: 10px;
bottom: 15px;
z-index: 100;
font-size: 16px;
opacity: 0;
}
Adjust the checkbox label and the error message, button in one row each one of them
.formulary__checkbox {
margin-right: 10px;;
}
.formulary__group-terms,
.formulary__message,
.formulary__group-btn-submit {
grid-column: span 2;
}
Formating the message and hidden it with display:none; only to be programmatically showed by adding another class.
.formulary__message {
height: 45px;
line-height: 45px;
background: #f66060;
padding: 0 15px;
border-radius: 3px;
display: none;
}
.formulary__message-active {
display: block;
}
.formulary__message p {
margin: 0;
}
formatting the button and success message
.formulary__group-btn-submit {
display: flex;
flex-direction: column;
align-items: center;
}
.formulary__btn {
height: 45px;
line-height: 45px;
width: 30%;
background: #0075ff;
color: white;
font-weight: bold;
border: none;
border-radius: 3px;
cursor: pointer;
transition: .1s easy all;
}
.formulary__btn:hover {
box-shadow: 5px 10px 5px rgba(163,163,163, 0.7);
}
.formulary__message-success {
font-size: 14px;
font-weight: bold;
color: #119200;
display: none;
}
.formulary__message-success-active {
display: block;
}
The validation styles in order to change color of the inputs
/* ---- validation styles ----*/
.formulary__group-correct .formulary_valid-state {
color: #1ed12d;
opacity: 1;
}
.formulary__group-incorrect label {
color: #bb2929;
}
.formulary__group-incorrect .formulary_valid-state {
color: #bb2929;
opacity: 1;
}
.formulary__group-incorrect .formulary__input {
border: 3px solid #bb2929;
}
The javascript to manage the validation behavior of the UI.
const form = document.getElementById('formulary');
const inputs = document.querySelectorAll('#formulary input');
const expressions = {
user: /^[a-zA-Z0-9\_\-]{4,16}$/, // letters, numbers, _ , -
name: /^[a-zA-ZÀ-ÿ\s]{1,40}$/, // letters, spaces, accents
password: /^.{4,12}$/, // 4 and 12 digits
email: /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-.]+$/,
telephone: /^\d{7,14}$/ // 7 to 14 numbers
}
const fields = {
user: false,
name: false,
password: false,
email: false,
telephone: false
}
const validForm = (e) => {
document.getElementById('formulary__message').classList.remove('formulary__message-active');
switch (e.target.name) {
case 'user':
validField(expressions.user, e.target, 'user');
break;
case 'name':
validField(expressions.name, e.target, 'name');
break;
case 'password':
validField(expressions.password, e.target, 'password');
validPassword2();
break;
case 'password2':
validPassword2();
break;
case 'email':
validField(expressions.email, e.target, 'email');
break;
case 'telephone':
validField(expressions.telephone, e.target, 'telephone');
break;
}
}
const validField = (expression, input, field) => {
if(expression.test(input.value)){
document.getElementById(`group__${field}`).classList.remove('formulary__group-incorrect');
document.getElementById(`group__${field}`).classList.add('formulary__group-correct');
document.querySelector(`#group__${field} i`).classList.add('fa-check-circle');
document.querySelector(`#group__${field} i`).classList.remove('fa-times-circle');
document.querySelector(`#group__${field} .formulary__input-error`).classList.remove('formulary__input-error-active');
fields[field] = true;
} else {
document.getElementById(`group__${field}`).classList.add('formulary__group-incorrect');
document.getElementById(`group__${field}`).classList.remove('formulary__group-correct');
document.querySelector(`#group__${field} i`).classList.add('fa-times-circle');
document.querySelector(`#group__${field} i`).classList.remove('fa-check-circle');
document.querySelector(`#group__${field} .formulary__input-error`).classList.add('formulary__input-error-active');
fields[field] = false;
}
}
const validPassword2 = () => {
const inputPassword1 = document.getElementById('password');
const inputPassword2 = document.getElementById('password2');
if(inputPassword1.value != inputPassword2.value){
document.getElementById(`group__password2`).classList.add('formulary__group-incorrect');
document.getElementById(`group__password2`).classList.remove('formulary__group-correct');
document.querySelector(`#group__password2 i`).classList.add('fa-times-circle');
document.querySelector(`#group__password2 i`).classList.remove('fa-check-circle');
document.querySelector(`#group__password2 .formulary__input-error`).classList.add('formulary__input-error-active');
fields['password'] = false;
} else {
document.getElementById(`group__password2`).classList.remove('formulary__group-incorrect');
document.getElementById(`group__password2`).classList.add('formulary__group-correct');
document.querySelector(`#group__password2 i`).classList.remove('fa-times-circle');
document.querySelector(`#group__password2 i`).classList.add('fa-check-circle');
document.querySelector(`#group__password2 .formulary__input-error`).classList.remove('formulary__input-error-active');
fields['password'] = true;
}
}
inputs.forEach((input) => {
input.addEventListener('keyup', validForm);
input.addEventListener('blur', validForm);
});
formulary.addEventListener('submit', (e) => {
e.preventDefault();
const terms = document.getElementById('terms');
if(fields.user && fields.name && fields.password && fields.email && fields.telephone && terms.checked ){
formulary.reset();
document.getElementById('formulary__message-success').classList.add('formulary__message-success-active');
setTimeout(() => {
document.getElementById('formulary__message-success').classList.remove('formulary__message-success-active');
}, 10000);
document.querySelectorAll('.formulary__group-correct').forEach((icon) => {
icon.classList.remove('formulary__group-correct');
});
} else {
document.getElementById('formulary__message').classList.add('formulary__message-active');
}
});
sample
eot
No hay comentarios:
Publicar un comentario