This question already has an answer here:
Comments not working in jinja2
(1 answer)
Closed 2 years ago.
I've created a basic python flask site. I'm working on a signup page where I need to perform password complexity requirement checks. I figured the best way to do this might be with javascript on the client side instead of having to deal with Python code to handle this. I've created a signup.html page and a route within my python code but the page just loads as a blank white screen. Please help!
Here's my HTML signup page:
<!DOCTYPE html>
<!-- {% extends "base.html" %} -->
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
/* Style all input fields */
input {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
}
/* Style the submit button */
input[type=submit] {
background-color: #4CAF50;
color: white;
}
/* Style the container for inputs */
.container {
background-color: #f1f1f1;
padding: 20px;
}
/* The message box is shown when the user clicks on the password field */
#message {
display:none;
background: #f1f1f1;
color: #000;
position: relative;
padding: 20px;
margin-top: 10px;
}
#message p {
padding: 10px 35px;
font-size: 18px;
}
/* Add a green text color and a checkmark when the requirements are right */
.valid {
color: green;
}
.valid:before {
position: relative;
left: -35px;
content: "✔";
}
/* Add a red text color and an "x" when the requirements are wrong */
.invalid {
color: red;
}
.invalid:before {
position: relative;
left: -35px;
content: "✖";
}
</style>
</head>
<body>
<h3>Password Validation</h3>
<p>Try to submit the form.</p>
<div class="container">
<form action="/action_page.php">
<label for="usrname">Username</label>
<input type="text" id="usrname" name="usrname" required>
<label for="psw">Password</label>
<input type="password" id="psw" name="psw" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" title="Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters" required>
<input type="submit" value="Submit">
</form>
</div>
<div id="message">
<h3>Password must contain the following:</h3>
<p id="letter" class="invalid">A <b>lowercase</b> letter</p>
<p id="capital" class="invalid">A <b>capital (uppercase)</b> letter</p>
<p id="number" class="invalid">A <b>number</b></p>
<p id="length" class="invalid">Minimum <b>8 characters</b></p>
</div>
<script>
var myInput = document.getElementById("psw");
var letter = document.getElementById("letter");
var capital = document.getElementById("capital");
var number = document.getElementById("number");
var length = document.getElementById("length");
// When the user clicks on the password field, show the message box
myInput.onfocus = function() {
document.getElementById("message").style.display = "block";
}
// When the user clicks outside of the password field, hide the message box
myInput.onblur = function() {
document.getElementById("message").style.display = "none";
}
// When the user starts to type something inside the password field
myInput.onkeyup = function() {
// Validate lowercase letters
var lowerCaseLetters = /[a-z]/g;
if(myInput.value.match(lowerCaseLetters)) {
letter.classList.remove("invalid");
letter.classList.add("valid");
} else {
letter.classList.remove("valid");
letter.classList.add("invalid");
}
// Validate capital letters
var upperCaseLetters = /[A-Z]/g;
if(myInput.value.match(upperCaseLetters)) {
capital.classList.remove("invalid");
capital.classList.add("valid");
} else {
capital.classList.remove("valid");
capital.classList.add("invalid");
}
// Validate numbers
var numbers = /[0-9]/g;
if(myInput.value.match(numbers)) {
number.classList.remove("invalid");
number.classList.add("valid");
} else {
number.classList.remove("valid");
number.classList.add("invalid");
}
// Validate length
if(myInput.value.length >= 8) {
length.classList.remove("invalid");
length.classList.add("valid");
} else {
length.classList.remove("valid");
length.classList.add("invalid");
}
}
</script>
</body>
</html>
Here's my signup page python code:
#auth.route('/signup')
def signup():
return render_template('signup.html')
#auth.route('/signup', methods=['POST'])
def signup_post():
email = request.form.get('email')
name = request.form.get('name')
password = request.form.get('password')
# if re.match(r"^(?=.*[\d])(?=.*[A-Z])(?=.*[a-z])(?=.*[##$])[\w\d##$]{6,12}$", password):
user = User.query.filter_by(email=email).first() # check to see if user already exists
if user: # if a user is found, we want to redirect back to signup page so user can try again
flash('email address already exists')
return redirect(url_for('auth.signup'))
new_user = User(email=email, name=name, password=generate_password_hash(password, method='sha256'))
# add the new user to the database
db.session.add(new_user)
db.session.commit()
return redirect(url_for('auth.login'))
Few point to remember
Your signup.html must be inside templates directory
You can't <!-- {% extends "base.html" %} --> comment jinja template syntax like this, you can use like {# extends "base.html" #} this to ignore or remove the dead codes.
Related
I made a contact form with JavaScript validation but the validation function does not work. Although it does not show any errors in the console. The submit funtion itself does work and shows an alert box when you submit the form.
The validation function adds a CSS error class and then should show the error message, the error border and the erros symbol. When I add the error class manually to the HTML file the erros signs do show. But with the funtcion it does not.
I think maybe it has to do something with the way how I add the function to the form. But I checked everything and it just seems to look fine.
Who knows what is going wrong?
Some help would be very much appreciated! Thanks in advance!
var firebaseConfig = {
apiKey: " /* anominzed by editor */ ",
authDomain: " /* anominzed by editor */ ",
databaseURL: " /* anominzed by editor */ ",
projectId: " /* anominzed by editor */ ",
storageBucket: " /* anominzed by editor */ ",
messagingSenderId: " /* anominzed by editor */ ",
appId: " /* anominzed by editor */ ",
measurementId: " /* anominzed by editor */ "
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
//Reference contactInfo collections
let contactInfo = firebase.database().ref("infos");
// Listen for a submit
document.querySelector(".contactForm").addEventListener("submit",
submitForm);
function submitForm(e) {
e.preventDefault();
checkInputs(); //val
//Get input values
let name = document.querySelector(".name").value;
let email = document.querySelector(".email").value;
let message = document.querySelector(".message").value;
console.log(name, email, message);
saveContactInfo(name, email, message);
//Refresh after submit
document.querySelector(".contactForm").reset();
//Call send email function
sendEmail(name, email, message);
}
const form = document.getElementById('form'); //Val
const namecontact = document.getElementById('namecontact'); //Val
const email = document.getElementById('email'); //Val
const message = document.getElementById('message'); //Val
//form validaton
function checkInputs() {
//Get the values from the inputs
const nameValue = namecontact.value.trim();
const emailValue = email.value.trim();
const messageValue = message.value.trim();
if (nameValue === '') {
setErrorFor(namecontact, "Name cannot be blank");
}
if (emailValue === '') {
setErrorFor(email, "Email cannot be blank");
} else if (!isEmail(emailValue)) {
setErrorFor(email, 'Email is not valid')
}
if (messageValue === '') {
setErrorFor(message, "Message cannot be blank");
}
}
function setErrorFor(input, errorMessage) {
const formControl = input.parentElement; //.form-control
const small = formControl.getElementsByClassName('small');
small.forEach(element => {
small.innerText = errorMessage;
})
//add error message inside small
// add error class
formControl.className = 'form-control error';
}
function isEmail(email) {
return /^(([^<>()\[\]\\.,;:\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,}))$/.test(email);
}
//Save infos to Firebase
function saveContactInfo(name, email, message) {
let newContactInfo = contactInfo.push();
newContactInfo.set({
contactname: name,
email: email,
message: message,
});
}
function showSucces() {
alert("succesfully sent")
}
//Send Email function
function sendEmail(name, email, message) {
Email.send({
Host: "smtp.gmail.com",
Username: "liaraskara#gmail.com",
To: "liaraskara#gmail.com",
From: "liaraskara#gmail.com",
Subject: `${name} sent you a message`,
Body: `Name: ${name} <br/> Email: ${email} <br/> Message: ${message}`,
}).then((message) => showSucces());
}
/* master styles */
html {
height: 100%;
}
.contactForm {
flex: 0%;
margin: 0px 0px;
width: 21%;
position: absolute;
margin: 90px 0px 0px 10.5px;
left: 0px;
/* max-width: 100%; */
/* opacity: 0.39; */
}
.name,
.email,
.subject {
position: relative;
width: 279px;
height: 45px;
padding: 9px 15px 15px 15px;
margin-left: 39.9px;
font-size: 12px;
}
.message {
position: relative;
width: 279px;
height: 141px;
padding: 9px 15px 15px 15px;
margin-left: 39.9px;
font-size: 12px;
}
::placeholder {
margin-top: 0px;
font-size: 12px;
}
.fas.fa-exclamation-circle {
color: red;
width: 15px;
height: 15px;
position: absolute;
visibility: hidden;
top: 15px;
right: 60px;
}
.form-control {
position: relative;
}
.form-control.error input {
border-color: red;
}
.form-control.error i.fas.fas.fa-exclamation-circle {
visibility: visible;
color: red;
}
.form-control.error small {
color: red;
visibility: visible;
}
small {
position: absolute;
left: 66px;
visibility: hidden;
top: 27px;
}
#submitButton {
margin: 9px 0px 0px 42px;
width: 277.2px;
height: 63px;
}
<html lang="en" id="html">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Liara Skara</title>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="stylesheet" href="styles.css">
<!-- <script src='https://kit.fontawesome.com/a076d05399.js'></script> -->
</head>
<body id="bodyContactpage">
<form method="POST" class="contactForm" id="form">
<!-- <div class="backgroundImg" style="background-image: url('Images/LiaraEyesOpen.png');"> -->
<div class="form-control">
<input class="name" id="namecontact" type="text" placeholder="Name" required/><br>
<i class="fas fa-exclamation-circle" id="exclamation1"></i>
<small class="small" id="small1">Error mesagge</small>
</div>
<div class="form-control">
<input class="email" id="email" type="email" placeholder="E-mail" required/><br>
<i class="fas fa-exclamation-circle" id="exclamation2"></i>
<small class="small" id="small2">Error mesagge</small>
</div>
<div class="form-control">
<input class="subject" type="text" placeholder="Subject" /><br>
<i class="fas fa-exclamation-circle" id="exclamation3"></i>
<small class="small" id="small3">Error mesagge</small>
</div>
<div class="form-control">
<textarea class="message" id="message" name="" id="" cols="30" rows="10" placeholder="Message" required></textarea><br>
<i class="fas fa-exclamation-circle" id="exclamation4"></i>
<small class="small" id="small4">Error mesagge</small>
</div>
<button id="submitButton" type="submit">
<span>Launch</span>
<svg class="checkmark" viewBox="0 0 52 52">
<path fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>
</button>
</form>
<script src="https://smtpjs.com/v3/smtp.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.7/firebase.js"></script>
<script src="myscript.js">
</script>
</body>
</html>
There are couple of errors in setErrorFor function.
The JavaScript function getElementsByClassName return a
HTMLCollection.
Try converting it to an Array using Array.from(HTMLCollection),
i.e, Array.from(formControl) in your case.
While looping through the Array(formControl) using forEach
function below:
small.forEach(element => { small.innerText = errorMessage; })
you should refer to element and not small. It should be
element.innerText. You also need to set the visibility property for the element with class = 'small'
from hidden to visible.
I had to comment out all the firebase stuff to get your code to run: it was failing to initialise without a complete config, and throwing an error that prevented all the rest of your code from running.
Once I had done that, I found an error in your setErrorFor function:
small.forEach is not a function
This is because getElementsByClassName (and also querySelectorAll) does not return an array, but a HTMLCollection. This doesn't have map or forEach methods.
Instead, you can use:
for (const el of small) {
el.innerText = errorMessage
}
In general, however, my advice would be to add descriptive logging to your code, so you can follow exactly what is happening. You may also wish to enable "Preserve/persist logs" in your browser devtools settings, in case the logs are being cleared by an unexpected page reload.
Thanks for your help! I have solved it and it is working now, by taking the function out of the other submit function. And I changed the setErrorFor function to this;
function setErrorFor(input, errorMessage) {
const formControl = input.parentElement; //.form-control
const small = formControl.querySelector('small');
//add error message inside small
small.innerText = errorMessage;
// add error class
formControl.className = 'form-control error';
}
I really need help with this if you can please help me out.
I will try to explain as simple as possible. Sorry for any English mistake I make.
First I have a blog page about an interior style with data like title, thumbnail and link
<h1 id="blog-title">Scandinavian style</h1>
<img id="blog-thumbnail">
blog url
Then on that blog page I have a button "get-consult-btn"
< button id="get-consult-btn"> Get consult with this style </ button>
When I click the button, it will go to a form page with 7 questions to choose. I need:
display title, thumbnail and link of the previous blog page on question 1 page as a reference interior style
when customer complete the form and submit it, I will get the data of that title, thumbnail and link along with the info customer filled in the form.
< form id="myForm">
< div class="tab">Question 1 + title, thumbnail and link here </ div>
< div class="tab">Question 2</ div>
< div class="tab">Question 3</ div>
< div class="tab">Question 4</ div>
< div class="tab">Question 5</div>
< div class="tab">Question 6</ div>
<div class="tab">Question 7</ div>
</ form>
Our website for some strange reason doesn't accept PHP, and I have limited knowledge of jquery or javascript so if you can please help me out.
Actually, you'll be happy to know that it will work without PHP! Instead of actually redirecting the user to different pages, you can create a multi step form, with all the pages in the same page. For example
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
<style>
* {
box-sizing: border-box;
}
body {
background-color: #f1f1f1;
}
#regForm {
background-color: #ffffff;
margin: 100px auto;
font-family: Raleway;
padding: 40px;
width: 70%;
min-width: 300px;
}
h1 {
text-align: center;
}
input {
padding: 10px;
width: 100%;
font-size: 17px;
font-family: Raleway;
border: 1px solid #aaaaaa;
}
/* Mark input boxes that gets an error on validation: */
input.invalid {
background-color: #ffdddd;
}
/* Hide all steps by default: */
.tab {
display: none;
}
button {
background-color: #04AA6D;
color: #ffffff;
border: none;
padding: 10px 20px;
font-size: 17px;
font-family: Raleway;
cursor: pointer;
}
button:hover {
opacity: 0.8;
}
#prevBtn {
background-color: #bbbbbb;
}
/* Make circles that indicate the steps of the form: */
.step {
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbbbbb;
border: none;
border-radius: 50%;
display: inline-block;
opacity: 0.5;
}
.step.active {
opacity: 1;
}
/* Mark the steps that are finished and valid: */
.step.finish {
background-color: #04AA6D;
}
</style>
<body>
<form id="regForm" action="/action_page.php">
<h1>Register:</h1>
<!-- One "tab" for each step in the form: -->
<div class="tab">Name:
<p><input placeholder="First name..." oninput="this.className = ''" name="fname"></p>
<p><input placeholder="Last name..." oninput="this.className = ''" name="lname"></p>
</div>
<div class="tab">Contact Info:
<p><input placeholder="E-mail..." oninput="this.className = ''" name="email"></p>
<p><input placeholder="Phone..." oninput="this.className = ''" name="phone"></p>
</div>
<div class="tab">Birthday:
<p><input placeholder="dd" oninput="this.className = ''" name="dd"></p>
<p><input placeholder="mm" oninput="this.className = ''" name="nn"></p>
<p><input placeholder="yyyy" oninput="this.className = ''" name="yyyy"></p>
</div>
<div class="tab">Login Info:
<p><input placeholder="Username..." oninput="this.className = ''" name="uname"></p>
<p><input placeholder="Password..." oninput="this.className = ''" name="pword" type="password"></p>
</div>
<div style="overflow:auto;">
<div style="float:right;">
<button type="button" id="prevBtn" onclick="nextPrev(-1)">Previous</button>
<button type="button" id="nextBtn" onclick="nextPrev(1)">Next</button>
</div>
</div>
<!-- Circles which indicates the steps of the form: -->
<div style="text-align:center;margin-top:40px;">
<span class="step"></span>
<span class="step"></span>
<span class="step"></span>
<span class="step"></span>
</div>
</form>
<script>
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the current tab
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("tab");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == (x.length - 1)) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("tab");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("regForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("step");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
</script>
</body>
</html>
There you go! Now you have a full fletched form with everything you need. Just edit it according to your needs. By the way, though I fixed this problem of yours, I am curious how you will proceed with this data and actually utilize it if you don't have PHP. Anyway, code took long time to write. Up vote is appreciated :D
This question already has answers here:
JavaScript code to stop form submission
(14 answers)
Closed 2 years ago.
I'm trying to create a form that when submitted, creates a new object with the input values, and then stores that object in an array.
For some reason, the array is "resetting" and not saving the objects.
let myLibrary = []
function Book(title,author,pages,read) {
this.title = title
this.author = author
this.pages = pages
this.read = read
myLibrary.push(this)
}
function checkForm(){
let name = document.querySelector('input[name="title"]').value
let author = document.querySelector('input[name="author"]').value
let pages = document.querySelector('input[name="pages"]').value
let read = document.querySelector('input[name="read"]').checked
new Book(name,author,pages,read)
document.getElementById('library').innerText = JSON.stringify(myLibrary)
}
const submit = document.getElementById('btn1')
submit.addEventListener("click",checkForm);
<input name='title' />
<input name='author' />
<input name='pages' />
<input name='read' />
<button id='btn1'>Click me! </button>
<div >Library:</div>
<div id='library'></div>
You are listening for a click event on the submit button, however the submit button also submits the form. Forms will naturally cause a refresh if the default "submit" event is not prevented.
Instead you could listen to your forms submit event and prevent it:
// Query select the form and
form.addEventListener('submit', function(e){
e.preventDefault();
checkForm();
});
As you have a form in your html, you'll have to prevent its default submission event which results in a reload of the page with preventDefault(). You could, for example, change your checkForm() and add the e.preventDefault() there to prevent the form from being submitted.
let myLibrary = []
function Book(title, author, pages, read) {
this.title = title
this.author = author
this.pages = pages
this.read = read
}
function addtoLibrary(title, author, pages, read) {
let book = new Book(title, author, pages, read)
myLibrary.push(book)
}
let table = document.querySelector(".table");
myLibrary.forEach(function(e) {
table.innerHTML += `<tr><td>${e.title}</td>
<td>${e.author}</td>
<td>${e.pages}</td>
<td>${e.read}</td>
</tr>
`
});
// Selectors
let add = document.querySelector("#add")
let submit = document.querySelector("#submit")
function checkForm(e) {
e.preventDefault(); // prevent the form from being submitted
let name = document.querySelector('input[name="title"]').value
let author = document.querySelector('input[name="author"]').value
let pages = document.querySelector('input[name="pages"]').value
let read = document.querySelector('input[name="read"]').checked
addtoLibrary(name, author, pages, read)
console.log(myLibrary);
}
submit.addEventListener("click", checkForm);
html,
body {
height: 100%;
}
* {
font-family: Graphik Regular;
}
ul {
list-style-type: none;
}
table,
th,
td {
border-collapse: collapse;
text-align: left;
border: 1px solid black;
}
table {
width: 100%;
}
td,
th {
height: 50px;
padding: 10px;
width: 200px;
min-width: 100px;
}
th {
background-color: gray;
margin-bottom: 50px;
}
.headers {
margin-bottom: 5px;
}
button {
background-color: #4CAF50;
/* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin-top: 30px;
}
.pop-container {
text-align: center;
/* display: none;*/
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
}
form {
background-color: gray;
}
input {
font-size: 20px;
width: 300px;
margin-bottom: 5px;
}
<!DOCTYPE html>
<meta charset="UTF-8">
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</stylesheet>
<script type="text/javascript" src="http://livejs.com/live.js"></script>
</head>
<body>
<div class="pop-container">
<form id="bookquery">
<input type="text" name="title" id="title" placeholder="Title"></br>
<input type="text" name="author" placeholder="Author"></br>
<input type="text" name="pages" placeholder="Pages"></br>
<p>Have you read it?<input type="checkbox" placeholder="Title" name="read"></p>
</br>
<button id="submit">Submit</button>
</form>
</div>
<table class="headers">
<th>Title</th>
<th>Author</th>
<th>Pages</th>
<th>Read</th>
</table>
<table class="table tstyle">
</table>
<button id="add">Add new book</button>
<script src="script.js"></script>
</body>
</html>
function checkForm(e) {
e.preventDefault(); // prevent the form from being submitted
let name = document.querySelector('input[name="title"]').value
let author = document.querySelector('input[name="author"]').value
let pages = document.querySelector('input[name="pages"]').value
let read = document.querySelector('input[name="read"]').checked
addtoLibrary(name, author, pages, read)
}
The above answers didn't quite work for me so here is a simplified, fully working example. As a general guide to getting things like this to work I always try to simplify as much as possible.
index.html
<html>
<header></header>
<body>
<div>
<form id="myForm">
<label for="title">title:</label><br>
<input type="text" id="title" name="title" value="title"><br>
<button id="submit">Submit</button>
</form>
</div>
<script type="text/javascript" src="functions.js"></script>
</body>
</html>
functions.html
let myLibrary = [];
function Book(title) {
this.title = title;
myLibrary.push(this);
}
function checkForm(){
let title = document.querySelector('input[name="title"]').value;
new Book(title);
myLibrary.forEach(function(element) {
console.log(element);
});
}
document.getElementById("myForm").addEventListener(
'submit',
function(e) {
e.preventDefault();
checkForm();
}
);
I'll leave it to you to add back in the other fields on the Book object.
I am not sure because I've tried to illustrate that your code actually stores the object. It's either that your form refreshes the page... that might be the cause but as far as the code you've provided is concerned, everything works as expected.
let myLibrary = []
function Book(title,author,pages,read) {
this.title = title
this.author = author
this.pages = pages
this.read = read
myLibrary.push(this)
}
function checkForm(name,author,pages,read)
{
new Book(name,author,pages,read)
}
checkForm("Chris","Jerry","56","65");
checkForm("Sean","John","56","65");
// Both Objects are still stored...
console.log(myLibrary);
I am using a JavaScript function to check if caps lock is on and on the console window I get "Uncaught TypeError: Cannot read property 'addEventListener' of null
at login.js:41"
In google chrome's console window I also get an error
"The key "intial-scale" is not recognized and ignored"
I tried searching for the causes of this problem and I saw people saying that this may be because the function is executed before the DOM runs so I tried adding window.onload before the function but it didn't fix the issue.
// array of objects to store adminstrators data
var usersObj =[
{
username: "karim",
password: "karim2019"
},
{
username: "nourhan",
password: "noura2019"
},
{
username: "nariman",
password: "nariman2019"
}
]
// function to authenticate login information and proceed to the next page
function getLoginInfo()
{
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
for(i = 0; i < usersObj.length; i++)
{
if(username == usersObj[i].username && password == usersObj[i].password)
{
alert("Login successful..");
document.getElementById("loginf").action = "dashboard.html";
return
}
}
alert("Username or password is incorrect!");
document.getElementById("loginf").action = "login.htm";
}
var input = document.getElementById("password");
var text = document.getElementById("text");
input.addEventListener("keyup", window.onload=function(event)
{
if (event.getModifierState("CapsLock"))
{
text.style.visibility = "visible";
}
else
{
text.style.visibility = "hidden"
}
});
.row {
margin-top: 5%;
}
/* Bordered form */
form {
margin-top: 20%;
}
/* Full-width inputs */
input[type=text], input[type=password] {
width: 100%;
padding: 1% 2%;
margin: 1%;
display: inline-block;
border: 1px solid black;
box-sizing: border-box;
}
p{
display: none;
}
/* Set a style for all buttons */
button {
background-color: #4CAF50;
color: white;
padding: 1% 2%;
margin: 1%;
border: none;
cursor: pointer;
width: 100%;
}
/* Add a hover effect for buttons */
button:hover {
opacity: 0.8;
}
/* Add padding to containers */
.container {
padding: 1.5%;
}
/* The "Forgot password" text */
span.psw {
float: right;
padding-top: 1.5%;
}
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, intial-scale=1 maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="loginstyles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="login.js"></script>
<body>
<div class="row">
<div class="col"></div>
<div class="col">
<form id = "loginf" name="loginf" method="POST">
<div>
<h1>Account Login</h1>
</div>
<div><hr></div>
<div class="container">
<label for="username"><b>Username</b></label>
<input id="username" type="text" placeholder="Enter Username" name="username" required>
<label for="password"><b>Password</b></label>
<input id="password" type="password" placeholder="Enter Password" name="password" required>
<p id="text">WARNING!Caps Lock is ON.</p>
<label>
<input type="checkbox" checked="checked" name="remember">Remember me
</label>
<span class="psw">Forgot Password?</span>
<button onclick="getLoginInfo()" type="submit">Login</button>
</div>
</form>
</div>
<div class="col"></div>
</div>
</body>
</html>
I have fixed the issue by wrapping the eventlistener inside a function that runs when the window loads
// array of objects to store adminstrators data
var usersObj =[
{
username: "karim",
password: "karim2019"
},
{
username: "nourhan",
password: "noura2019"
},
{
username: "nariman",
password: "nariman2019"
}
]
// function to authenticate login information and proceed to the next page
function getLoginInfo()
{
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
for(i = 0; i < usersObj.length; i++)
{
if(username == usersObj[i].username && password == usersObj[i].password)
{
alert("Login successful..");
document.getElementById("loginf").action = "dashboard.html";
return
}
}
alert("Username or password is incorrect!");
document.getElementById("loginf").action = "login.htm";
}
window.onload=function()
{
var input = this.document.getElementById("password");
var text = this.document.getElementById("text");
input.addEventListener("keyup", function(event)
{
if(event.getModifierState("CapsLock"))
{
text.style.display = "block";
}
else
{
text.style.display = "none";
}
});
};
I am implementing an HTML input field where the user has to enter his email address. I am also implementing validation on the same input field using JavaScript.
function validateEmail() {
var email = document.getElementById('EmailTextbox');
var errorMessage = document.getElementById('ErrorMessageJumbotron');
var filter = /^([a-zA-Z0-9_\.\-])+\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (!filter.test(email.value)) {
errorMessage.style.display = 'block';
email.style.color = '#E54A49';
email.style.border = "1px solid #E54A49";
} else {
errorMessage.style.display = 'none';
email.style.border = "1px solid #949494";
email.style.color = 'black';
}
}
* {
font-family: 'Poppins', sans-serif;
}
#EmailTextbox {
margin-bottom: 15px;
}
input[type="text"] {
font-size: 1em;
height: 45px;
width: 100%;
border: 1px solid #949494;
}
<div class="container">
<div class="jumbotron" id="ErrorMessageJumbotron" style="display: none;">
<div id="errorMessage">
<i class="fa fa-exclamation-triangle fa-2x" aria-hidden="true">
<span style="font-family: 'Poppins', sans-serif; font-weight: 500;">Please correct the marked fields.</span>
</i>
</div>
</div>
</div>
<!--container-->
<div class="container jumbotron">
<input type="text" onblur="validateEmail()" id="EmailTextbox" placeholder="E-mail address" class="form-control">
</div>
If the email is incorrect, the border of the input field is set to red and the user is prompted to enter a valid email address. However, when the user clicks on the input field, the focus is coloured blue and I want it red for this particular case. Otherwise, I want it to be blue as the default.
I have tried several approaches to try to change the focus colour using JavaScript but I did not manage to get it working properly.
Here is a simplified version of what you are trying to do, to help you achieve your end goal:
HTML
<input onblur="onEmailInputBlur(event)" placeholder="E-mail address">
CSS
input.is-invalid {
border: 1px solid red;
outline: none;
}
JS
var invalidClass = 'is-invalid';
function onEmailInputBlur(event) {
var email = event.target.value,
elClassList = event.target.classList;
elClassList.remove(invalidClass);
if (!isEmailValid(email)) {
elClassList.add(invalidClass);
}
}
function isEmailValid(email) {
var validEmailRegex = /^([a-zA-Z0-9_\.\-])+\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return validEmailRegex.test(email);
}
A JsFiddle example:
https://jsfiddle.net/ybaagysn/2/