Related
I'm doing a Contact form and when I'm using the error messages when the infos aren't correct it works but I can't remove the messages once it's corrected.
What's wrong/missing in my code please?
Here's my code :
// Get Data
const nom = document.querySelector("#nom");
const prenom = document.querySelector("#prenom");
const email = document.querySelector("#email");
const message = document.querySelector("#message");
const success = document.querySelector("#success");
const errorNodes = document.querySelectorAll(".error");
// Validate Data
clearMessages ();
let errorFlag = false;
function validateForm(){
errorNodes[0].innerText = "";
errorNodes[1].innerText = "";
if(nom.value.length < 1){
errorNodes[0].innerText = "Le nom ne peut pas être vide.";
errorFlag = true;
}
if(prenom.value.length < 1){
errorNodes[1].innerText = "Le prénom ne peut pas être vide.";
errorFlag = true;
}
if(!errorFlag){
success.innerText = "Message envoyé!";
}
}
// Clear error / success messages
function clearMessages(){
for (let i = 0; i < errorNodes.length; i++){
errorNodes[i].innerText = "";
}
success.innerText = "";
}
// Check if email is valid
function emailIsValid(email){
let pattern = /\S+#\S+\.\S+/;
return pattern.test(email);
}
* {
font-family: Arial;
font-size: 16px;
}
body {
background: #5a8cdb;
}
form {
max-width: 550px;
width: 90%;
background: white;
margin: 90px auto 0 auto;
padding: 40px;
border-radius: 10px;
box-sizing: border-box;
}
h1 {
font-size: 32px;
margin: 0;
text-align: center;
}
.item label {
display: block;
margin: 20px 0;
}
.item input, textarea {
width: 100%;
padding: 10px;
box-sizing: border-box;
outline: none;
resize: none;
border: none;
border-bottom: 1px solid #d3d3d3;
}
input[type="text"]:focus, textarea:focus {
border-bottom: 1px solid #5a8cdb;
}
textarea::-webkit-scrollbar {
width: 3px;
}
textarea::-webkit-scrollbar-thumb {
background-color: #5a8cdb;
}
.center {
text-align: center;
}
input[type="submit"] {
margin-top: 30px;
width: 90%;
max-width: 200px;
border-radius: 5px;
background: #5a8cdb;
color: white;
font-size: 16px;
cursor: pointer;
}
input[type="submit"]:hover {
background: #3F73C5;
}
.error {
display: block;
margin: 5px 0;
color: red;
}
.error-border {
border-bottom: 1px solid red;
}
#success {
color: green;
}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Formulaire de Contact</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<form onsubmit="event.preventDefault(); validateForm()">
<h1>Contactez-nous</h1><br>
<div class="item">
<label for="nom">Nom</label>
<input type="text" id="nom" placeholder="Votre nom">
<small class="error"></small>
<label for="prenom">Prénom</label>
<input type="text" id="prenom" placeholder="Votre prénom">
<small class="error"></small>
<div class="center">
<input type="submit" value="Envoyez">
<p id="success"></p>
</div>
</form>
<script src="script.js"></script>
</body>
</html>
..........................................................................
.........................................................................
well you have to call 'clearMessages()' after editing input somehow. or during editing.
add this to js file:
nom.addEventListener('change', clearMessages);
prenom.addEventListener('change', clearMessages);
nom.addEventListener('focus', clearMessages);
prenom.addEventListener('focus', clearMessages);
EDIT :
change code in clear message to :
errorFlag = false;
for (let i = 0; i < errorNodes.length; i++){
errorNodes[i].innerText = "";
}
success.innerText = "";
and also edit this :
let errorFlag = false;
clearMessages ();
You don't have necessary code when everything is correct within validateForm method. So either add statement that if everything is okay, will remove the the error messages with innerHTML = '' or instead of calling the validation on formSubmit you can:
nom.addEventListener('keyup', (e) => {
if(e.target.value < 1)
//show error code
else //remove error
})
This can be added to every input you want to validate.
When you call the validateForm(), clear them before it does anything else
function validateForm(){
errorNodes[0].innerText = "";
errorNodes[1].innerText = "";
Then the rest of your code and add this
if(!errorFlag){
errorNodes[0].innerText = "";
errorNodes[1].innerText = "";
success.innerText = "Message envoyé!";
}
Easiest way
It is because the code didn't call the 'clearMessages()' after checking the form is validated.
Move the 'clearMessages()' insdie the 'if(!errorFlag)' condition block so the function will call 'clearMessages()' once the form is submit with no error.
if(!errorFlag){
success.innerText = "Message envoyé!";
clearMessages ();
}
I am trying to solve my problem with if-else in Javascript.
I would highly appreciate your help.
I wanted to filter the name via gender, also safe the keys - woman / man to local storage.
But I can not find out how to make if-else clause.
Can someone help me?
There is also the link:
https://drive.google.com/file/d/1RNJxbiU_DsFTCqGJWgxpepCgdOhGuzIj/view?usp=sharing
Thanks a lot, it means world to me, I am new here. :-)
$(document).ready(function() {
function displayName() {
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
//find list
let nameUl = $('#list_2');
nameUl.empty(); //.html('')
//making list
$.each(safeName, function(key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//remove link
let jmenoRemoveLink = $('x');
jmenoRemoveLink.click(function(e) {
e.preventDefault();
//name
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
//remove
safeName.splice(key, 1);
//safe name
localStorage.setItem('woman', JSON.stringify(safeName));
//display name
displayName();
});
nameLi.append(jmenoRemoveLink);
nameUl.append(nameLi);
});
}
$('#formular').submit(function(e) {
e.preventDefault();
let zadaneJmeno = $('#name').val();
if (zadaneJmeno) {
//safe
let safeNameVal = localStorage.getItem('woman');
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
safeName.push(zadaneJmeno);
localStorage.setItem('woman', JSON.stringify(safeName)); /// ["Tom"]
//list
displayName();
$('#name').val('');
} else {
// alert
alert('please enter the name"');
$('#name').focus();
}
});
$('#removeAll').click(function() {
localStorage.setItem('woman', '[]'); ///localStorage.setItem('woman', JSON.stringify([]));
displayName();
});
displayName();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="formular">
<label for="name">Enter the name</label>
<input type="text" id="name" required />
<label for="section">Gender</label>
<select name="selectSection" id="section" required>
<option value="">---</option>
<option value="man" id="man">man</option>
<option value="woman" id="woman">woman</option>
</select>
<input type="submit" value="add" />
</form>
<button id="removeAll">Remove</button>
<div id="man_div">
<h1>man:</h1>
<ul id="list"></ul>
</div>
<div id="woman_div">
<h1>woman:</h1>
<ul id="list_2"></ul>
</div>
I made a number of changes to your script, do note that as I am solving your problem, I removed the 'x' function on click because it is too verbose to read while solving your problem, do add it back later, and make sure you remove from the correct localStorage.
$(document).ready(function () {
function displayName() {
//Separate the local storage into man and woman keys
let manSafeNameVal = localStorage.getItem('man');
let manSafeName;
let womanSafeNameVal = localStorage.getItem('woman');
let womanSafeName
if (manSafeNameVal) {
manSafeName = JSON.parse(manSafeNameVal);
} else {
manSafeName = [];
}
if (womanSafeNameVal) {
womanSafeName = JSON.parse(womanSafeNameVal);
} else {
womanSafeName = [];
}
//find list
//Use list and list_2 to display
let manUl = $('#list');
let womanUl = $('#list_2');
manUl.empty(); //.html('')
womanUl.empty();
//list for man
$.each(manSafeName, function (key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//do add back your 'x' remove here, because it is too verbose to read when I am trying to read the code
manUl.append(nameLi);
});
//list for woman
$.each(womanSafeName, function (key, name) {
let nameLi = $('<li></li>');
nameLi.text(name);
//Also here, the 'x' for woman list
womanUl.append(nameLi);
});
}
$('#formular').submit(function (e) {
e.preventDefault();
let zadaneJmeno = $('#name').val();
//get the selected gender, either man or woman
let gender = $('#section').val();
console.log(gender);
console.log(zadaneJmeno);
if (zadaneJmeno && gender !== "") {
//safe into the localStorage of selected gender
let safeNameVal = localStorage.getItem(gender);
let safeName;
if (safeNameVal) {
safeName = JSON.parse(safeNameVal);
} else {
safeName = [];
}
safeName.push(zadaneJmeno);
localStorage.setItem(gender, JSON.stringify(safeName));/// ["Tom"]
//list
displayName();
$('#name').val('');
} else {
// alert
alert('please enter the name"');
$('#name').focus();
}
});
$('#removeAll').click(function () {
localStorage.setItem('woman', '[]'); ///localStorage.setItem('woman', JSON.stringify([]));
displayName();
});
displayName();
});
const katText = document.getElementById('txtKategorie');
const oText=document.querySelector('input[homework="homework"]');
// selektor tlačítka uložit úkol
const oBttn=document.querySelector('input[type="submit"]');
// selektor tlačítka na odstranění všech úkolů z kategorie
const oDelete=document.querySelector('button#removeAll');
const createlist=function(){
let parent=document.getElementById('lists');
Object.keys(localStorage).forEach(function (key) {
let category = key;
let div = document.createElement('div');
div.id = category;
let h1 = document.createElement('h1');
h1.textContent = category;
let ul = document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
div.onclick = oznacDiv;
parent.appendChild(div);
});
parent.querySelectorAll('div').forEach( div=>{
div.addEventListener('click',function(e){
// odstranění určité položky
if( e.target!=e.currentTarget && e.target.tagName=='A') deleteitem( e );
});
// při načtení stránky načíst úkoly z localStorage a vytvoření listu
// podmmínka -- pokud není úložiště prázdné
let store=div.id;
if( localStorage.getItem(store)!=null )JSON.parse( localStorage.getItem( store ) ).forEach( homework=>{
addlistitem(homework,store);
})
});
}
//na klik oznaci div
function oznacDiv() {
if (oBttn.disabled) oBttn.disabled = false;
document.querySelectorAll('div.active').forEach(div => {
div.classList.remove('active')
});
document.querySelector('div#' + this.id).classList.add('active')
}
const clearstoreitems=function(category){
localStorage.setItem( category, JSON.stringify([]) );
document.querySelector( 'div#' + category ).querySelector('ul').innerHTML='';
};
const deleteitem=function(e){
let parent=e.target.parentNode;
let homework=parent.dataset.homework;
let category=parent.dataset.category;
parent.parentNode.removeChild(parent);
let data=JSON.parse(localStorage.getItem(category));
if( data!=null )data.splice(data.indexOf(homework),1);
localStorage.setItem(category,JSON.stringify(data));
};
const addlistitem=function(homework,category){
let p=document.createElement('button');
p.innerHTML=' Uprava';
p.onclick =function(){
editWorking(li);
}
let a=document.createElement('a');
a.href='#';
a.innerHTML=' Hotovo';
let li=document.createElement('li');
li.value=homework;
li.textContent=homework;
li.dataset.homework=homework;
li.dataset.category=category;
li.appendChild( a );
li.appendChild(p);
document.querySelector( 'div#' + category ).querySelector('ul').appendChild( li );
};
function editWorking(e){
let editValue = prompt('Přejete si upravit úkol?', e.firstChild.nodeValue);
e.firstChild.nodeValue = editValue;
let parent=e.parentNode;
let homework=parent.dataset.homework;
let category=parent.dataset.category;
addlistitem(editValue,category);
addstoreitem(editValue,category);
}
const addstoreitem=function(homework,category){
let data=localStorage.getItem( category );
if( data!=null ){
let json=JSON.parse( data );
json.push(homework);
data=JSON.stringify(json);
}
else
{
data=JSON.stringify([homework]);
}
localStorage.setItem( category, data );
};
//prida novej div s kategorii a poznamkou
const addNewItemList = function () {
let parent = document.getElementById('lists');
let category = katText.value;
let div = document.createElement('div');
div.id = category;
let h1 = document.createElement('h1');
h1.textContent = category;
let ul = document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
div.onclick = oznacDiv;
parent.appendChild(div);
parent.querySelectorAll('div').forEach(div => {
div.addEventListener('click', function (e) {
// odstranění určité položky
if (e.target != e.currentTarget && e.target.tagName == 'A') deleteitem(e);
});
// při načtení stránky načíst úkoly z localStorage a vytvoření listu
// podmmínka -- pokud není úložiště prázdné
let store = div.id;
if (localStorage.getItem(store) != null) JSON.parse(localStorage.getItem(store)).forEach(homework => {
addlistitem(homework, store);
})
});
}
oBttn.addEventListener('click',function(e){
e.preventDefault();
if (oText.value != '') {
if (katText.value != '') {
if (document.querySelector('div#' + katText.value) == null) {
addNewItemList()
}
addlistitem(oText.value, katText.value);
addstoreitem(oText.value, katText.value);
oText.value = '';
return true;
} else {
alert('Zadejte kategorii prosím...');
}
} else {
alert('Zadejte úkol prosím...');
}
});
// vymazat, resetovat pole
oDelete.addEventListener('click', function (e) {
document.querySelectorAll('div.active').forEach(div => {
//clearstoreitems(document.querySelectorAll('div.active').id);
clearstoreitems(div.id);
//div.classList.remove('active')
});
});
createlist();
#charset "UTF-8";
/* CSS Document */
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap');
*{
padding: 100;
margin: 100;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
/**styly pro tělo celé aplikace **/
body{
background: rgb(131,58,180);
background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);
/* background: linear-gradient(139deg, rgba(193,62,62,1) 0%, rgba(230,179,50,1) 100%);
background-image: url("pozadi.png");*/
overflow-x: hidden;
background-repeat: no-repeat;
background-size: cover;
background-position: center;
background-attachment: fixed;
height: 100%;
}
.weather{
width: 100%;
margin: 20px;
padding: 30px;
}
/** pomohla jsem si tady https://the-echoplex.net/flexyboxes/ **/
/**
.flex-container {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-align-content: center;
-ms-flex-line-pack: center;
align-content: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
}
.flex-item:nth-child(1) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
.flex-item:nth-child(2) {
-webkit-order: 0;
-ms-flex-order: 0;
order: 0;
-webkit-flex: 0 100 auto;
-ms-flex: 0 100 auto;
flex: 0 100 auto;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
**/
/**nadpis aplikace **/
#nadpis {
/** margin: auto;
width: 50%;
padding: 5px; **/
text-align: center;
font-size: 40px;
}
.predpoved {
/** width: 30%; **/
border-radius: 15px 50px;
border:4px solid white;
background: black;
-webkit-box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
margin:0 auto;
height: 10%;
width:60%;
padding: 0 auto;
}
.nadpis_1{
font-size: 50px;
color:white;
font:bold;
}
label{
color:white;
font:oblique;
text-transform:inherit;
}
#lists > div{
padding:1rem;
margin:1rem auto;
border-radius: 15px 50px;
border:4px solid white;
margin-left: 30px;
margin-right: 30px;
-webkit-box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
box-shadow: 7px 8px 6px 0px rgba(0,0,0,0.52);
}
.active{
background: linear-gradient(90deg, rgba(252,176,69,1) 0%, rgba(253,29,29,1) 50%, rgba(131,58,180,1)100%);
}
h1{
text-transform:capitalize;
color:white;
}
ul{
list-style: square;
}
ul li{
color:white;
margin-top: 40px;
font-size: 20px;
}
ul a {
color:white;
font:oblique;
padding: 10px;
margin:10px;
margin-left:100px;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
}
ul a:hover {
color:white;
font:oblique;
background:rgba(252,176,69,1);
padding: 10px;
margin:10px;
margin-left:100px;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
}
form{
color: white;
padding: 20px;
width: 600px;
margin: 0 auto;
height: auto;
}
#removeAll{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding:10px;
margin-left: 30px;
margin-right: 30px;
}
#removeAll:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
margin-left: 30px;
margin-right: 30px;
}
#refresh{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding: 10px;
}
#refresh:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
}
#safe{
color:white;
font:oblique;
background: black;
border-radius: 15px ;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
margin: 0 auto;
height: auto;
padding: 10px;
}
#safe:hover {
color:white;
font:oblique;
background: red;
border:1px solid white;
text-decoration: none;
text-transform: uppercase;
padding:10px;
margin: 0 auto;
height: auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Deadline</title>
<link rel="stylesheet" href="style.css">
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div class="flex-container">
<div id="nadpis">
<h1>Deadline</h1>
<form>
<label for="txtHomework">Your homework.. </label>
<input type="text" id="txtHomework" homework="homework" required />
<label for="txtKategorie">Category</label>
<input type="text" id="txtKategorie" kategorie="valKategorie" required />
<!--<select name="selectSection" required>
<option selected hidden disabled>---</option>
<option value="škola">Škola</option>
<option value="Práce">Práce</option>
<option value="Doma">Doma</option>
<option value="Jiné">Jiné</option>
</select>-->
<!--</label>-->
<!-- tlačítko uložit je nedostupné dokud nevybereme kategorii a nezapíšeme úkol -->
<input id ="safe" type="submit" value="Uložit" />
</form>
<div id="lists"></div>
<button id="removeAll">Vyčistit kategorii</button>
I know you already have a solution but I offer an alternative, in vanilla Javascript rather than jQuery, that splits the names according to gender - assigns them to individual areas in localStorage based upon gender and has the functionality to remove individual items from the store. Any items stored in any of the generated stores will be used to populate the HTML lists on page load. I don't use jQuery which is why I wrote this in plain js - no doubt you can cherrypick things from it that might be useful - I hope that it is useful anyway.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Gender splitter</title>
<style>
#lists > div{
padding:1rem;
margin:1rem auto;
border:1px dotted gray;
}
.active{
background:whitesmoke
}
h1{text-transform:capitalize}
</style>
</head>
<body>
<form>
<label>Enter the name
<input type='text' name='name' required />
</label>
<label>Gender
<select name='selectSection' required>
<option selected hidden disabled>---
<option value='male'>Male
<option value='female'>Female
<option value='teapot'>Teapot
<option value='crocodile'>Crocodile
</select>
</label>
<!-- initially disabled to prevent adding when no gender is selected -->
<input type='submit' value='add' disabled />
</form>
<button id='removeAll'>Remove</button>
<div id='lists'></div>
<script>
const oSelect=document.querySelector('select[name="selectSection"]');
const oText=document.querySelector('input[name="name"]');
const oBttn=document.querySelector('input[type="submit"]');
const oDelete=document.querySelector('button#removeAll');
// generate the necessary HTML nodes to display names/genders based
// upon the options in the select menu.
const createlist=function(){
let parent=document.getElementById('lists');
oSelect.querySelectorAll('option').forEach( option=>{
if( option.value !== oSelect.childNodes[1].value ){
let gender=option.value;
let div=document.createElement('div');
div.id=gender;
let h1=document.createElement('h1');
h1.textContent=gender;
let ul=document.createElement('ul');
div.appendChild(h1);
div.appendChild(ul);
parent.appendChild( div );
}
});
parent.querySelectorAll('div').forEach( div=>{
div.addEventListener('click',function(e){
// delete specific item from the store
if( e.target!=e.currentTarget && e.target.tagName=='A') deleteitem( e );
});
// load any names from the store on page load and recreate the lists
let store=div.id;
if( localStorage.getItem(store)!=null )JSON.parse( localStorage.getItem( store ) ).forEach( name=>{
addlistitem(name,store);
})
});
}
// erase store content by gender and clear html list display
const clearstoreitems=function(gender){
localStorage.setItem( gender, JSON.stringify([]) );
document.querySelector( 'div#' + gender ).querySelector('ul').innerHTML='';
};
// delete specific item from particular store
const deleteitem=function(e){
let parent=e.target.parentNode;
let name=parent.dataset.name;
let gender=parent.dataset.gender;
parent.parentNode.removeChild(parent);
let data=JSON.parse(localStorage.getItem(gender));
if( data!=null )data.splice(data.indexOf(name),1);
localStorage.setItem(gender,JSON.stringify(data));
};
// add new item to HTML list based upon gender
const addlistitem=function(name,gender){
let a=document.createElement('a');
a.href='#';
a.innerHTML='X';
let li=document.createElement('li');
li.value=name;
li.textContent=name;
li.dataset.name=name;
li.dataset.gender=gender;
li.appendChild( a );
document.querySelector( 'div#' + gender ).querySelector('ul').appendChild( li );
};
// add new name to the localStorage in gender specific named store
const addstoreitem=function(name,gender){
let data=localStorage.getItem( gender );
if( data!=null ){
let json=JSON.parse( data );
json.push(name);
data=JSON.stringify(json);
} else { data=JSON.stringify([name]); }
localStorage.setItem( gender, data );
};
// Add new item listener
oBttn.addEventListener('click',function(e){
e.preventDefault();
if( oText.value!='' ){
addlistitem(oText.value,oSelect.value);
addstoreitem(oText.value,oSelect.value);
oText.value='';
return true;
}
alert('Name please...');
});
oSelect.addEventListener('change',function(e){
// ensure the "Add" button is enabled
if( oBttn.disabled )oBttn.disabled=false;
document.querySelectorAll('div.active').forEach( div=>{
div.classList.remove('active')
});
// assign a class to visually identify which gender is selected
document.querySelector( 'div#' + this.value ).classList.add('active')
});
// erase this entire store - reset to empty array
oDelete.addEventListener('click',function(e){
clearstoreitems(oSelect.value);
});
createlist();
</script>
</body>
</html>
My program basically displays books and other information about it. It also should be able to delete said book from the library and also the array in which it is stored. This is where my problem lies, I can't seem to delete that exact book from the display and the array. I tried using array.pop() and deleteRow(), but they only delete from the bottom. Thanks in advance for the help.
let myLibrary = [];
function book(name, author, pages, hasRead) {
this.name = name;
this.author = author;
this.pages = pages;
this.read = hasRead;
}
const Book1 = new book('Harry Potter', 'J. K. Rowling', 322, 'Yes');
const Book2 = new book('Great Expectations', 'Charles Dickens', 234, 'Yes');
const Book3 = new book('To Kill a Mockingbird', 'Harper Lee', 312, 'No')
const Book4 = new book('The Great Gatsby', 'F Scott Fitzgerald', 421, 'Yes');
const Book5 = new book('Ulysses', 'James Joyce', 267, 'Yes');
myLibrary.push(Book1, Book2, Book3, Book4, Book5);
function tableHeader() {
var html = "<table id=myTable1>";
html += "<tr>";
html += "<th class=top1>" + 'BOOK NAME'+ "</th>";
html += "<th class=top2>" + 'AUTHOR' + "</th>";
html += "<th class=top3>" + 'PAGES' + "</th>";
html += "<th class=top4>" + 'READ?' + "</th>";
html += "</tr>";
html += "</table>";
document.getElementById("top").innerHTML = html
}
tableHeader();
function viewLibrary() {
var html = "<table id=myTable>";
for (i = 0; i < myLibrary.length; i++) {
html += "<tr>";
html += "<td>" + [i+1] + "</td>";
html += "<td class=box1>" + myLibrary[i].name + "</td>";
html += "<td class=box2>" + myLibrary[i].author + "</td>";
html += "<td class=box3>" + myLibrary[i].pages + "</td>";
html += "<td class=box4>" + myLibrary[i].read + "</td>";
html += "<td class=del>" + 'X' + "</td>";
html += "</tr>";
}
html += "</table>";
document.getElementById("box").innerHTML = html;
}
viewLibrary();
function deleteBook() {
var button = document.querySelectorAll('.del');
var table = document.getElementById('myTable');
var rowCount = table.rows.length;
for (var i = 0; i < rowCount; i++) {
button[i].addEventListener('click', function () {
table.deleteRow(this);
console.log(event);
myLibrary.pop();
})
}
}
deleteBook();
function addModal() {
var btn = document.getElementById("new-book");
var modal = document.getElementById("myModal");
var span = document.getElementsByClassName("close")[0];
btn.onclick = function () {
modal.style.display = "block";
}
span.onclick = function () {
modal.style.display = "none";
}
}
addModal();
function addBookToLibrary() {
let name = document.getElementById('name').value;
let author = document.getElementById('author').value;
let pages = document.getElementById('pages').value;
let read = document.getElementById('dropdown').value;
var submit = document.getElementById("submit");
var modal = document.getElementById("myModal");
if (name === '' || author === '' || pages === '' || read === '') {
alert("Fill out all values.")
return false;
} else {
submit.onclick = function () {
modal.style.display = "none";
}
const NewBook = new book(name, author, pages, read);
myLibrary.push(NewBook);
console.log(NewBook);
viewLibrary();
document.getElementById('name').value = '';
document.getElementById('author').value = '';
document.getElementById('pages').value = '';
document.getElementById('dropdown').value = '';
deleteBook();
}
}
let x = document.querySelectorAll('button');
x.forEach(button => {
button.addEventListener('click', () => {
let selection = button.innerHTML;
switch (selection) {
case "Submit":
addBookToLibrary();
break;
}
})
})
body {
background-color: #edc4b3;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
}
/* Modal Content/Box */
.modal-content {
background-color: #eddcd2;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 40%;
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
table {
margin-left: 14.5%;
margin-top: 5%;
width: 70%;
background-color: #edddd4;
border: 5px solid #8d99ae;
border-collapse: collapse;
margin-top: 2%;
}
#top {
color: #9d6b53;
}
#box {
margin-top: -1.5%;
}
.line {
color: #774936;
}
td {
padding-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
}
h1 {
text-align: center;
text-transform: uppercase;
font-family: 'Notable', sans-serif;
}
h2 {
text-align: center;
text-decoration: underline;
}
#new-book {
margin-left: 79%;
background-color: #888;
cursor: pointer;
margin-top: 2%;
padding: 5px 5px;
font-weight: bold;
}
/*tr:first-child { font-weight: bold }*/
#name, #author, #pages {
width: 60%;
border: 0;
border-bottom: 1px solid black;
font-size: 1rem;
color: black;
background-color: #eddcd2;
font-family: 'Times New Roman', Times, serif;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 2px;
padding-right: 2px;
}
td {
font-family: 'Source Code Pro', monospace;
}
#author {
width: 58.5%;
}
#pages {
width: 61.3%;
}
#dropdown {
width: 28%;
background-color: #edddd4;
font-size: 17px;
cursor: pointer;
box-sizing: border-box;
margin: 0;
border: 1px solid black;
padding-top: 5px;
padding-bottom: 5px;
}
#submit {
background-color: black;
border: none;
color: white;
padding: 16px 32px;
text-decoration: none;
margin: 4px 2px;
cursor: pointer;
width: 30%;
margin-left: 35%;
}
input:focus,
select:focus,
textarea:focus,
button:focus {
outline: none;
}
.del {
color: red;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Library</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<button id='new-book'>Add Book</button>
<section id="top"></section>
<section id="box"></section>
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<h2>Add a new book</h2>
<label for="name">Name of the Book:</label>
<input type="text" id="name" name="fname" required><br><br>
<label for="author">Name of the Author:</label>
<input type="text" id="author" name="lname" required><br><br>
<label for="pages">Number of Pages:</label>
<input type="number" id="pages" name="pname" required><br><br>
<p>Have you read this book?</p>
<select id="dropdown" required>
<option value="" disabled selected>Select your option</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select><br><br>
<button id="submit">Submit</button>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
I would suggest a different approach. Instead of creating your new elements through string concatenation and .innerHTML (which has performance and security implications), use the DOM API to create your new elements and then just attach an event handler to the dynamically created cells that contain the X.
See additional comments inline below:
let headers = ["name", "author", "pages", "read"];
// Get your DOM references just once, not every time
// your event handlers execute and make sure to always
// reference the DOM element, rather than a property
// of the DOM element. That way, if you ever decide
// that you need a different property value, you won't
// have to scan the DOM for the element reference again.
let box = document.getElementById("box");
var btn = document.getElementById("new-book");
var modal = document.getElementById("myModal");
let closeModal = document.querySelector("span.close");
let name = document.getElementById('name');
let author = document.getElementById('author');
let pages = document.getElementById('pages');
let read = document.getElementById('dropdown');
var submit = document.getElementById("submit");
var modal = document.getElementById("myModal");
// DO NOT USE GETELEMENTSBYCLASSNAME and especially
// pass an idex to the first element within it:
// var span = document.getElementsByClassName("close")[0];
// Read this for details: https://stackoverflow.com/questions/54952088/how-to-modify-style-to-html-elements-styled-externally-with-css-using-js/54952474#54952474
// Instead, use .querySelector()
var span = document.querySelector(".close");
// Bind the "buttons" that show/hide the modal
// to a common function that does that.
btn.addEventListener('click', showHideModal);
closeModal.addEventListener('click', showHideModal);
function showHideModal(){
// No need for if/then. Just toggle the use of
// the .hidden CSS class
modal.classList.toggle("hidden");
}
submit.addEventListener('click', addBookToLibrary);
function book(name, author, pages, hasRead) {
this.name = name;
this.author = author;
this.pages = pages;
this.read = hasRead;
}
// No need to create variables to store new book references,
// and then push them into the Array. Just put the new books
// directly into the new Array.
let myLibrary = [
new book('Harry Potter', 'J. K. Rowling', 322, 'Yes'),
new book('Great Expectations', 'Charles Dickens', 234, 'Yes'),
new book('To Kill a Mockingbird', 'Harper Lee', 312, 'No'),
new book('The Great Gatsby', 'F Scott Fitzgerald', 421, 'Yes') ,
new book('Ulysses', 'James Joyce', 267, 'Yes')
];
function makeLibrary() {
// Get rid of the prior table (if exists)
if(document.getElementById("myTable")){
document.getElementById("myTable").remove();
}
// Instead of creating concatenated strings of HTML, which gets
// messy and hard to maintain, create DOM objects and set their
// propeties.
let tbl = document.createElement("table");
tbl.id = "myTable";
for (i = 0; i < myLibrary.length; i++) {
let row = document.createElement("tr");
let numCell = document.createElement("td");
numCell.textContent = i + 1;
row.appendChild(numCell);
// Loop over the headers array to build the row cells
headers.forEach(function(header, index){
let cell = document.createElement("td");
cell.textContent = myLibrary[i][header];
cell.classList.add("box" + (index + 1));
row.appendChild(cell); // Add the cell to the row
});
let delCell = document.createElement("td");
delCell.textContent = "X";
delCell.classList.add("del");
// Because the elements are now being created as elements
// and not strings, you can set up even binding on them.
delCell.addEventListener("click", function(){
myLibrary.splice(i, 1); // Remove book from library
this.closest("tr").remove(); // Remove row
});
row.appendChild(delCell); // Add cell to row
tbl.appendChild(row); // Add row to table
box.appendChild(tbl); // Add table to section
}
}
makeLibrary();
function addBookToLibrary() {
if (name.value === '' || author.value === '' || pages.value === '' || read.value === '') {
alert("Fill out all values.")
return false;
} else {
myLibrary.push(new book(name.value, author.value, pages.value, read.value));
makeLibrary();
name.value = '';
author.value = '';
pages.value = '';
dropdown.value = '';
showHideModal();
}
}
body {
background-color: #edc4b3;
}
/* Added classes */
h1.addBook { font-size: 1em; }
.hidden { display:none; }
/* The Modal (background) */
.modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
}
/* Modal Content/Box */
.modal-content {
background-color: #eddcd2;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 40%;
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
table {
margin-left: 14.5%;
margin-top: 5%;
width: 70%;
background-color: #edddd4;
border: 5px solid #8d99ae;
border-collapse: collapse;
margin-top: 2%;
}
#top {
color: #9d6b53;
}
#box {
margin-top: -1.5%;
}
.line {
color: #774936;
}
td {
padding-bottom: 10px;
padding-top: 10px;
padding-left: 10px;
}
h1 {
text-align: center;
text-transform: uppercase;
font-family: 'Notable', sans-serif;
}
h2 {
text-align: center;
text-decoration: underline;
}
#new-book {
margin-left: 79%;
background-color: #888;
cursor: pointer;
margin-top: 2%;
padding: 5px 5px;
font-weight: bold;
}
/*tr:first-child { font-weight: bold }*/
#name, #author, #pages {
width: 60%;
border: 0;
border-bottom: 1px solid black;
font-size: 1rem;
color: black;
background-color: #eddcd2;
font-family: 'Times New Roman', Times, serif;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 2px;
padding-right: 2px;
}
td {
font-family: 'Source Code Pro', monospace;
}
#author {
width: 58.5%;
}
#pages {
width: 61.3%;
}
#dropdown {
width: 28%;
background-color: #edddd4;
font-size: 17px;
cursor: pointer;
box-sizing: border-box;
margin: 0;
border: 1px solid black;
padding-top: 5px;
padding-bottom: 5px;
}
#submit {
background-color: black;
border: none;
color: white;
padding: 16px 32px;
text-decoration: none;
margin: 4px 2px;
cursor: pointer;
width: 30%;
margin-left: 35%;
}
input:focus,
select:focus,
textarea:focus,
button:focus {
outline: none;
}
.del {
color: red;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Library</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<button id='new-book'>Add Book</button>
<section id="top">
<!-- If you have static bits of HTML, don't create them
dynamically in JavaScript, go ahead and hard-code them
into the HTML. This will reduce the amount of JavaScript
and improve the speed of the page load. -->
<table id="myTable1">
<tr>
<th class="top1">BOOK NAME</th>
<th class=top2>AUTHOR</th>
<th class=top3>PAGES</th>
<th class=top4>READ?</th>
</tr>
</table>
</section>
<section id="box"></section>
<div id="myModal" class="modal hidden">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<!-- You can't have an H2 if it's not a child of an H1.
Don't choose a heading because of how it looks, pick
it because it represents the right heading level and
then style it with CSS. -->
<h1 class="addBook">Add a new book</h1>
<label for="name">Name of the Book:</label>
<input type="text" id="name" name="fname" required><br><br>
<label for="author">Name of the Author:</label>
<input type="text" id="author" name="lname" required><br><br>
<label for="pages">Number of Pages:</label>
<input type="number" id="pages" name="pname" required><br><br>
<p>Have you read this book?</p>
<select id="dropdown" required>
<option value="" disabled selected>Select your option</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select><br><br>
<button id="submit">Submit</button>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
function deleteBook() {
var button = document.querySelectorAll('.del');
var table = document.getElementById('myTable');
var rowCount = table.rows.length;
for (var i = 0; i < rowCount; i++) {
button[i].addEventListener('click', function () {
table.deleteRow(i);
// I think pop will delete only the last element.
myLibrary.splice(i, 1);
})
}
}
this in table.deleteRow(this) refers to a HTMLTableCellElement.
According to this doc : https://www.w3schools.com/jsreF/met_table_deleterow.asp
You'll need to pass an index instead.
Edit :
What about adding a data-row attribute to your rows where you put the index, and then getting this index by using element.dataset.row
E.G :
var html = "<table id=myTable1>";
html += "<tr data-row=" + $yourIndex + ">";
html += "<th class=top1>" + 'BOOK NAME'+ "</th>";
html += "<th class=top2>" + 'AUTHOR' + "</th>";
html += "<th class=top3>" + 'PAGES' + "</th>";
html += "<th class=top4>" + 'READ?' + "</th>";
html += "</tr>";
html += "</table>";
Use Splice to remove the element from the array. Use this link for your reference.
your way of explanation is a little bit vague to understand.
I have an unordered list.
This list has elements with checkboxes in it. If you check in a checkbox, the list element goes to the bottom of the list. when you check out one of the checkboxes, it has to go back to its original place. so far, I managed.
BUT. Take the following situation: You checked in all the checkboxes, and they seem to align according to their original place. Now, when you check out a list element, it will stuck between to other elements, which are on their place, but they are checked in. I want that in that case, the checked off box will be the first in the list. Then, when you check off the next box, that one will now be on the right place, aligning with thee unchecked boxes only.
TL;DR:
I have to make a To Do list, the 'done' elements go to the bottom, the undone elements sorted above, according to their timestamp.
http://codepen.io/balazsorban44/pen/mAvqmk
<!DOCTYPE html>
<html>
<head>
<title>A Todo List</title>
<style media="screen">
*{
margin:0;
padding: 0;
font-family: sans-serif;
color: gold;
font-weight: bolder;
font-size: 1em;
border: none;
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
width: 100vw;
background: #333;
}
#content{
border: 1px solid #333;
padding: 20px;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
background-color: gold;
box-shadow: 0px 0px 4px 4px rgba(0,0,0,.2);
}
h1,h2{
display: block;
color: #444;
font-size: 1.3em;
padding: 10px;
align-self: flex-start;
}
h2{
font-size: 1.1em
}
input{
color: #333;
padding: 5px;
border-radius: 5px;
border: 1px solid #333;
box-shadow: inset 0px 0px 3px rgba(0,0,0,.3)
}
input:focus{
outline: none
}
button{
background: #333;
border-radius: 5px;
padding: 5px 10px;
max-width: 50%;
margin-top:15px;
cursor: pointer
}
ul li{
list-style-type: none;
color:#333;
min-width: 100px;
padding: 5px;
align-self: flex-start;
}
ul li input{
margin: 0 5px
}
</style>
</head>
<body onload="loaded()">
<div id=content>
<h1>A very nice To Do list</h1>
<div>
<input id="todo-input" type="text" name="todo-input" value="" placeholder="Click + or press Enter." onkeydown="enter()">
<button type="button" name="button" onclick="addTask()">+</button>
</div>
<h2>Your todo list (done/all): <output>/</output></h2>
<ul id="tasks">
</ul>
</div>
<script type="text/javascript">
const inputArea= document.getElementById('todo-input')
const list = document.getElementById("tasks");
tasks = [];
function loaded(){
inputArea.focus();
}
function addTask(){
const newTask = document.createElement("li")
const text = document.createTextNode(inputArea.value)
const checkBox = document.createElement("input");
newTask.appendChild(text);
list.insertBefore(newTask, list.childNodes[0]);
checkBox.setAttribute("type", "checkbox");
checkBox.setAttribute("onclick", "toggleCheckBox()");
list.childNodes[0].insertBefore(checkBox, list.childNodes[0].childNodes[0]);
tasks.push({timestamp: new Date(), task: inputArea.value});
list.childNodes[0].id=tasks[tasks.length-1].timestamp.getTime();
inputArea.value ="";
inputArea.focus();
}
function enter(){
if(event.keyCode == 13) {
addTask()
}
}
function toggleCheckBox(){
const task = event.target.parentNode
if (task.style.textDecoration == '') {
task.style.textDecoration = 'line-through';
list.appendChild(task)
}
else {
task.style.textDecoration = ''
for (var i = 0; i < tasks.length; i++) {
if (task.id > list.childNodes[i].id) {
list.insertBefore(task, list.childNodes[i]);
break
}
}
}
}
</script>
</body>
</html>
Manage your tasks list in javascript and update the HTML whenever a checkbox value is changed or task is added:
var inputArea = document.getElementById('todo-input')
var list = document.getElementById("tasks");
var tasks = [];
function loaded() {
inputArea.value = "";
inputArea.focus();
}
function update(){
list.innerHTML = '';
// Sort the tasks on done boolean
tasks.sort(function(x, y) {
return (x.done === y.done)? 0 : x.done ? 1 : -1;
});
for(var i = 0; i < tasks.length; i++){
var item = tasks[i];
var task = document.createElement("li")
var text = document.createElement("span");
var checkBox = document.createElement("input");
text.innerHTML = item.task;
text.style.color = 'black';
checkBox.setAttribute("type", "checkbox");
checkBox.addEventListener("change", (function(t){
return function(){
tasks[t].done = this.checked;
console.log(tasks[t]);
update();
}
}(i)));
if(item.done){
checkBox.checked = true;
text.style.textDecoration = 'line-through'
}
task.appendChild(checkBox);
task.appendChild(text);
list.appendChild(task);
}
}
function addTask() {
tasks.push({
id: tasks.length ? tasks[tasks.length - 1].timestamp.getTime() : +new Date(),
done: false,
timestamp: new Date(),
task: inputArea.value
});
update();
loaded();
}
Codepen
I guess you have to make an object structure as
function Task(id,itemName,timeStamp,isCompleted){
this.id=id;
this.itemName=itemName;
this.time=timeStamp;
this.completed=isCompleted;
}
var Tasks=[];
while adding each task,you have to save in such format.
So whenever a task is completed ,you would set completed to true . For all the uncompleted tasks all you need to do is to sort based on their time or based on their name
Hope this helps
Made a script that checks if: $("#password") has 9 symbols and if $("#password") = $("#confirm_password").
The problem is when I try to enable the "submit" button... What is wrong with "function submitButton()"?
$("form span").hide();
$('input[type="submit"]').attr("disabled", "true");
var samePass = false;
var eight = false;
var $password01 = $("#password");
var $password02 = $("#confirm_password")
//Why this function doesn't work?
function submitButton() {
if (samePass && eight){
$('input[type="submit"]').removeAttr('disabled');
};
};
//Checks if the pass has 8 symbles
function passwordEvent() {
if ($password01.val().length > 8) {
eight = true;
$password01.next().hide().submitButton();
} else {
$password01.next().show();
};
};
//Checks if the two passwards are the same
function passwordCheck() {
if($password02.val() !== $password01.val()) {
$password02.next().show();
} else {
samePass = true;
$password02.next().hide().submitButton();
};
};
$password01.focus(passwordEvent).keyup(passwordEvent).focus(passwordCheck).keyup(passwordCheck);
$password02.focus(passwordCheck).keyup(passwordCheck);
$("form span").hide();
$('input[type="submit"]').attr("disabled", "true");
var samePass = false;
var eight = false;
var $password01 = $("#password");
var $password02 = $("#confirm_password")
//Why this function doesn't work?
function submitButton() {
if (samePass && eight){
$('input[type="submit"]').removeAttr('disabled');
};
};
//Checks if the pass has 8 symbles
function passwordEvent() {
if ($password01.val().length > 8) {
eight = true;
$password01.next().hide().submitButton();
} else {
$password01.next().show();
};
};
//Checks if the two passwards are the same
function passwordCheck() {
if($password02.val() !== $password01.val()) {
$password02.next().show();
} else {
samePass = true;
$password02.next().hide().submitButton();
};
};
$password01.focus(passwordEvent).keyup(passwordEvent).focus(passwordCheck).keyup(passwordCheck);
$password02.focus(passwordCheck).keyup(passwordCheck);
body {
background: #384047;
font-family: sans-serif;
font-size: 10px
}
form {
background: #fff;
border-radius: 10px;
padding: 4em 4em 2em;
box-shadow: 0 0 1em #222;
max-width: 400px;
margin: 100px auto;
}
p {
margin: 0 0 3em 0;
position: relative;
}
label {
font-size: 1.6em;
font-weight:600;
color: #333;
display: block;
margin: 0 0 .5em;
}
input {
display: block;
height: 40px;
width: 100%;
box-sizing: border-box;
outline: none
}
input[type="text"],
input[type="password"] {
background: #f5f5f5;
border: 1px solid #F0F0F0;
border-radius: 5px;
font-size: 1.6em;
padding: 1em 0.5em;
}
input[type="text"]:focus,
input[type="password"]:focus {
background: #fff
}
span {
border-radius: 5px;
padding: 7px 10px;
background: #2F558E;
color: #fff;
width: 160px;
display: block; /* Needed for the width to work */
text-align: center; /* For the inner text */
position: absolute;
left: 105%;
top: 25px;
}
span:after {
content: " ";
position: absolute;
/* pointer-events: none;*/
right: 100%;
top: 50%;
/*
height: 0;
width: 0;
*/
border: solid transparent;
/* border-color: rgba(136, 183, 213, 0);*/
border-right-color: #2F558E;
border-width: 8px;
margin-top: -8px;
}
.enableSub {
background: #0099FF;
border: none;
border-radius: 5px;
color: white;
height: 50px;
box-shadow: 0 3px 0 0 #005C99;
}
.disableSub {
background: #AEAEAE;
border: none;
border-radius: 5px;
color: white;
height: 50px;
}
<!DOCTYPE html>
<html>
<head>
<title>Sign Up Form</title>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" title="no title" charset="utf-8">
</head>
<body>
<form action="#" method="post">
<p>
<label for="username">Username</label>
<input id="username" name="username" type="text">
</p>
<p>
<label for="password">Password</label>
<input id="password" name="password" type="password">
<span>Enter a password longer than 8 characters</span>
</p>
<p>
<label for="confirm_password">Confirm Password</label>
<input id="confirm_password" name="confirm_password" type="password">
<span>Please confirm your password</span>
</p>
<p>
<input type="submit" class="disableSub" value="SUBMIT">
</p>
</form>
<script src="http://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/app.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
$password01.next().hide().submitButton();
et al. won't work. You instead need to do;
$password01.next().hide();
submitButton();
You've declared submitButton as a function, not a method on a jQuery object, hence you need to call it as such.
The "undefined is not a function" error appears cryptic at first, but becomes clear once understood.
Since the jQuery object returned from hide() doesn't have a submitButton property (or method), hide().submitButton returns undefined. You're then trying to call that as a function (with the ()), hence JavaScript is telling you that undefined is not a function.
As well as the above, your logic is also flawed. Namely samePass is being set to true the second you click into the password1 field (since, on focus, when they're both blank, $password02.val() === $password01.val()). That means that as soon as password is > 8 chars, both conditions will match, and your submit will be enabled.
To fix this, you should probably be setting samePass and eight to false when they don't match their criteria, and calling submitButton() in all cases to update the state
//Why this function doesn't work?
function submitButton() {
if (samePass && eight) {
$('input[type="submit"]').removeAttr('disabled');
} else {
$('input[type="submit"]').attr('disabled', "true");
}
};
//Checks if the pass has 8 symbles
function passwordEvent() {
if ($password01.val().length > 8) {
eight = true;
$password01.next().hide();
submitButton();
} else {
eight = false;
$password01.next().show();
submitButton();
};
};
//Checks if the two passwards are the same
function passwordCheck() {
if ($password02.val() !== $password01.val()) {
samePass = false;
$password02.next().show();
submitButton();
} else {
samePass = true;
$password02.next().hide();
submitButton();
};
};
... which then works; http://jsfiddle.net/9qqnqLxm/