I am creating a multi form.
When I do not input any words and click the next button, the system has a display function validation but it also goes to next page automaticly.
So, what I need todo, is detect when I input a wrong format or empty string, so the system will make a validation and not automaticly go to the next page.
Finally, how can I click the submit button have the system save all my form data?
Here's is my script:
function page1() {
var name = document.forms["form1"]["name"].value
var email = document.forms["form1"]["email"].value
if (name == "" || !isNaN(name)) {
alert("Please enter correct name");
return false;
}
if (email.match(/^[\w\d._-]+#[\w\d.-]+\.[\w\d]{2,6}$/)) {
} else {
alert("Please enter correct email");
return false;
}
}
function page2() {
var phone = document.forms["form1"]["phone"].value
var address = document.forms["form1"]["address"].value
if (address == "" || !isNaN(address)) {
alert("Please enter correct address");
return false;
}
if (phone == "" || phone.length <= 9 || phone.length > 13 || isNaN(phone)) {
alert("Please enter correct phone");
return false;
}
return true;
}
function page3() {
var password = document.forms["form1"]["password"].value
var password2 = document.forms["form1"]["password"].value
if (password.match(/((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%]).{8,15})/)) {
} else {
alert("Please enter correct password");
return false;
}
if (password1 != password2) {
alert("Password and Re-enter Password was not same");
return false;
}
return true;
}
$(document).ready(function() {
$(".form-wrapper .button1").click(function() {
$(this).closest("form1").find("input[type=text], input[type=password]").val("");
var button = $(this);
var currentSection = button.parents(".section");
var currentSectionIndex = currentSection.index();
var headerSection = $('.steps li').eq(currentSectionIndex);
currentSection.removeClass("is-active").next().addClass("is-active");
headerSection.removeClass("is-active").next().addClass("is-active");
$(".form-wrapper").submit(function(e) {
e.preventDefault();
submit = $(this);
});
if (currentSectionIndex === 3) {
$(document).find(".form-wrapper .section").first().addClass("is-active");
$(document).find(".steps li").first().addClass("is-active");
}
});
});
$(document).ready(function() {
$(".form-wrapper .button2").click(function() {
var button = $(this);
var currentSection = button.parents(".section");
var currentSectionIndex = currentSection.index();
var headerSection = $('.steps li').eq(currentSectionIndex);
currentSection.removeClass("is-active").prev().addClass("is-active");
headerSection.removeClass("is-active").prev().addClass("is-active");
$(".form-wrapper").submit(function(e) {
e.preventDefault();
this.submit();
});
if (currentSectionIndex === 3) {
$(document).find(".form-wrapper .section").first().addClass("is-active");
$(document).find(".steps li").first().addClass("is-active");
}
});
});
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: 'Open Sans', sans-serif;
background-color: #fff;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: #fff;
font-weight: 200;
}
a {
text-decoration: none;
}
p,
li,
a {
font-size: 14px;
}
fieldset {
margin: 0;
padding: 0;
border: none;
color: #fff;
}
/* GRID */
.twelve {
width: 100%;
}
.eleven {
width: 91.53%;
}
.ten {
width: 83.06%;
}
.nine {
width: 74.6%;
}
.eight {
width: 66.13%;
}
.seven {
width: 57.66%;
}
.six {
width: 49.2%;
}
.five {
width: 40.73%;
}
.four {
width: 32.26%;
}
.three {
width: 23.8%;
}
.two {
width: 15.33%;
}
.one {
width: 6.866%;
}
/* COLUMNS */
.col {
display: block;
float: left;
margin: 0 0 0 1.6%;
}
.col:first-of-type {
margin-left: 0;
}
.container {
width: 100%;
max-width: 700px;
margin: 0 auto;
position: relative;
}
.row {
padding: 20px 0;
}
/* CLEARFIX */
.cf:before,
.cf:after {
content: " ";
display: table;
}
.cf:after {
clear: both;
}
.cf {
*zoom: 1;
}
.wrapper {
width: 100%;
margin: 30px 0;
}
/* STEPS */
.steps {
list-style-type: none;
margin: 0;
padding: 0;
background-color: #000;
text-align: center;
}
.steps li {
display: inline-block;
margin: 20px;
color: #ccc;
padding-bottom: 5px;
}
.steps li.is-active {
border-bottom: 1px solid #fff;
color: #fff;
}
/* FORM */
.form-wrapper .section {
padding: 0px 20px 30px 20px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
background-color: #000;
opacity: 0;
-webkit-transform: scale(1, 0);
-ms-transform: scale(1, 0);
-o-transform: scale(1, 0);
transform: scale(1, 0);
-webkit-transform-origin: top center;
-moz-transform-origin: top center;
-ms-transform-origin: top center;
-o-transform-origin: top center;
transform-origin: top center;
-webkit-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
text-align: center;
position: absolute;
width: 100%;
min-height: 300px
}
.form-wrapper .section h3 {
margin-bottom: 30px;
}
.form-wrapper .section.is-active {
opacity: 1;
-webkit-transform: scale(1, 1);
-ms-transform: scale(1, 1);
-o-transform: scale(1, 1);
transform: scale(1, 1);
}
.form-wrapper .button1,
.form-wrapper .submit {
background-color: #fff;
display: inline-block;
padding: 8px 30px;
color: #000;
cursor: pointer;
font-size: 14px !important;
font-family: 'Open Sans', sans-serif !important;
position: absolute;
right: 20px;
bottom: 20px;
}
.form-wrapper .button2 {
background-color: #fff;
display: inline-block;
padding: 8px 30px;
color: #000;
cursor: pointer;
font-size: 14px !important;
font-family: 'Open Sans', sans-serif !important;
position: absolute;
left: 20px;
bottom: 20px;
}
.form-wrapper .submit {
border: none;
outline: none;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.form-wrapper input[type="text"],
.form-wrapper input[type="password"] {
display: block;
padding: 10px;
margin: 10px auto;
background-color: #f1f1f1;
border: none;
width: 50%;
outline: none;
font-size: 14px !important;
font-family: 'Open Sans', sans-serif !important;
}
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
<div class="container">
<div class="wrapper">
<ul class="steps">
<li class="is-active">Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
</ul>
<form class="form-wrapper" id="form1" onsumbit="return submit1()">
<fieldset class="section is-active">
<h3>Your Details</h3>
<input type="text" name="name" id="name" placeholder="Name">
<input type="text" name="email" id="email" placeholder="Email">
<input class="button1" type="button" value="Next" onclick="return page1()">
</fieldset>
<fieldset class="section">
<h3>other Details</h3>
<input type="text" name="phone" id="phone" placeholder="Phone">
<input type="text" name="address" id="address" placeholder="address">
<input class="button2" type="button" value="Previous">
<input class="button1" type="button" value="Next" onclick="return page2()">
</fieldset>
<fieldset class="section">
<h3>Choose a Password</h3>
<input type="password" name="password" id="password" placeholder="Password">
<input type="password" name="password2" id="password2" placeholder="Re-enter Password">
<input class="button2" type="button" value="Previous">
<input class="submit button1" type="submit" value="Sign Up" onclick="return page3()">
</fieldset>
<fieldset class="section">
<h3>Account Created!</h3>
<p>Your account has now been created.</p>
<div class="button1">Reset Form</div>
</fieldset>
</form>
</div>
</div>
You do not need onclick event on the button of the page1, page2, page3.
remove onclick="return page1()" call the functions
Just use one event onclick and it should work, add classes to check the validations, this is what I did.
if ($(this).hasClass('page1')) {
if (!page1()) {
return;
}
}
else if ($(this).hasClass('page2')) {
if (!page2()) {
return;
}
}
else if ($(this).hasClass('page3')) {
if (!page3()) {
return;
}
}
function page1() {
var name = document.forms["form1"]["name"].value
var email = document.forms["form1"]["email"].value
if (name == "" || !isNaN(name)) {
alert("Please enter correct name");
return false;
}
if (email.match(/^[\w\d._-]+#[\w\d.-]+\.[\w\d]{2,6}$/)) {
} else {
alert("Please enter correct email");
return false;
}
return true;
}
function page2() {
var phone = document.forms["form1"]["phone"].value
var address = document.forms["form1"]["address"].value
if (address == "" || !isNaN(address)) {
alert("Please enter correct address");
return false;
}
if (phone == "" || phone.length <= 9 || phone.length > 13 || isNaN(phone)) {
alert("Please enter correct phone");
return false;
}
return true;
}
function page3() {
var password = document.forms["form1"]["password"].value
var password2 = document.forms["form1"]["password"].value
if (password.match(/((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%]).{8,15})/)) {
} else {
alert("Please enter correct password");
return false;
}
if (password1 != password2) {
alert("Password and Re-enter Password was not same");
return false;
}
return true;
}
$(document).ready(function() {
$(".form-wrapper .button1").click(function() {
if ($(this).hasClass('page1')) {
if (!page1()) {
return;
}
}
else if ($(this).hasClass('page2')) {
if (!page2()) {
return;
}
}
else if ($(this).hasClass('page3')) {
if (!page3()) {
return;
}
}
$(this).closest("form1").find("input[type=text], input[type=password]").val("");
var button = $(this);
var currentSection = button.parents(".section");
var currentSectionIndex = currentSection.index();
var headerSection = $('.steps li').eq(currentSectionIndex);
currentSection.removeClass("is-active").next().addClass("is-active");
headerSection.removeClass("is-active").next().addClass("is-active");
$(".form-wrapper").submit(function(e) {
e.preventDefault();
submit = $(this);
});
if (currentSectionIndex === 3) {
$(document).find(".form-wrapper .section").first().addClass("is-active");
$(document).find(".steps li").first().addClass("is-active");
}
});
});
$(document).ready(function() {
$(".form-wrapper .button2").click(function() {
var button = $(this);
var currentSection = button.parents(".section");
var currentSectionIndex = currentSection.index();
var headerSection = $('.steps li').eq(currentSectionIndex);
currentSection.removeClass("is-active").prev().addClass("is-active");
headerSection.removeClass("is-active").prev().addClass("is-active");
$(".form-wrapper").submit(function(e) {
e.preventDefault();
this.submit();
});
if (currentSectionIndex === 3) {
$(document).find(".form-wrapper .section").first().addClass("is-active");
$(document).find(".steps li").first().addClass("is-active");
}
});
});
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: 'Open Sans', sans-serif;
background-color: #fff;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: #fff;
font-weight: 200;
}
a {
text-decoration: none;
}
p,
li,
a {
font-size: 14px;
}
fieldset {
margin: 0;
padding: 0;
border: none;
color: #fff;
}
/* GRID */
.twelve {
width: 100%;
}
.eleven {
width: 91.53%;
}
.ten {
width: 83.06%;
}
.nine {
width: 74.6%;
}
.eight {
width: 66.13%;
}
.seven {
width: 57.66%;
}
.six {
width: 49.2%;
}
.five {
width: 40.73%;
}
.four {
width: 32.26%;
}
.three {
width: 23.8%;
}
.two {
width: 15.33%;
}
.one {
width: 6.866%;
}
/* COLUMNS */
.col {
display: block;
float: left;
margin: 0 0 0 1.6%;
}
.col:first-of-type {
margin-left: 0;
}
.container {
width: 100%;
max-width: 700px;
margin: 0 auto;
position: relative;
}
.row {
padding: 20px 0;
}
/* CLEARFIX */
.cf:before,
.cf:after {
content: " ";
display: table;
}
.cf:after {
clear: both;
}
.cf {
*zoom: 1;
}
.wrapper {
width: 100%;
margin: 30px 0;
}
/* STEPS */
.steps {
list-style-type: none;
margin: 0;
padding: 0;
background-color: #000;
text-align: center;
}
.steps li {
display: inline-block;
margin: 20px;
color: #ccc;
padding-bottom: 5px;
}
.steps li.is-active {
border-bottom: 1px solid #fff;
color: #fff;
}
/* FORM */
.form-wrapper .section {
padding: 0px 20px 30px 20px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
background-color: #000;
opacity: 0;
-webkit-transform: scale(1, 0);
-ms-transform: scale(1, 0);
-o-transform: scale(1, 0);
transform: scale(1, 0);
-webkit-transform-origin: top center;
-moz-transform-origin: top center;
-ms-transform-origin: top center;
-o-transform-origin: top center;
transform-origin: top center;
-webkit-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
text-align: center;
position: absolute;
width: 100%;
min-height: 300px
}
.form-wrapper .section h3 {
margin-bottom: 30px;
}
.form-wrapper .section.is-active {
opacity: 1;
-webkit-transform: scale(1, 1);
-ms-transform: scale(1, 1);
-o-transform: scale(1, 1);
transform: scale(1, 1);
}
.form-wrapper .button1,
.form-wrapper .submit {
background-color: #fff;
display: inline-block;
padding: 8px 30px;
color: #000;
cursor: pointer;
font-size: 14px !important;
font-family: 'Open Sans', sans-serif !important;
position: absolute;
right: 20px;
bottom: 20px;
}
.form-wrapper .button2 {
background-color: #fff;
display: inline-block;
padding: 8px 30px;
color: #000;
cursor: pointer;
font-size: 14px !important;
font-family: 'Open Sans', sans-serif !important;
position: absolute;
left: 20px;
bottom: 20px;
}
.form-wrapper .submit {
border: none;
outline: none;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.form-wrapper input[type="text"],
.form-wrapper input[type="password"] {
display: block;
padding: 10px;
margin: 10px auto;
background-color: #f1f1f1;
border: none;
width: 50%;
outline: none;
font-size: 14px !important;
font-family: 'Open Sans', sans-serif !important;
}
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
<div class="container">
<div class="wrapper">
<ul class="steps">
<li class="is-active">Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
</ul>
<form class="form-wrapper" id="form1" onsumbit="return submit1()">
<fieldset class="section is-active">
<h3>Your Details</h3>
<input type="text" name="name" id="name" placeholder="Name">
<input type="text" name="email" id="email" placeholder="Email">
<input class="button1 page1" type="button" value="Next">
</fieldset>
<fieldset class="section">
<h3>other Details</h3>
<input type="text" name="phone" id="phone" placeholder="Phone">
<input type="text" name="address" id="address" placeholder="address">
<input class="button2" type="button" value="Previous">
<input class="button1 page2" type="button" value="Next" onclick="return page2()">
</fieldset>
<fieldset class="section">
<h3>Choose a Password</h3>
<input type="password" name="password" id="password" placeholder="Password">
<input type="password" name="password2" id="password2" placeholder="Re-enter Password">
<input class="button2" type="button" value="Previous">
<input class="submit button1 page3" type="submit" value="Sign Up" onclick="return page3()">
</fieldset>
<fieldset class="section">
<h3>Account Created!</h3>
<p>Your account has now been created.</p>
<div class="button1">Reset Form</div>
</fieldset>
</form>
</div>
</div>
by doing this you will be able to apply your code easily and you do not have to find multiple places to be appear.
Related
let myLibrary = [
{
id: 0,
title: "The Once and Future King",
author: "White",
pages: 654,
read: false,
},
{
id: 1,
title: "The Hobbit",
author: "Tolkien",
pages: 304,
read: false,
},
];
const bookContent = document.getElementById("content");
function displayBook(book) {
const addBook = document.createElement("div");
addBook.className = "book";
addBook.id = book.id;
bookContent.appendChild(addBook);
addBook.innerHTML = `
<div class="title">
<p class="bookTitle">
<span>${book.title}</span>
</p>
</div>
<div class="body">
<p>
Author: <span>${book.author}</span>
</p>
<p>
Pages: <span>${book.pages}</span>
</p>
</div>
<div class="read">
<label class="switch" data-book="0">
<input type="checkbox" />
<span class="slider round"></span>
</label>
</div>
<div class="delete">
<button class="delete-btn">DELETE</button>
</div>`;
}
// Display your original object list
myLibrary.forEach((book) => {
displayBook(book);
});
// Handle your object creation
const form = document.getElementById("form");
form.addEventListener("submit", updateLibrary);
function updateLibrary(event) {
// Need this so it doesn't refresh page
event.preventDefault();
const title = document.getElementById("title").value;
const author = document.getElementById("author").value;
const pages = document.getElementById("pages").value;
const book = {
title: title,
author: author,
pages: parseInt(pages),
read: false,
};
// Adds object to array
myLibrary.push(book);
// Displays new book
displayBook(book);
// Reset form
resetForm();
// Close form
document.getElementById("addBookForm").style.display = "none";
console.log(myLibrary);
}
// Resets the form so user can input another book
function resetForm() {
document.getElementById("form").reset();
}
// The form is automatically set to hidden. This loads it up for the user
const openForm = function () {
document.getElementById("addBookForm").style.display = "block";
document.getElementById("title").focus();
};
// Sets the form display back to none
const closeForm = () =>
(document.getElementById("addBookForm").style.display = "none");
/* .main {
} */
.header {
display: flex;
flex-direction: column;
background-color: #c689c6;
height: 150px;
border: 1px solid #3b133b;
}
.btn {
margin: 0 auto;
margin-top: 55px;
display: block;
text-align: center;
background-color: #4649ff;
padding: 0.75rem 1.25rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
font-size: 1rem;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.btn:hover {
background-color: #3134fa;
}
.content {
display: flex;
flex-flow: row wrap;
align-content: flex-start;
justify-content: flex-start;
background-color: #fffdfa;
height: auto;
}
.book {
border: 2px solid #ffa94d;
background-color: #ffd8a8;
color: #d9480f;
width: 280px;
height: 365px;
margin: 10px;
}
.title {
border-bottom: 2px solid #ffa94d;
}
.title p {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
font-size: larger;
}
.title span {
color: #3c4048;
}
.body {
border: 1px solid transparent;
height: 200px;
background-color: #fff4e6;
}
.body p {
padding-left: 20px;
}
p span {
color: #3c4048;
}
.read {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
border-top: 2px solid #ffa94d;
text-align: center;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked + .slider {
background-color: #3d8361;
}
input:focus + .slider {
box-shadow: 0 0 1px #3d8361;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.delete {
height: 50px;
border-top: 2px solid #ffa94d;
}
.delete-btn {
margin: 0 auto;
margin-top: 8px;
display: block;
text-align: center;
background-color: #e94560;
padding: 0.5rem 0.75rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.delete-btn:hover {
background-color: #e7082d;
}
.close-btn {
color: #e7082d;
font-size: large;
background-color: #c689c6;
border: none;
float: right;
cursor: pointer;
}
/* THE FORM */
.form-content {
display: flex;
justify-content: center;
}
.form {
display: none;
position: fixed;
margin-top: 5px;
border: 2px solid #3b133b;
animation: openForm 0.5s;
z-index: 1;
}
#keyframes openForm {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
.form h1 {
text-align: center;
}
.form-container {
background-color: #c689c6;
border: 2px solid black;
max-width: 300px;
padding: 10px;
}
.form-container h1 {
padding-left: 20px;
}
.form-container input[type="text"],
.form-container input[type="number"] {
width: 80%;
padding: 15px;
margin: 5px 0 22px 0;
border: none;
}
.form-container input[type="text"]:focus,
.form-container input[type="number"]:focus {
outline: none;
}
<!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" />
<link rel="stylesheet" href="styles.css" />
<title>Library</title>
</head>
<body>
<div class="main">
<div class="header">
<button class="btn" id="btn" onclick="openForm()">Add a Book</button>
</div>
<div class="form-content">
<div class="form" id="addBookForm">
<form id="form" action="" class="form-container">
<button type="button" class="close-btn" onclick="closeForm()">
x
</button>
<h1>Add a Book</h1>
<label for="title">Title</label>
<input
type="text"
placeholder="Title"
name="title"
id="title"
required
/>
<label for="author">Author</label>
<input
type="text"
placeholder="Author"
name="author"
id="author"
required
/>
<label for="pages">Pages</label>
<input
type="number"
placeholder="Pages"
name="pages"
required
id="pages"
/>
<button type="submit" id="submit-btn">Submit</button>
</form>
</div>
</div>
<div id="content" class="content"></div>
</div>
</body>
</html>
I have a form where the user inputs information from a book they are reading and upon hitting submit, the information is sent as its own object inside an array. I also have a forEach method running which loops through the array and displays each object as a div on the web page.
let myLibrary = [];
const book = {
title: title,
author: author,
pages: parseInt(pages),
read: false,
};
myLibrary.push(book)
As you can see from the code above, the three properties that the user fills out are the books title, author and page count. There's also a property that is automatically added called the read property and it is automatically set as false.
The Problem
My problem is this. I have the following code displayed at the bottom of each div.
<div class="read">
<label class="switch">
<input type="checkbox" />
<span class="slider round"></span>
</label>
</div>
This code is very simple. It's a toggle switch which I found here.
I want it so when the toggle switch is grayed out, the read status is set to false. But when the toggle switch is turned on, the read property is set to true. I am having a very difficult time figuring out how to get this done.
What I've Tried
I was able to use an onclick to select the toggle switch's parent element, and I tested it using console.log however I am unsure of where to go from there. I attempted to update the book.read to true using the ternary operator but it was out of scope and resulted in an error.
document.querySelector(".main").onclick = (ev) => {
let el = ev.target.classList.contains("switch")
? ev.target.parentElement
: ev.target.classList.contains("slider")
? ev.target
: false;
if (el) {
let toggle = el.parentElement.parentElement.parentElement;
let index = [...toggle.parentElement.children].indexOf(toggle);
myLibrary[index].read = false ? false : true;
console.log(myLibrary[index].read);
}
console.log(myLibrary);
};
Change this
function displayBook(book) {
...
<label class="switch" data-book="0">
to
function displayBook(book,bookIndex) {
...
<label class="switch" data-book="${bookIndex}">
and
myLibrary.forEach((book) => {
displayBook(book);
});
to
myLibrary.forEach((book,i) => {
displayBook(book,i);
});
lastly change
// Displays new book
displayBook(book);
to
// Displays new book
displayBook(book,myLibrary.length-1);
Here is the code inclusive a delete function
It would be slightly simpler if we had an associate array on book_id
Note I removed the numeric ID because it is not needed since the index of the array is the same
let myLibrary = [{
title: "The Once and Future King",
author: "White",
pages: 654,
read: false,
},
{
title: "The Hobbit",
author: "Tolkien",
pages: 304,
read: false,
},
];
const bookContent = document.getElementById("content");
const formDiv = document.getElementById("addBookForm");
function displayBook(book, idx) {
const addBook = document.createElement("div");
addBook.className = "book";
addBook.id = `book_${idx}`;
bookContent.appendChild(addBook);
addBook.innerHTML = `
<div class="title">
<p class="bookTitle">
<span>${book.title}</span>
</p>
</div>
<div class="body">
<p>
Author: <span>${book.author}</span>
</p>
<p>
Pages: <span>${book.pages}</span>
</p>
</div>
<div class="read">
<label class="switch" data-book="${idx}">
<input type="checkbox" />
<span class="slider round"></span>
</label>
</div>
<div class="delete">
<button class="delete-btn">DELETE</button>
</div>`;
}
// Display your original object list
myLibrary.forEach((book, i) => {
displayBook(book, i);
});
const deleteBook = (e) => {
const parent = e.target.closest("div.book");
const idx = parent.querySelector(".switch").dataset.book;
parent.remove();
console.log(idx);
myLibrary.splice(idx, 1);
console.log(myLibrary);
content.querySelectorAll("div.book").forEach((book, i) => { // reset the hard way
book.id = `book_${i}`;
book.querySelector("label.switch").dataset.book = i;
})
};
content.addEventListener("click", function(e) {
const tgt = e.target;
if (!tgt.matches(".delete-btn")) return; // not the delete
deleteBook(e); // pass the event to the delete
})
// Handle your object creation
const form = document.getElementById("form");
form.addEventListener("submit", updateLibrary);
function updateLibrary(event) {
// Need this so it doesn't refresh page
event.preventDefault();
const title = document.getElementById("title").value;
const author = document.getElementById("author").value;
const pages = document.getElementById("pages").value;
const book = {
title: title,
author: author,
pages: parseInt(pages),
read: false,
};
// Adds object to array
myLibrary.push(book);
// Displays new book
displayBook(book);
// Reset form
resetForm();
// Close form
formDiv.style.display = "none";
console.log(myLibrary);
}
// Resets the form so user can input another book
function resetForm() {
document.getElementById("form").reset();
}
// The form is automatically set to hidden. This loads it up for the user
const openForm = function() {
formDiv.style.display = "block";
document.getElementById("title").focus();
};
// Sets the form display back to none
const closeForm = () => formDiv.style.display = "none";
/* .main {
} */
.header {
display: flex;
flex-direction: column;
background-color: #c689c6;
height: 150px;
border: 1px solid #3b133b;
}
.btn {
margin: 0 auto;
margin-top: 55px;
display: block;
text-align: center;
background-color: #4649ff;
padding: 0.75rem 1.25rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
font-size: 1rem;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.btn:hover {
background-color: #3134fa;
}
.content {
display: flex;
flex-flow: row wrap;
align-content: flex-start;
justify-content: flex-start;
background-color: #fffdfa;
height: auto;
}
.book {
border: 2px solid #ffa94d;
background-color: #ffd8a8;
color: #d9480f;
width: 280px;
height: 365px;
margin: 10px;
}
.title {
border-bottom: 2px solid #ffa94d;
}
.title p {
display: flex;
align-items: center;
text-align: center;
justify-content: center;
font-size: larger;
}
.title span {
color: #3c4048;
}
.body {
border: 1px solid transparent;
height: 200px;
background-color: #fff4e6;
}
.body p {
padding-left: 20px;
}
p span {
color: #3c4048;
}
.read {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
border-top: 2px solid #ffa94d;
text-align: center;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: 0.4s;
transition: 0.4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
}
input:checked+.slider {
background-color: #3d8361;
}
input:focus+.slider {
box-shadow: 0 0 1px #3d8361;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.delete {
height: 50px;
border-top: 2px solid #ffa94d;
}
.delete-btn {
margin: 0 auto;
margin-top: 8px;
display: block;
text-align: center;
background-color: #e94560;
padding: 0.5rem 0.75rem;
border-radius: 10rem;
color: #fff;
cursor: pointer;
letter-spacing: 0.15rem;
transition: all 0.3s;
}
.delete-btn:hover {
background-color: #e7082d;
}
.close-btn {
color: #e7082d;
font-size: large;
background-color: #c689c6;
border: none;
float: right;
cursor: pointer;
}
/* THE FORM */
.form-content {
display: flex;
justify-content: center;
}
.form {
display: none;
position: fixed;
margin-top: 5px;
border: 2px solid #3b133b;
animation: openForm 0.5s;
z-index: 1;
}
#keyframes openForm {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
.form h1 {
text-align: center;
}
.form-container {
background-color: #c689c6;
border: 2px solid black;
max-width: 300px;
padding: 10px;
}
.form-container h1 {
padding-left: 20px;
}
.form-container input[type="text"],
.form-container input[type="number"] {
width: 80%;
padding: 15px;
margin: 5px 0 22px 0;
border: none;
}
.form-container input[type="text"]:focus,
.form-container input[type="number"]:focus {
outline: none;
}
<div class="main">
<div class="header">
<button class="btn" id="btn" onclick="openForm()">Add a Book</button>
</div>
<div class="form-content">
<div class="form" id="addBookForm">
<form id="form" action="" class="form-container">
<button type="button" class="close-btn" onclick="closeForm()">
x
</button>
<h1>Add a Book</h1>
<label for="title">Title</label>
<input type="text" placeholder="Title" name="title" id="title" required />
<label for="author">Author</label>
<input type="text" placeholder="Author" name="author" id="author" required />
<label for="pages">Pages</label>
<input type="number" placeholder="Pages" name="pages" required id="pages" />
<button type="submit" id="submit-btn">Submit</button>
</form>
</div>
</div>
<div id="content" class="content"></div>
</div>
I wrote this for a Bmr tool on my website. I don't have much understanding regarding html CSS just started learning this. . On running the snippet is not showing the result. I am unable to figure out 'why?'.
I wrote a similar code for BMI that worked fine but this one is not.
var bmr;
function calc() {
var age = document.getElementById("age").value;
var gender = document.getElementById("gender").value;
var height = document.getElementById("height").value;
var weigth = document.getElementById("weigth").value;
if (gender == "masc") {
bmr = 66.5 + (13.75 * weigth) + (5.003 * height) - (6.755 * age);
} else {
bmr = 655.1 + (9.563 * weigth) + (1.850 * height) - (4.676 * age);
}
}
document.getElementsByTagName("button")[0].addEventListener("click", function() {
calc();
document.getElementById('lblResult').innerHTML = bmr;
})
* {
.column {
max-block-size: 100%;
}
#media (min-width: 600px) {
.column {
width: 50%;
}
}
}
body {
margin: 0;
min-height: 100vh;
;
background: linear-gradient(to bottom right, #ffffff, #ffffff) font-family: LEMONMILK-Bold;
font-size: 1rem;
color: #ffffff;
}
.form {
background-color: #0295DB;
max-height: 240px;
max-width: 450px;
border-radius: 20px;
margin: 1.25rem auto 1.25rem auto;
padding-bottom: 0.4rem;
display: block;
border: solid 1px #289df6;
box-shadow: 0 0 40px 0 #ddd;
}
.form:hover {
box-shadow: 0 0 60px 0 #ccc;
transition: .4s;
transform: scale(1.02);
}
.row-one {
padding: 1.25rem;
}
.row-two {
padding: 1.25rem;
}
.text-input {
width: 3.125rem;
height: 1rem;
border-radius: 10px;
background-color: #dbeffe;
border: none;
outline: none;
padding: 0.313rem 0.625rem;
cursor: pointer;
}
.text-input:last-child {
margin-bottom: 2.188rem;
}
.text-input:hover {
background-color: #cbe7fd;
}
#submit {
border: none;
border-radius: 10px;
max-height: 2.5rem;
max-width: 8.75rem;
background-color: #ffffff;
color: #289df6;
margin: auto;
display: block;
outline: none;
cursor: pointer;
}
#submit:hover {
background-color: #f7f7f7;
}
.text {
display: inline-block;
margin: 0.313rem 1.25rem 0.313rem 0.5rem;
;
}
.row-one {
padding: 1.875rem 1.25rem 1.563rem 1.25rem;
}
.row-two {
padding: 0.938rem 1.25rem 1.875rem 1.25rem;
}
.container {
display: inline-block;
position: relative;
padding-left: 1.875rem;
cursor: pointer;
user-select: none;
}
.container input {
position: absolute;
opacity: 0;
}
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 1.563rem;
width: 1.563rem;
background-color: #dbeffe;
border-radius: 50%;
}
.container:hover input~.checkmark {
background-color: #cbe7fd;
}
.container input:checked~.checkmark {
background-color: #289df6;
}
h3 {
font-size: 1rem;
font-weight: 400;
text-align: center;
padding: 0.938rem;
color: #333333;
}
h3 b {
font-size: 2rem;
font-weight: 400;
color: #289df6;
}
.checkmark:after {
content: "";
position: absolute;
display: none;
}
.container input:checked~.checkmark:after {
display: block;
}
.container .checkmark:after {
left: 0.563rem;
top: 0.313rem;
width: 0.313rem;
height: 0.625rem;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
<link href="http://gadgetsense.in/wp-content/uploads/2021/09/LEMONMILK-Bold.otf" rel="stylesheet">
<form class="form" id="form" onsubmit="return validateForm()">
<div class="row-one">
<input type="text" class="text-input" id="age" autocomplete="off" required/>
<p class="text">Age</p>
<label class="container">
<input type="radio" name="gender" id="gender" value="fem"><p class="text">Female</p>
<span class="checkmark"></span>
</label>
<label class="container">
<input type="radio" name="gender" id="gender" value="masc"><p class="text">Male</p>
<span class="checkmark"></span>
</label>
</div>
<div class="row-two">
<input type="text" class="text-input" id="height" autocomplete="off" required>
<p class="text">Height (cm)</p>
<input type="text" class="text-input" id="weight" autocomplete="off" required>
<p class="text">Weight (kg)</p>
</div>
<button type="button" onclick="" id="submit">Submit</button>
</form>
<p id="lblResult">BMR</p>
First, change onclick to include function name...
<button type="button" onclick="calc" id="submit">Submit</button>
Then change to...
<script>
function calc() {
var bmr;
var age = document.getElementById("age").value;
var gender = document.getElementById("gender").value;
var height = document.getElementById("height").value;
var weigth = document.getElementById("weigth").value;
if (gender == "masc") {
bmr = 66.5 + (13.75 * weigth) + (5.003 * height) - (6.755 * age);
} else {
bmr = 655.1 + (9.563 * weigth) + (1.850 * height) - (4.676 * age);
}
}
document.getElementById('lblResult').innerHTML = bmr;
})
The error says, that you are using an undefined variable:
"message": "Uncaught TypeError: Cannot read properties of null (reading 'value')",
"filename": "https://stacksnippets.net/js",
"lineno": 202,
"colno": 49
I had personally much trouble with this error, and that was because the elements that I wanted to use in JS wasn't defined.
You define a element with:
id="someid"
class="someid"
The last two JSONs (key: value) give us information about the error's location.
Here also a similar explanation: https://bobbyhadz.com/blog/javascript-cannot-read-property-click-of-null
Hope that helps, OpiliteX
In the example below the expected behavior is that once the form field has valid input, a specific class is applied, which pushes the input label to sit mid-line of the form field's border. You can see this when you navigate to each input.
When a field is validated, that class, valid-ct is applied and it's supposed to remain there and keep that label above the input. But, as I navigate to each field, the class, valid-ct goes away and the label goes back into the placeholder position, covering any input.
I believe the culprit is in this function, but I am not getting any errors, so I'm not sure what I'm doing wrong:
$(function () {
$("input, textarea").bind("ClassChanged", function () {
$(this).parent().removeClass("valid-ct error-ct");
// console.log(!$.trim($(this).val()));
if ($(this).hasClass("error")) {
$(this).parent().addClass("error-ct");
} else if ($(this).hasClass("valid") && $.trim($(this).val())) {
$(this).parent().addClass("valid-ct");
} else if ($(this).hasClass("error terms-agree")) {
console.log(123);
}
});
});
Where am I going wrong with this?
(function () {
var originalAddClassMethod = jQuery.fn.addClass;
jQuery.fn.addClass = function () {
// Execute the original method.
var result = originalAddClassMethod.apply(this, arguments);
// trigger a custom event
jQuery(this).trigger("ClassChanged");
// return the original result
return result;
};
})();
$(function () {
$("input, textarea").bind("ClassChanged", function () {
$(this).parent().removeClass("valid-ct error-ct");
// console.log(!$.trim($(this).val()));
if ($(this).hasClass("error")) {
$(this).parent().addClass("error-ct");
} else if ($(this).hasClass("valid") && $.trim($(this).val())) {
$(this).parent().addClass("valid-ct");
} else if ($(this).hasClass("error terms-agree")) {
console.log(123);
}
});
});
$("input.required, textarea.required").trigger("ClassChanged");
$(".request-form .form-ct a.company-btn--blue").on("click", function (e) {
e.preventDefault();
$("#footer-form-submit").submit();
});
$("input").on("focus blur", function () {
$(this).parent().toggleClass("focus-ct");
});
// Create a custom classChange trigger
(function () {
var originalAddClassMethod = jQuery.fn.addClass;
jQuery.fn.addClass = function () {
// Execute the original method.
var result = originalAddClassMethod.apply(this, arguments);
// trigger a custom event
jQuery(this).trigger("ClassChanged");
// return the original result
return result;
};
})();
$(function () {
$("input").bind("ClassChanged", function () {
$(this).parent().removeClass("valid-ct error-ct");
// console.log(!$.trim($(this).val()));
if ($(this).hasClass("error")) {
$(this).parent().addClass("error-ct");
} else if ($(this).hasClass("valid") && $.trim($(this).val())) {
$(this).parent().addClass("valid-ct");
} else if ($(this).hasClass("error terms-agree")) {
console.log(123);
}
});
});
$("input.required").trigger("ClassChanged");
.container {
padding: 0.5rem;
}
.request-form h2 {
margin: 80px auto 56px;
max-width: 768px;
font-weight: 800;
}
.request-form h2 span {
color: #005fec;
font-weight: 800;
}
#media screen and (min-width: 768px) {
.request-form h2 {
margin-bottom: 72px;
text-align: center;
}
}
.request-form .container .row h4.sub-head {
margin-bottom: 2.5rem;
margin-top: 0;
}
.request-form input[type="text"],
.request-form input[type="email"],
.request-form input[type="tel"],
.request-form input[type="number"] {
background-color: #fff;
border: 0;
font-size: 20px;
width: 100%;
height: 60px;
cursor: auto;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
box-sizing: border-box;
transition: background-color 0.4s;
border: 1px solid #6d7582;
padding: 0 16px;
border-radius: 4px;
}
.request-form input:-webkit-autofill {
box-shadow: 0 0 0 50px white inset;
-webkit-box-shadow: 0 0 0 50px white inset;
-webkit-text-fill-color: #333;
}
.request-form input:-webkit-autofill:focus {
box-shadow: 0 0 0 50px white inset;
-webkit-box-shadow: 0 0 0 50px white inset;
-webkit-text-fill-color: #333;
}
.request-form .email-ct {
margin-right: 12px;
}
.request-form .phone-ct {
margin-left: 12px;
}
.request-form .input-ct {
position: relative;
margin-top: 24px;
width: 100%;
}
.fandlname {
display: flex;
}
.fandlname .first-name-ct {
margin-right: 12px;
}
.fandlname .last-name-ct {
margin-left: 12px;
}
.request-form .input-ct label:not(.error) {
color: #444a53;
position: absolute;
top: 22px;
left: 8px;
background-color: #fff;
padding: 0 8px;
font-weight: 300;
font-size: 16px;
transition: all 200ms ease-in-out;
pointer-events: none;
z-index: 1;
}
.request-form .state-search-ct.error-ct.input-ct label {
top: 22px;
}
.state-search-ct.valid-ct label.error {
display: none !important;
}
.request-form .input-ct.focus-ct label:not(.error) {
color: #005fec !important;
font-family: motiva-sans, sans-serif;
top: -13px;
z-index: 1;
}
.request-form .input-ct.focus-ct label.error {
display: none !important;
}
.request-form .input-ct input:focus,
.request-form .input-ct textarea:focus {
border-color: #005fec !important;
}
.request-form .input-ct input.error,
.request-form textarea.error {
border-color: #e12d2d;
}
.request-form .input-ct.valid-ct label {
color: #444a53;
top: -8px;
z-index: 1;
}
.request-form .input-ct.error-ct label {
color: #e12d2d;
z-index: 1;
}
.request-form label.error {
font-size: 14px;
font-weight: 400;
background: url("/assets/icons/icon-error.svg") left center no-repeat;
padding-left: 20px;
line-height: 16px;
color: #e12d2d;
margin-top: 8px;
display: block !important;
text-align: left;
}
.request-form .valid-ct label.error {
display: none !important;
}
div.error-ct h4 {
color: #e12d2d;
margin-bottom: 8px;
}
.request-form textarea {
border: 1px solid #6d7582;
border-radius: 4px;
background-color: #fff;
font-size: 20px;
width: 100%;
height: 136px;
cursor: auto;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
padding: 20px 16px;
box-sizing: border-box;
transition: background-color 0.4s;
font-family: motiva-sans, sans-serif;
}
.error-label-ct {
margin: 0px 0 16px;
}
.request-form .info-txt {
margin: 4px 0 0px;
font-size: 14px;
color: #62668c;
line-height: 16px;
}
#media screen and (min-width: 500px) {
.company-bttn-anim:first-child {
margin-bottom: 0.75rem;
}
}
.request-form h4.big {
font-size: 24px;
margin-bottom: 0;
}
.request-form h4.title {
font-size: 12px;
padding-bottom: 0;
margin-top: 0;
}
.request-form h4.by-submit {
font-size: 16px;
line-height: 24px;
font-weight: 600;
}
.request-form h4.by-submit a {
color: inherit;
font-weight: inherit;
}
.request-form .hidden-fields {
display: none;
}
.request-form .hidden-fields .input-ct {
margin: 20px 0;
}
.request-form .max-char {
display: block;
font-size: 14px;
color: #18216d;
}
.request-form .agent-group h4 {
padding-bottom: 0;
}
.request-form .clarification-txt {
display: block;
font-size: 14px;
padding-bottom: 15px;
}
.request-form .disclaimer a {
font-weight: 800;
}
.request-form .disclaimer a:hover {
text-decoration: underline;
}
.request-form .g-recaptcha {
margin: 45px 0 0px;
}
.request-form #submit-btn {
min-width: 165px;
height: 68px;
margin-top: 48px;
line-height: 68px;
padding: 0;
pointer-events: none;
opacity: 0.35;
}
.form-failure .light-blue {
margin-top: 50px;
}
.form-failure p,
.form-success p {
font-size: 18px;
margin: 20px auto 0;
}
.company-bttn-anim {
border: 0;
}
.hidden {
display: none;
}
#media screen and (max-width: 767px) {
.hero {
min-height: unset;
}
.request-form .email-ct {
margin-right: 0;
}
.request-form .phone-ct {
margin-left: 0;
}
}
.submit-ct {
margin: 32px 0 0;
}
#media screen and (min-width: 1200px) {
.form-ct {
margin-top: -24px;
}
.request-form .container {
padding: 0;
}
}
#media screen and (min-width: 991px) {
.request-form h3.sub-head {
text-align: center;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="request-form form-ct">
<form accept-charset="UTF-8" method="post" action="">
<input type="hidden" name="oid" value="">
<div class="utm-params-and-cta-id" style="display:none;">
<input type="hidden" name="utm_term" id="utm_term" value="<? if(isset($_GET['utm_term'])){echo $_GET['utm_term'];} ?>">
<input type="hidden" name="utm_content" id="utm_content" value="<? if(isset($_GET['utm_content'])){echo $_GET['utm_content'];} ?>">
<input type="hidden" name="utm_campaign" id="utm_campaign" value="<? if(isset($_GET['utm_campaign'])){echo $_GET['utm_campaign'];} ?>">
<input type="hidden" name="utm_source" id="utm_source" value="<? if(isset($_GET['utm_source'])){echo $_GET['utm_source'];} ?>">
<input type="hidden" name="utm_medium" id="utm_medium" value="<? if(isset($_GET['utm_medium'])){echo $_GET['utm_medium'];} ?>">
<input type="hidden" name="cta_id" id="cta_id" value="No cta_id set">
</div>
<div class="fandlname">
<div class="input-ct first-name-ct">
<label for="first_name">First name</label>
<input type="text" autocomplete="given-name" name="first_name" id="first_name" value="" class="text required" size="30" maxlength="32">
</div>
<div class="input-ct last-name-ct">
<label for="last_name">Last name</label>
<input type="text" autocomplete="family-name" name="last_name" id="last_name" value="" class="text required" size="30" maxlength="32">
</div>
</div>
<div class="input-ct">
<label for="email">Email address</label>
<input type="email" autocomplete="email" name="email" id="email" value="" class="text required email" size="30" maxlength="255">
</div>
<div class="input-ct">
<label for="phone">Phone</label>
<input type="tel" autocomplete="tel" name="phone" id="phone" value="" class="text required" size="30" maxlength="32">
</div>
<div class="input-ct">
<label for="company">Company</label>
<input type="text" autocomplete="organization" name="company" id="company" value="" class="text required" size="30" maxlength="100">
</div>
<div class="input-ct">
<label for="employees">Number of employees</label>
<input type="text" name="employees" id="employees" value="" class="text required" size="30" maxlength="8">
</div>
<div class="submit-ct">
<div>
<input type="submit" accesskey="s" id="jbx-submit" aria-hidden="Submit" value="Get started" class="company-bttn-anim company-btn--blue large light" name="submitBttn">
<img src="https://companyweb.imgix.net/icons/Arrow-Right-Hover-Animation_white-2021.svg" alt="right arrow icon" class="learn-more-arrow">
</div>
</div>
</form>
</div>
</div>
You have to handle this on input change event if the length of the input is greater than 0 apply the valid-ct class otherwise don't
$('input').keyup(function () {
if($(this).val().length > 0 ){
$(this).parent().addClass("valid-ct");
}else {
$(this).parent().removeClass("valid-ct");
}
});
I am trying to make a counter for submitting a form in php, if the data from the forms is sent to the server, +1 is written to the counter.txt file, this data is used to form the header in the letter. Everything works, but 5 identical letters come to the mail, the next time it sends 10 and so on. What is the problem? Why is this happening?
When I remove the counter code everything works fine and one letter arrives.
<?php
$email = ($_POST['sel']);
$change = ($_POST['button-set']);
$name = ($_POST['name']);
$question = ($_POST['message']);
$submit = ($_POST['submit']);
if (isset ($submit)) {
$count = file_get_contents ('counter.txt');
$count ++;
file_put_contents ('counter.txt', $count);
}
else {
$count = file_get_contents ('counter.txt');
};
$to = 'support#archsupport.ru';
$subject = 'Application number: ' . $count . 'from the site archsupport.ru';
$message = 'Name: ' . $name . "\r\n" . 'Contacts: ' . $email . "\r\n" . 'Write ' . $change . "\r\n" . 'Question: ' . $question ;
$headers = 'From: zergg52#gmail.com ' . "\r\n";
$subject = preg_replace("/(\r\n)|(\r)|(\n)/", "", $subject);
$subject = preg_replace("/(\t)/", " ", $subject);
$subject = '=?UTF-8?B?' . base64_encode($subject) . '?=';
#mail($to, $subject, $message, $headers);
echo 'message sent!';
var_dump($email,$change,$name,$question,$submit,$count)
?>
Page code:
var form = document.getElementsByTagName('form')[0];
var names = document.getElementById('name');
var validn = document.getElementById('vn');
var iconrequired = document.querySelector('#namereq');
var email = document.getElementById('sellection');
var valids = document.getElementById('vs');
var iconrequireds = document.querySelector('#sellectionreq');
var text = document.getElementById('qestions');
var validt = document.getElementById('vt');
var iconrequiredt = document.querySelector('#textreq');
document.addEventListener('input', function validation() {
var x = document.forms["support"]["sellection"].value;
if (names.validity.valid) {
validn.className = "valid";
iconrequired.className = "iconrequired hide";
};
if (email.validity.valid && x != "") {
valids.className = "valid";
iconrequireds.className = "iconrequired hide";
};
if (text.validity.valid) {
validt.className = "valid";
iconrequiredt.className = "iconrequired hide";
};
if (!names.validity.valid) {
validn.className = "invalid";
iconrequired.className = "iconrequired hide";
};
if (!email.validity.valid) {
valids.className = "invalid";
iconrequireds.className = "iconrequired hide";
};
if (!text.validity.valid) {
validt.className = "invalid";
iconrequiredt.className = "iconrequired hide";
};
if (names.validity.valid && email.validity.valid && text.validity.valid) {
$('#support').submit(function() {
$.post(
'https://www.archsupport.ru/post-email.php',
$("#support").serialize(),
function(msg) {
$('#support').hide('slow');
$('#message').html(msg);
}
);
});
} else {
return false;
}
});
function validateSellection() {
var x = document.forms["support"]["sellection"].value;
if (x === "") {
document.getElementById('sellectionreq').classList.remove("hide");
return false;
} else {
document.getElementById('sellectionreq').classList.add("hide");
return false;
}
};
function validateName() {
var x = document.forms["support"]["name"].value;
if (x === "") {
document.getElementById('namereq').classList.remove("hide");
return false;
} else {
document.getElementById('namereq').classList.add("hide");
return false;
}
};
function validateText() {
var x = document.forms["support"]["qestions"].value;
if (x === "") {
document.getElementById('textreq').classList.remove("hide");
return false;
} else {
document.getElementById('textreq').classList.add("hide");
return false;
}
};
$('#support').submit(function validate() {
if (validateName() && validateSellection() && validateText() === true) {
return false;
} else {
validateSellection();
validateName();
validateText()
return false
}
});
$(".radio").on('click.two', function() {
let input = $("#sellection");
if ($("#radio").prop("checked")) {
input.prop("disabled", false);
input.prop({
"type": "email",
"placeholder": "example#yourmail.ru",
"autocomplete": "email",
"maxlength": "35",
"minlength": "12",
"value": "",
});
document.getElementById("sellection").pattern = "^[a-z0-9._%+-]+#[a-z0-9.-]+\\.[a-z]{2,4}$";
} else {
input.prop("disabled", false);
$("#sellection").prop({
"type": "tel",
"placeholder": "+7-910-205-46-15",
"autocomplete": "tel",
"maxlength": "16",
"minlength": "11",
"value": "",
});
document.getElementById("sellection").pattern = "\\+7\\s?[\\(]{0,1}9[0-9]{2}[\\)]{0,1}\\s?\\d{3}[-]{0,1}\\d{2}[-]{0,1}\\d{2}";
}
input.focus();
input.val("");
});
var fab = $('.icons');
fab.on('click.ten', function iconback() {
fab.removeClass('checked');
$(this).addClass('checked');
});
#keyframes req {
0% {
transform: translatex(0px);
}
100% {
transform: translatex(5px);
}
}
#keyframes inv {
0% {
opacity: .5;
}
100% {
opacity: 1;
}
}
* {
padding: 0;
margin: 0;
}
:root {
font-family: "HelveticaNeueCyr";
font-weight: 100;
}
form {
font-size: 24px;
position: relative;
width: 100%;
display: inline-flex;
flex-direction: column;
}
textarea {
height: 30vh;
border-radius: 18px;
padding-left: 15px;
padding-top: 10px;
border: 2px solid #d7d7d7;
overflow: hidden;
overflow-y: scroll;
outline: none;
resize: none
}
input,
textarea {
font-family: "HelveticaNeueCyr";
font-weight: 100;
font-size: 18px;
}
::-webkit-input-placeholder {
color: gray;
font-size: 18px;
}
::-moz-placeholder {
color: gray;
font-size: 18px;
}
/* Firefox 19+ */
:-moz-placeholder {
color: gray;
font-size: 18px;
}
/* Firefox 18- */
:-ms-input-placeholder {
color: gray;
font-size: 18px;
}
input:not([type="submit"]) {
border-radius: 100px;
padding-left: 15px;
height: 36px;
border: none;
background: #f3f3f3;
}
input:focus {
outline: none;
border: 2px solid #f3f3f3;
box-sizing: border-box;
background: white;
padding-left: 13px;
}
.required {
display: inline-flex;
width: 100%;
flex-direction: column;
margin-bottom: 15px;
position: relative;
}
.iconrequired {
margin: auto;
display: flex;
align-items: center;
justify-content: center;
width: 90px;
height: 14px;
color: white;
border-radius: 100px;
font-size: 10px;
font-weight: 100;
font-family: "HelveticaNeueCyr";
background: #343434;
position: absolute;
right: 15px;
top: 10px;
opacity: 1;
transition: opacity ease-out 1s;
animation: .05s ease-in-out 0s 4 alternate req;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
transition: background-color 5000s ease-in-out 0s;
border: 2px solid #f3f3f3;
box-sizing: border-box;
padding-left: 13px;
}
div.button-set {
display: inline-flex;
}
div.button-set>label {
position: relative;
flex: 0 0 auto;
height: 50px;
width: 50px;
margin-left: 15px;
border-radius: 100px;
outline: none;
border: none;
margin-bottom: 20px;
}
.checked {
background: #f3f3f3;
border-radius: 100px;
}
input[type="submit"] {
font-family: "HelveticaNeueCyr";
height: 36px;
width: 160px;
font-weight: 100;
font-size: 24px;
margin-top: 20px;
margin-left: 10px;
border: none;
border-radius: 100px;
background: #f3f3f3;
padding: 0;
}
::-webkit-scrollbar {
position: absolute;
z-index: 9999;
width: 5px;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-track {
z-index: 9999;
background-color: transparent;
}
::-webkit-scrollbar-track-piece {
z-index: 9999;
z-index: 9999;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
z-index: 9999;
background-color: #d7d7d7;
border-radius: 3px;
}
::-webkit-scrollbar-corner {
z-index: 9999;
background-color: #d7d7d7;
}
.invalid {
width: 12px;
height: 12px;
color: white;
position: absolute;
right: 15px;
top: 12px;
background: tomato;
border-radius: 6px;
animation: 2s ease-in-out 0s infinite alternate inv;
}
.valid {
width: 12px;
height: 12px;
color: white;
position: absolute;
right: 15px;
top: 12px;
background: #9dc46b;
border-radius: 6px;
animation: 2s ease-in-out 0s infinite alternate inv;
}
.error {
text-align: right;
font-size: 12px;
padding-right: 20px;
padding-top: 10px;
color: gray;
letter-spacing: .05em;
}
.hide {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/css/form.css">
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<form novalidate action="" method="post" name="support" id="support">
<label class="required"><span id="vs" class="invalid hide"></span><input id="sellection" class="mail sellection" name="sel" vlaue="" placeholder="choose a communication way...." required disabled><span id="error1"></span><div id="sellectionreq" class="iconrequired hide">REQUIRED</div></label>
<div class="button-set">
<label title="Email"><img class="icons" src='/img/icon/social_icon_mail_white.svg'><input class="radio" id="radio" type="radio" name="button-set" value="to mail" style="display:none;"></label>
<label for="radio1" title="WhatsApp"><img class="icons" src='/img/icon/social_icon_whatsapp_white.svg'><input class="radio" id="radio1" type="radio" name="button-set" value="to WhatsApp" style="display:none;"></label>
<label for="radio2" title="Telegram"><img class="icons" src='/img/icon/social_icon_telegram_white.svg'><input class="radio" id="radio2" type="radio" name="button-set" value="to Telegram" style="display:none;"></label>
<label for="radio3" title="Viber"><img class="icons" src='/img/icon/social_icon_viber_white.svg'><input class="radio" id="radio3" type="radio" name="button-set" value="to Viber" style="display:none;"></label>
</div>
<label class="required"><span id="vn" class="invalid hide"></span>
<input id="name" class="mail" type="name" name="name" autocomplete= none placeholder="what's your name...." value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="15" minlength="2" required><div id="namereq" class="iconrequired hide">REQUIRED</div></label>
<label class="required"><span id="vt" class="invalid hide"></span><textarea id="qestions" type="text" placeholder="your question...." name="message" value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="400" minlength="4" required></textarea><div id="textreq" class="iconrequired hide">REQUIRED</div></label>
<input name="submit" type="submit" id="submit" value="SUBMIT" />
</form>
<div id="message"></div>
</body>
<script src="/js/form.js"></script>
</html>
without counter:
var_dump($email,$change,$name,$question,$submit) - string(12)
"+79102054615" string(11) "to WhatsApp" string(4) "ZERG" string(8)
"ANYTHING" NULL
with counter:
var_dump($email,$change,$name,$question,$submit,$count) - string(12)
"+79102054615" string(11) "to WhatsApp" string(4) "ZERG" string(8)
"ANYTHING" NULL string(1) "9"
$count immediately takes on value "9"
site with form: https://www.archsupport.ru/
In regards to the HTML/JavaScript, consider the following code.
$(function() {
var form = $("#support");
function checkFieldValidity(fObj) {
var r = false;
var re = new RegExp(fObj.attr("pattern"));
var v = fObj.val();
if (fObj.is("[required]")) {
if (v.length) {
fObj.next(".iconrequired").hide();
} else {
fObj.next(".iconrequired").show();
}
if (re.test(v)) {
fObj.prev(".icon").removeClass("invalid").addClass("valid");
r = true;
} else {
fObj.prev(".icon").removeClass("valid").addClass("invalid");
}
} else {
r = true;
}
return r;
}
$("input", form).blur(function() {
checkFieldValidity($(this));
});
form.submit(function(e) {
e.preventDefault();
var valid = true;
$("[required]", form).each(function(i, el) {
valid = valid && checkFieldValidity($(el));
});
return valid;
});
$(".button-set label", form).on('click', function() {
$(this).parent().find(".checked").removeClass("checked");
$("img", this).addClass("checked");
var input = $("#sellection");
input.prop("disabled", false);
switch ($(this).data("value")) {
case "email":
input.prop({
type: "email",
placeholder: "example#yourmail.com",
autocomplete: "email",
maxlength: 35,
minlength: 12,
value: "",
}).attr("pattern", "^[a-z0-9._%+-]+#[a-z0-9.-]+\\.[a-z]{2,4}$");
break;
// Add Cases for each selection option if needed
default:
input.prop({
"type": "tel",
"placeholder": "+7-910-205-46-15",
"autocomplete": "tel",
"maxlength": "16",
"minlength": "11",
"value": "",
});
input.attr("pattern", "\\+7\\s?[\\(]{0,1}9[0-9]{2}[\\)]{0,1}\\s?\\d{3}[-]{0,1}\\d{2}[-]{0,1}\\d{2}");
break;
}
input.focus();
input.val("");
});
});
#keyframes req {
0% {
transform: translatex(0px);
}
100% {
transform: translatex(5px);
}
}
#keyframes inv {
0% {
opacity: .5;
}
100% {
opacity: 1;
}
}
* {
padding: 0;
margin: 0;
}
:root {
font-family: "HelveticaNeueCyr";
font-weight: 100;
}
form {
font-size: 24px;
position: relative;
width: 100%;
display: inline-flex;
flex-direction: column;
}
textarea {
height: 30vh;
border-radius: 18px;
padding-left: 15px;
padding-top: 10px;
border: 2px solid #d7d7d7;
overflow: hidden;
overflow-y: scroll;
outline: none;
resize: none
}
input,
textarea {
font-family: "HelveticaNeueCyr";
font-weight: 100;
font-size: 18px;
}
::-webkit-input-placeholder {
color: gray;
font-size: 18px;
}
::-moz-placeholder {
color: gray;
font-size: 18px;
}
/* Firefox 19+ */
:-moz-placeholder {
color: gray;
font-size: 18px;
}
/* Firefox 18- */
:-ms-input-placeholder {
color: gray;
font-size: 18px;
}
input:not([type="submit"]) {
border-radius: 100px;
padding-left: 15px;
height: 36px;
border: none;
background: #f3f3f3;
}
input:focus {
outline: none;
border: 2px solid #f3f3f3;
box-sizing: border-box;
background: white;
padding-left: 13px;
}
.required {
display: inline-flex;
width: 100%;
flex-direction: column;
margin-bottom: 15px;
position: relative;
}
.iconrequired {
margin: auto;
display: flex;
align-items: center;
justify-content: center;
width: 90px;
height: 14px;
color: white;
border-radius: 100px;
font-size: 10px;
font-weight: 100;
font-family: "HelveticaNeueCyr";
background: #343434;
position: absolute;
right: 15px;
top: 10px;
opacity: 1;
transition: opacity ease-out 1s;
animation: .05s ease-in-out 0s 4 alternate req;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
transition: background-color 5000s ease-in-out 0s;
border: 2px solid #f3f3f3;
box-sizing: border-box;
padding-left: 13px;
}
div.button-set {
display: inline-flex;
}
div.button-set>label {
position: relative;
flex: 0 0 auto;
height: 50px;
width: 50px;
margin-left: 15px;
border-radius: 100px;
outline: none;
border: none;
margin-bottom: 20px;
}
.checked {
background: #f3f3f3;
border-radius: 100px;
}
input[type="submit"] {
font-family: "HelveticaNeueCyr";
height: 36px;
width: 160px;
font-weight: 100;
font-size: 24px;
margin-top: 20px;
margin-left: 10px;
border: none;
border-radius: 100px;
background: #f3f3f3;
padding: 0;
}
::-webkit-scrollbar {
position: absolute;
z-index: 9999;
width: 5px;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-track {
z-index: 9999;
background-color: transparent;
}
::-webkit-scrollbar-track-piece {
z-index: 9999;
z-index: 9999;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
z-index: 9999;
background-color: #d7d7d7;
border-radius: 3px;
}
::-webkit-scrollbar-corner {
z-index: 9999;
background-color: #d7d7d7;
}
.invalid {
width: 12px;
height: 12px;
color: white;
position: absolute;
right: 15px;
top: 12px;
background: tomato;
border-radius: 6px;
animation: 2s ease-in-out 0s infinite alternate inv;
}
.valid {
width: 12px;
height: 12px;
color: white;
position: absolute;
right: 15px;
top: 12px;
background: #9dc46b;
border-radius: 6px;
animation: 2s ease-in-out 0s infinite alternate inv;
}
.error {
text-align: right;
font-size: 12px;
padding-right: 20px;
padding-top: 10px;
color: gray;
letter-spacing: .05em;
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form novalidate action="" method="post" name="support" id="support">
<span class="icon"></span><input id="sellection" class="mail" name="f[sel]" value="" placeholder="Choose a communication method...." required disabled>
<div class="iconrequired hide">REQUIRED</div>
<div class="button-set">
<label title="Email" data-value="email"><img class="icon" src='/img/icon/social_icon_mail_white.svg'></label>
<label title="WhatsApp" data-value="whatsapp"><img class="icon" src='/img/icon/social_icon_whatsapp_white.svg'></label>
<label title="Telegram" data-value="telegram"><img class="icon" src='/img/icon/social_icon_telegram_white.svg'></label>
<label title="Viber" data-value="viber"><img class="icon" src='/img/icon/social_icon_viber_white.svg'></label>
</div>
<label class="required"><span class="icon"></span>
<input id="name" class="mail" type="name" name="f[name]" autocomplete="none" placeholder="what's your name...." value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="15" minlength="2" required><div id="namereq" class="iconrequired hide">REQUIRED</div></label>
<label class="required"><span id="vt" class="invalid hide"></span><textarea id="qestions" type="text" placeholder="your question...." name="f[message]" value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="400" minlength="45" required></textarea><div id="textreq" class="iconrequired hide">REQUIRED</div></label>
<input name="f[submit]" type="submit" id="submit" value="SUBMIT" />
</form>
<div id="message"></div>
You want to evaluate if each field that is required has content and matches a specific pattern. I think your approach was too complicated. Additionally, I would stick with all native JavaScript or all jQuery. Don't mix them.
For submit, you will want to test each field and keep a running tally. To do this, you can logically start with a true value and as you test, keep logically evaluating. Example:
var result = true;
result = result && true; // result is true
result = result && false; // result is false
result = result && true; // result is false
If some of the fields validate and if any do not, the result will be false and the form should not submit. If all validate, the result will be true and it's safe to submit the data to PHP. This should also prevent multiple submissions.
Remember that this is Client Side validation and can be bypassed by posting the data manually to the PHP. Most users will not even bother, yet all it takes is one curious or malicious User or Bot to see that they can bypass the form and create their own HTTP Post Payload. So you will want to ensure that your PHP is protected from such actions. Test any data submitted by the User before using it in your PHP Code. For example, you define $name like so:
$name = ($_POST['name']);
If I construct a payload like:
&name=;include "/etc/passwd";
This might get evaluated in the following code:
$message = 'Name: ' . $name . "\r\n" . 'Contacts: ' . $email . "\r\n" . 'Write ' . $change . "\r\n" . 'Question: ' . $question;
Just some things to consider.
I am a stuck on following issues:
How to add required error just once after first click on submit button? And not at any subsequent click after.
How can to start function (checkValid()) with RegExp validation only after first function (checkRequired()) implementation with required checking?
How to show every error after RegExp validation in its relative element? Now all errors are displayed in the last block with phone input.
Here is case on jsfiddle:
https://jsfiddle.net/SanchezMalina/hno7v4tf/35/
Or code here:
// regexp pattern functions
function validateEmail(email) {
let 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(email.toLowerCase());
}
function validatePhone(phone) {
let re = /^[0-9]{7,20}$/;
return re.test(phone.toLowerCase());
}
function validateName(name) {
let re = /^([a-zA-Z0-9А]){3,50}$/;
return re.test(name.toLowerCase());
}
let flag = false;
// check required fields
function checkRequired() {
let notFilled = document.querySelectorAll('.is-required');
notFilled.forEach(function (el) {
if (el.value === '') {
el.parentElement.classList.add('is-empty');
addRequiredError();
} else {
el.parentElement.classList.remove('is-empty');
removeRequiredError();
}
});
}
let formFields = document.querySelectorAll('.form__field');
//add required error message
function addRequiredError() {
let errorRequiredMsg = document.createElement('div');
errorRequiredMsg.classList.add('input-required');
errorRequiredMsg.innerHTML = `<span> This field is required! </span>`;
formFields.forEach( function (elem) {
if (elem.classList.contains('is-empty')) {
elem.appendChild(errorRequiredMsg);
}
});
}
//remove required error message
function removeRequiredError() {
let requiredErrorMsg = document.querySelectorAll('.form__field .input-required');
requiredErrorMsg.forEach(function (elem) {
elem.parentElement.removeChild(elem);
});
flag = true;
}
//check validation inputs
function checkValid() {
let firstName = document.querySelector('#f-name');
let lastName = document.querySelector('#l-name');
let selectCountry = document.querySelector('.form__select');
let phone = document.querySelector('#cell');
let email = document.querySelector('#email');
formFields.forEach(function () {
if(!validateName(firstName.value) && !validateName(lastName.value) && !validatePhone(phone.value) && !validateEmail(email.value)) {
firstName.parentElement.classList.add('is-error');
lastName.parentElement.classList.add('is-error');
selectCountry.parentElement.classList.add('is-error');
phone.parentElement.classList.add('is-error');
email.parentElement.classList.add('is-error');
addValidError();
} else {
firstName.parentElement.classList.remove('is-error');
lastName.parentElement.classList.remove('is-error');
selectCountry.parentElement.classList.remove('is-error');
phone.parentElement.classList.remove('is-error');
email.parentElement.classList.remove('is-error');
removeValidError();
}
});
}
//add invalid error message
function addValidError() {
let errorValidMsg = document.createElement('div');
errorValidMsg.classList.add('input-error');
errorValidMsg.innerHTML = `<span> Input is invalid! </span>`;
formFields.forEach(function (elem) {
if (elem.classList.contains('is-error')) {
elem.appendChild(errorValidMsg);
}
});
// for (let i = 0; i < formFields.length; i++) {
//
// if (formFields[i].classList.contains('is-error')) {
//
// formFields[i].appendChild(errorValidMsg);
//
// }
// }
}
//remove invalid error message
function removeValidError() {
let requiredErrorMsg = document.querySelectorAll('.input-error');
requiredErrorMsg.forEach(function (elem) {
elem.parentNode.removeChild(elem);
})
}
//form submit handler
let formTrial = document.querySelector('.form__main');
formTrial.addEventListener('submit', function (event) {
event.preventDefault();
checkRequired();
console.log(flag);
if(flag !== false) {
checkValid();
}
});
.form__main {
display: block;
margin: 25px auto;
width: 450px;
}
.form__field {
position: relative;
margin: 10px 0;
padding: 5px 15px;
background-color: #fff;
height: 50px;
}
.form__field_select::after {
content: "";
width: 0;
height: 0;
border: 7px solid transparent;
border-color: #000 transparent transparent transparent;
position: absolute;
top: 55%;
right: 17px;
transform: translateY(-50%);
}
.form__input {
position: absolute;
left: 0;
top: 10px;
right: 0;
bottom: 10px;
padding-left: 45px;
background: none;
font-size: 14px;
font-weight: 400;
font-family: "Open Sans", sans-serif;
width: 100%;
color: #333;
line-height: 1.714;
box-sizing: border-box;
}
.form__input:focus ~ .form__label,
.form__input:valid ~ .form__label {
top: 0;
left: 45px;
transform: scale(0.6, 0.6);
color: #000;
}
.form__input:focus ~ .form__label[for=cell],
.form__input:valid ~ .form__label[for=cell] {
top: 0;
left: 125px;
}
.form__input[type=tel] {
padding-left: 125px;
}
.form__input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 100px white inset;
}
.form__label {
position: absolute;
top: 50%;
left: 50px;
transform-origin: left top;
transition: all 0.3s ease;
transform: translateY(-50%);
font-size: 14px;
font-family: "Open Sans", sans-serif;
color: #999999;
line-height: 1.714;
}
.form__label[for=cell] {
left: 135px;
}
.form__select {
position: absolute;
width: 100%;
height: 100%;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
padding-left: 50px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-appearance: none;
-moz-appearance: none;
background-color: transparent;
border-color: #fff;
font-size: 14px;
font-family: "Open Sans", sans-serif;
color: #000;
line-height: 1.714;
}
.form__country-code {
position: absolute;
color: #000;
left: 50px;
font-size: 14px;
font-family: "Open Sans", sans-serif;
line-height: 2;
height: 100%;
top: 0;
bottom: 0;
display: flex;
align-items: center;
border-right: 1px solid;
padding-right: 20px;
z-index: 2;
}
.form .btn {
width: 100%;
margin: 20px 0;
}
.form .btn:hover {
transform: translateY(-5px);
box-shadow: 1px 3px 20px #c5f833;
}
<form method="post" class="form__main" novalidate>
<div class="form__field">
<i class="icon icon-user"></i>
<input class="form__input is-required" id="f-name" type="text" required>
<label class="form__label" for="f-name">First Name</label>
</div>
<div class="form__field">
<i class="icon icon-user"></i>
<input class="form__input is-required" id="l-name" type="text" required>
<label class="form__label" for="l-name">Last Name</label>
</div>
<div class="form__field">
<i class="icon icon-envelop"></i>
<input class="form__input" id="email" type="text" required>
<label class="form__label" for="email">Email</label>
</div>
<div class="form__field form__field_select">
<i class="icon icon-pin"></i>
<select class="form__select" name="country">
<option value="ro" selected>USA</option>
<option value="ua">India</option>
<option value="il">Spain</option>
</select>
</div>
<div class="form__field">
<i class="icon icon-phone"></i>
<span class="form__country-code">+10000</span>
<input class="form__input" id="cell" type="tel" required>
<label class="form__label" for="cell">Phone</label>
</div>
<button class="btn btn_lime">Try for free</button>
</form>
1)
if( !el.parentElement.classList.contains('is-empty') ) {
addRequiredError();
}
2)
not sure to understand the question
3)
function addValidError() {
let errorValidMsg = document.createElement('div');
errorValidMsg.classList.add('input-error');
errorValidMsg.innerHTML = '<span> Input is invalid! </span>';
formFields.forEach(function (elem) { // <-- here formFields is not defined
}