Prevent input field from any changes except with arrow buttons - javascript

I want to prevent completely users to modify the values of the number input form in any way that is not using the arrows in the form. Basically I have this:
const pwEl = document.getElementById("pw");
const copyEl = document.getElementById("copy");
const lenEl = document.getElementById("len");
const upperEl = document.getElementById("upper");
const numberEl = document.getElementById("number");
const symbolEl = document.getElementById("symbol");
const generateEl = document.getElementById("generate");
const footerEl = document.getElementById("footer");
const lowerLetters = "abcdefghijklmnopqrstuvwxyz"
const upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const numbers = "1234567890"
const specialCharacters = "|##~€!$%&/()=?¿"
function randomUpper() {
return upperLetters[Math.floor(Math.random()*upperLetters.length)];
}
function randomNumbers() {
return numbers[Math.floor(Math.random()*numbers.length)];
}
function randomSpecial() {
return specialCharacters[Math.floor(Math.random()*specialCharacters.length)];
}
function randomLower() {
return lowerLetters[Math.floor(Math.random()*lowerLetters.length)];
}
function generateChunk() {
const xs = [];
xs.push(randomLower());
if (upperEl.checked) {
xs.push(randomUpper());
}
if (numberEl.checked) {
xs.push(randomNumbers());
}
if (symbolEl.checked) {
xs.push(randomSpecial());
}
return xs[Math.floor(Math.random()*xs.length)];
}
function generatePassword() {
const len = lenEl.value;
let password = "";
for (let i = 0; i < len; i++) {
password += generateChunk();
}
pwEl.innerText = password;
}
function copy() {
var textArea = document.createElement("textarea");
textArea.value = pwEl.textContent;
document.body.appendChild(textArea);
textArea.select();
document.execCommand("Copy");
textArea.remove();
//adding class to transition
footerEl.innerText = "Succesfully copied to clipboard!";
footerEl.classList.add("footer-active");
setTimeout(() => {
footerEl.classList.remove("footer-active");
}, 1000)
setTimeout(() => {
footerEl.innerText = "";
}, 1200);
}
generateEl.addEventListener("click", generatePassword);
copyEl.addEventListener("click", copy);
#import url('https://fonts.googleapis.com/css2?family=Raleway:wght#500&display=swap');
* {
box-sizing: border-box;
}
body{
background-color:#37505c;
color: #FFEAD0;
font-family: 'Raleway', sans-serif;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.pw-container{
background-color: #113537;
width:500px;
box-shadow: 5px 10px 8px rgba(0,0,0,0.2);
z-index:2;
}
.pw {
background-color:#37505c;
height: 70px;
width:100%;
position: relative;
align-items: center;
font-size: 2rem;
padding: 1rem;
text-align: center;
}
.pw button{
font-family: inherit;
position: absolute;
top: 0;
right: 0;
transform: translate(0, -20%);
background-color: #FFFFFF;
border: none;
color: #000000;
padding: 0.25rem;
opacity:0;
transition: opacity 0.2s ease, transform 0.2s ease;
cursor: pointer;
}
.pw:hover button {
opacity: 1;
transform: translate(0, -90%)
}
.pw-header {
padding: 1rem;
}
.pw-body {
padding: 0 1rem 1rem;
}
.form-control {
display:flex;
justify-content: space-between;
margin: 0.5rem;
}
.generate {
background-color: #FFFFFF;
display:block;
border: none;
font-size: 1rem;
padding : 0.5rem;
width: 100%;
margin-top: 2rem;
}
.footer {
position: absolute;
top: 1;
bottom: 0;
font-size: 2rem;
width:100%;
background-color:#113537;
text-align: center;
padding: 2rem;
opacity:0;
transition: opacity 0.2s ease;
z-index: 1;
}
.footer-active {
opacity: 1;
transform: translate(0, 0%);
z-index: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Generator</title>
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
<div class="pw-container">
<div class="pw-header">
<div class="pw">
<span id="pw">1234</span>
<button id="copy">Copy to clipboard</button>
</div>
</div>
<div class="pw-body">
<div class="form-control">
<label for="len">Length</label>
<input id="len" onKeyDown="return false" type="number" min="5" max="20" value="7">
</div>
<div class="form-control">
<label for="upper">Uppercase</label>
<input id="upper" type="checkbox">
</div>
<div class="form-control">
<label for="number">Numbers</label>
<input id="number" type="checkbox">
</div>
<div class="form-control">
<label for="symbol">Symbols</label>
<input id="symbol" type="checkbox">
</div>
<button class="generate" id="generate">
Generate Password
</button>
</div>
</div>
<div id="footer" class="footer">
</div>
</body>
</html>
Note that in the input, I added onKeyDown="return false", an answer in other post like this one.
However, this is not going to prevent the user from doing a paste of any value he wants, nor moving a value with the mouse into the field. Is there any way to prevent it?

You can easily block any events you want with event handlers like this - it takes a list of events and adds an event handler for each to block it. You can add as many or few events as you need - see a list of Events here:
"keypress paste dragstart drop cut".split(" ").forEach(function(e){
lenEl.addEventListener(e, function(e){
e.preventDefault();
return false;
});
});
Working Example - Accessible Version: Allows tab and arrow keys
const pwEl = document.getElementById("pw");
const copyEl = document.getElementById("copy");
const lenEl = document.getElementById("len");
const upperEl = document.getElementById("upper");
const numberEl = document.getElementById("number");
const symbolEl = document.getElementById("symbol");
const generateEl = document.getElementById("generate");
const footerEl = document.getElementById("footer");
const lowerLetters = "abcdefghijklmnopqrstuvwxyz"
const upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const numbers = "1234567890"
const specialCharacters = "|##~€!$%&/()=?¿"
"keypress paste dragstart drop cut".split(" ").forEach(function(e){
lenEl.addEventListener(e, function(e){
e.preventDefault();
return false;
});
});
function randomUpper() {
return upperLetters[Math.floor(Math.random()*upperLetters.length)];
}
function randomNumbers() {
return numbers[Math.floor(Math.random()*numbers.length)];
}
function randomSpecial() {
return specialCharacters[Math.floor(Math.random()*specialCharacters.length)];
}
function randomLower() {
return lowerLetters[Math.floor(Math.random()*lowerLetters.length)];
}
function generateChunk() {
const xs = [];
xs.push(randomLower());
if (upperEl.checked) {
xs.push(randomUpper());
}
if (numberEl.checked) {
xs.push(randomNumbers());
}
if (symbolEl.checked) {
xs.push(randomSpecial());
}
return xs[Math.floor(Math.random()*xs.length)];
}
function generatePassword() {
const len = lenEl.value;
let password = "";
for (let i = 0; i < len; i++) {
password += generateChunk();
}
pwEl.innerText = password;
}
function copy() {
var textArea = document.createElement("textarea");
textArea.value = pwEl.textContent;
document.body.appendChild(textArea);
textArea.select();
document.execCommand("Copy");
textArea.remove();
//adding class to transition
footerEl.innerText = "Succesfully copied to clipboard!";
footerEl.classList.add("footer-active");
setTimeout(() => {
footerEl.classList.remove("footer-active");
}, 1000)
setTimeout(() => {
footerEl.innerText = "";
}, 1200);
}
generateEl.addEventListener("click", generatePassword);
copyEl.addEventListener("click", copy);
#import url('https://fonts.googleapis.com/css2?family=Raleway:wght#500&display=swap');
* {
box-sizing: border-box;
}
body{
background-color:#37505c;
color: #FFEAD0;
font-family: 'Raleway', sans-serif;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.pw-container{
background-color: #113537;
width:500px;
box-shadow: 5px 10px 8px rgba(0,0,0,0.2);
z-index:2;
}
.pw {
background-color:#37505c;
height: 70px;
width:100%;
position: relative;
align-items: center;
font-size: 2rem;
padding: 1rem;
text-align: center;
}
.pw button{
font-family: inherit;
position: absolute;
top: 0;
right: 0;
transform: translate(0, -20%);
background-color: #FFFFFF;
border: none;
color: #000000;
padding: 0.25rem;
opacity:0;
transition: opacity 0.2s ease, transform 0.2s ease;
cursor: pointer;
}
.pw:hover button {
opacity: 1;
transform: translate(0, -90%)
}
.pw-header {
padding: 1rem;
}
.pw-body {
padding: 0 1rem 1rem;
}
.form-control {
display:flex;
justify-content: space-between;
margin: 0.5rem;
}
.generate {
background-color: #FFFFFF;
display:block;
border: none;
font-size: 1rem;
padding : 0.5rem;
width: 100%;
margin-top: 2rem;
}
.footer {
position: absolute;
top: 1;
bottom: 0;
font-size: 2rem;
width:100%;
background-color:#113537;
text-align: center;
padding: 2rem;
opacity:0;
transition: opacity 0.2s ease;
z-index: 1;
}
.footer-active {
opacity: 1;
transform: translate(0, 0%);
z-index: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Generator</title>
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
<div class="pw-container">
<div class="pw-header">
<div class="pw">
<span id="pw">1234</span>
<button id="copy">Copy to clipboard</button>
</div>
</div>
<div class="pw-body">
<div class="form-control">
<label for="len">Length</label>
<input id="len" type="number" min="5" max="20" value="7">
</div>
<div class="form-control">
<label for="upper">Uppercase</label>
<input id="upper" type="checkbox">
</div>
<div class="form-control">
<label for="number">Numbers</label>
<input id="number" type="checkbox">
</div>
<div class="form-control">
<label for="symbol">Symbols</label>
<input id="symbol" type="checkbox">
</div>
<button class="generate" id="generate">
Generate Password
</button>
</div>
</div>
<div id="footer" class="footer">
</div>
</body>
</html>
Blocking ALL Key Presses
Note that it is not recommended to prevent all keyDown/keyUp events, for accesibility reasons - it makes your form impossible to use without mouse/touch screen - not only are you unable to change the values, you get stuck inside that input forever and can't even tab out of it! \
Therefore I use keypress instead of keydown above, as keypress allows for control keys to work but if you really need to, you can use keydown instead.
Working Example Blocking ALL Key Presses (inaccessible for visually impaired users)
const pwEl = document.getElementById("pw");
const copyEl = document.getElementById("copy");
const lenEl = document.getElementById("len");
const upperEl = document.getElementById("upper");
const numberEl = document.getElementById("number");
const symbolEl = document.getElementById("symbol");
const generateEl = document.getElementById("generate");
const footerEl = document.getElementById("footer");
const lowerLetters = "abcdefghijklmnopqrstuvwxyz"
const upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const numbers = "1234567890"
const specialCharacters = "|##~€!$%&/()=?¿"
"keydown paste dragstart drop cut".split(" ").forEach(function(e){
lenEl.addEventListener(e, function(e){
e.preventDefault();
return false;
});
});
function randomUpper() {
return upperLetters[Math.floor(Math.random()*upperLetters.length)];
}
function randomNumbers() {
return numbers[Math.floor(Math.random()*numbers.length)];
}
function randomSpecial() {
return specialCharacters[Math.floor(Math.random()*specialCharacters.length)];
}
function randomLower() {
return lowerLetters[Math.floor(Math.random()*lowerLetters.length)];
}
function generateChunk() {
const xs = [];
xs.push(randomLower());
if (upperEl.checked) {
xs.push(randomUpper());
}
if (numberEl.checked) {
xs.push(randomNumbers());
}
if (symbolEl.checked) {
xs.push(randomSpecial());
}
return xs[Math.floor(Math.random()*xs.length)];
}
function generatePassword() {
const len = lenEl.value;
let password = "";
for (let i = 0; i < len; i++) {
password += generateChunk();
}
pwEl.innerText = password;
}
function copy() {
var textArea = document.createElement("textarea");
textArea.value = pwEl.textContent;
document.body.appendChild(textArea);
textArea.select();
document.execCommand("Copy");
textArea.remove();
//adding class to transition
footerEl.innerText = "Succesfully copied to clipboard!";
footerEl.classList.add("footer-active");
setTimeout(() => {
footerEl.classList.remove("footer-active");
}, 1000)
setTimeout(() => {
footerEl.innerText = "";
}, 1200);
}
generateEl.addEventListener("click", generatePassword);
copyEl.addEventListener("click", copy);
#import url('https://fonts.googleapis.com/css2?family=Raleway:wght#500&display=swap');
* {
box-sizing: border-box;
}
body{
background-color:#37505c;
color: #FFEAD0;
font-family: 'Raleway', sans-serif;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.pw-container{
background-color: #113537;
width:500px;
box-shadow: 5px 10px 8px rgba(0,0,0,0.2);
z-index:2;
}
.pw {
background-color:#37505c;
height: 70px;
width:100%;
position: relative;
align-items: center;
font-size: 2rem;
padding: 1rem;
text-align: center;
}
.pw button{
font-family: inherit;
position: absolute;
top: 0;
right: 0;
transform: translate(0, -20%);
background-color: #FFFFFF;
border: none;
color: #000000;
padding: 0.25rem;
opacity:0;
transition: opacity 0.2s ease, transform 0.2s ease;
cursor: pointer;
}
.pw:hover button {
opacity: 1;
transform: translate(0, -90%)
}
.pw-header {
padding: 1rem;
}
.pw-body {
padding: 0 1rem 1rem;
}
.form-control {
display:flex;
justify-content: space-between;
margin: 0.5rem;
}
.generate {
background-color: #FFFFFF;
display:block;
border: none;
font-size: 1rem;
padding : 0.5rem;
width: 100%;
margin-top: 2rem;
}
.footer {
position: absolute;
top: 1;
bottom: 0;
font-size: 2rem;
width:100%;
background-color:#113537;
text-align: center;
padding: 2rem;
opacity:0;
transition: opacity 0.2s ease;
z-index: 1;
}
.footer-active {
opacity: 1;
transform: translate(0, 0%);
z-index: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Generator</title>
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
</head>
<body>
<div class="pw-container">
<div class="pw-header">
<div class="pw">
<span id="pw">1234</span>
<button id="copy">Copy to clipboard</button>
</div>
</div>
<div class="pw-body">
<div class="form-control">
<label for="len">Length</label>
<input id="len" type="number" min="5" max="20" value="7">
</div>
<div class="form-control">
<label for="upper">Uppercase</label>
<input id="upper" type="checkbox">
</div>
<div class="form-control">
<label for="number">Numbers</label>
<input id="number" type="checkbox">
</div>
<div class="form-control">
<label for="symbol">Symbols</label>
<input id="symbol" type="checkbox">
</div>
<button class="generate" id="generate">
Generate Password
</button>
</div>
</div>
<div id="footer" class="footer">
</div>
</body>
</html>
Note, you no longer need the onkeydown or other event handlers on the input itself in either of these examples

By using event listeners, if the user focuses on the input then blur:
jQuery:
$("input").on("focus", function() {
$(this).blur();
});
Vanilla:
const input = document.querySelector("input#len");
input.addEventListener("focus", function() {
input.blur();
});

Related

Multiple modals on one page only showing 1 modal

This may be a duplicate, but I can't figure this out.
I can't figure out why the same modal is showing for both buttons. I've tried making separate classes for each modal but that didn't work.
// emailmodal.js
var emailModal = document.getElementById("email-modal");
var emailBtn = document.getElementById("email");
var emailSpan = document.getElementsByClassName("email-close")[0];
emailBtn.onclick = function() {
emailModal.style.display = "block";
}
emailSpan.onclick = function() {
emailModal.style.display = "none";
}
window.onclick = function(event) {
if (event.taget == emailModal) {
emailModal.style.display = "none";
}
}
// phonemodal.js
var phoneModal = document.getElementById("phone-modal");
var phoneBtn = document.getElementById("phone");
var phoneSpan = document.getElementsByClassName("phone-close")[0];
phoneBtn.onclick = function() {
phoneModal.style.display = "block";
}
phoneSpan.onclick = function() {
phoneModal.style.display = "none";
}
window.onclick = function(event) {
if (event.taget == phoneModal) {
phoneModal.style.display = "none";
}
}
.fa {
padding: 80px;
font-size: 50px;
width: 50px;
text-align: center;
text-decoration: none;
margin: 10px 10px;
border-radius: 10%;
color: white;
transition: 0.7s;
}
.fa-envelope-o {
background: #199cad;
}
.fa-phone {
background: #121e88;
}
.container {
text-align: center;
padding: 50px;
}
.middle-colour {
color: #00ffff;
}
.email-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);
}
.phone-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);
}
.socials-modal-content {
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 25%;
color: white;
font-size: 20px;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #888888;
text-decoration: none;
cursor: pointer;
}
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="styles/contact.css">
</head>
<body>
<div class="main">
<div class="container">
<div class="socials-3">
<a class="fa fa-envelope-o" id="email" href="#Email"></a>
<div id="email-modal" class="email-modal">
<div class="socials-modal-content">
<span class="close email-close">×</span>
<p>fun<span class="middle-colour">#</span>wbf<span class="middle-colour">.</span>com</p>
</div>
<script src="js/emailmodal.js"></script>
</div>
<a class="fa fa-phone" id="phone" href="#Phone"></a>
<div id="phone-modal" class="phone-modal">
<div class="socials-modal-content">
<span class="close phone-close">×</span>
<p>01234567890</p>
</div>
<script src="js/phonemodal.js"></script>
</div>
</div>
</div>
</div>
</body>
</html>
It's probably something simple but would be a big help if someone can find out the issue.
Edit:
Changed code to snippet.
Try giving your phone element variables their phone element equivalents. Right now they're all referring to email elements.
i.e. change this:
var phoneModal = document.getElementById("email-modal");
var phoneBtn = document.getElementById("email");
var phoneSpan = document.getElementsByClassName("email-close")[0];
to this:
var phoneModal = document.getElementById("phone-modal");
var phoneBtn = document.getElementById("phone");
var phoneSpan = document.getElementsByClassName("phone-close")[0];
Edit
You also have multiple typos: event.taget should be event.target, and you might want to use strict equality (===) instead of normal equality (==). Both equalities will work, however.
Here's a working example based on your code.
You can change the style of socials-modal-content in your CSS file.
For example, define two classes for email and phone like below code:
.socials-modal-content-email {
background-color: rgb(100, 800, 0);
background-color: rgba(0, 0, 0, 0.4);
margin: 15% auto;
padding: 20px;
border: 10px solid #888;
width: 25%;
color: green;
font-size: 30px;
}
.socials-modal-content-phone {
background-color: rgb(1, 0, 0);
background-color: rgba(1, 0, 0, 0.4);
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 25%;
color: white;
font-size: 20px;
}
Then in your HTML file spread both of them like:
<div class="socials-modal-content-email">
<div class="socials-modal-content-phone">
Overall, you can edit and combine your HTML and JS like:
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="styles/contact.css">
</head>
<body>
<div class="main">
<div class="container">
<div class="socials-3">
<a class="fa fa-envelope-o" onclick="show_email()" id="email" href="#Email"></a>
<div id="email-modal" class="email-modal">
<div class="socials-modal-content-email">
<span class="close email-close" onclick="close_eamil()">×</span>
<p>fun<span class="middle-colour">#</span>wbf<span class="middle-colour">.</span>com</p>
</div>
</div>
<a class="fa fa-phone" id="phone" onclick="show_phone()" href="#Phone"></a>
<div id="phone-modal" class="phone-modal">
<div class="socials-modal-content-phone">
<span class="close phone-close" onclick="close_phone()">×</span>
<p>01234567890</p>
</div>
</div>
</div>
</div>-
</div>
</body>
</html>
<script type="text/javascript" >
var emailModal = document.getElementById("email-modal");
var phoneModal = document.getElementById("phone-modal");
function show_email(){
emailModal.style.display = "block";
}
function close_eamil(){
emailModal.style.display = "none";
}
function show_phone(){
phoneModal.style.display = "block";
}
function close_phone(){
phoneModal.style.display = "none";
}
</script>

Vanilla JS budget app delete dynamically rendered income or expense

I've made a budgeting app that has expenses and Income tabs. Every time you add an expense or income, the app pushes the information inside of an array of objects and dynamically renders an <li> component and places it inside of a <ul>. I'm having trouble with the edit and delete features. Each individual <li> comes with a delete and edit button. The <li>, delete button, and edit button all have the same id of Date.now(). Date.now() is used because it produces a number based on milliseconds and won't produce the same id twice unless someone types an expense or income twice within one millisecond I want to click on the delete button inside of the <li> and have my app remove that individual object from my entry_list[] array and also remove the <li> from the DOM.
'use strict'
const balanceElement = document.querySelector(".balance .value");
const totalIncome = document.querySelector(".income-total");
const totalOutcome = document.querySelector(".outcome-total");
const incomeElement = document.querySelector(".income-tab");
const expense = document.querySelector(".expense-tab");
const all = document.querySelector(".all-tab");
const incomeList = document.querySelector(".income-tab .list");
const expenseList = document.querySelector(".expense-tab .list");
const allList = document.querySelector(".all-tab .list");
const expensesButton = document.querySelector(".tab1");
const incomeButton = document.querySelector(".tab2");
const allButton = document.querySelector(".tab3");
const addExpense = document.querySelector(".add-expense")
const expenseTitle = document.querySelector(".expense-title-input")
const expenseAmount = document.querySelector(".expense-amount-input")
const addIncome = document.querySelector(".add-income")
const incomeTitle = document.querySelector(".income-title-input")
const incomeAmount = document.querySelector(".income-amount-input")
const list = document.querySelector('.list')
//SWITCHING BETWEEN TABS
expensesButton.addEventListener('click', () => {
expense.classList.remove('hidden');
incomeElement.classList.add('hidden');
expensesButton.classList.add('clicked');
incomeButton.classList.remove('clicked');
})
incomeButton.addEventListener('click', () => {
incomeElement.classList.remove('hidden');
expense.classList.add('hidden');
expensesButton.classList.remove('clicked');
incomeButton.classList.add('clicked');
})
incomeList.addEventListener('click', deleteOrEdit)
expenseList.addEventListener('click', deleteOrEdit)
let entry_list = []
addExpense.addEventListener('click', () =>{
if(expenseTitle.value == '' || expenseAmount.value == ''){
return;
}
let expense = {
type: 'expense',
title: expenseTitle.value,
amount: expenseAmount.value,
id: Date.now()
}
entry_list.push(expense)
clearExpense()
changeLists()
})
addIncome.addEventListener('click', () =>{
if(incomeTitle.value == '' || incomeAmount.value == ''){
return;
}
let income = {
type: 'income',
title: incomeTitle.value,
amount: incomeAmount.value,
id: Date.now()
}
entry_list.push(income)
clearIncome()
changeLists()
})
const clearExpense = () =>{
expenseTitle.value = '';
expenseAmount.value = '';
}
const clearIncome = () =>{
incomeTitle.value = ''
incomeAmount.value = ''
}
const changeLists = () =>{
expenseList.innerHTML = ''
incomeList.innerHTML = ''
entry_list.map((entry) =>{
if(entry.type == 'expense'){
return expenseList.innerHTML += `<li id = "${entry.id}" class= "${entry.type}">
<div class = "entry">${entry.title}: $${entry.amount}</div>
<div class="icon-container">
<div class = "edit" id="${entry.id}"></div>
<div class ="delete" id="${entry.id}"></div>
</div>
</li>`
}
else if(entry.type == 'income'){
return incomeList.innerHTML += `<li id = "${entry.id}" class= "${entry.type}">
<div class = "entry">${entry.title}: $${entry.amount}</div>
<div class="icon-container">
<div class = "edit" id="${entry.id}"></div>
<div class ="delete" id="${entry.id}"></div>
</div>
</li>`
}
})
addIncomes()
}
const addIncomes = () =>{
let sum = 0;
let income = 0;
let outcome = 0;
balanceElement.innerHTML = 0
totalIncome.innerHTML = 0
totalOutcome.innerHTML = 0
entry_list.forEach(list =>{
if(list.type == 'expense'){
sum -= list.amount
outcome -= list.amount
}else if(list.type == 'income'){
sum += Number(list.amount)
income += Number(list.amount)
}
balanceElement.innerHTML = '$' + sum
totalIncome.innerHTML = '$' + income
totalOutcome.innerHTML = '$' + outcome
})
}
// // DETERMINE IF BUTTON IS EDIT OR DELETE
function deleteOrEdit(e){
const targetButton = e.target;
const entry = targetButton.parentNode.parentNode;
if(targetButton.classList == ('delete')){
deleteEntry(entry)
}else if(targetButton.classList == ('edit')){
editEntry(entry);
}
}
// //DELETE FUNCTION
const deleteEntry = (entry) =>{
console.log(entry.id)
entry_list.splice(entry.id, 1)
// entry.innerHTML = ''
console.log(entry.id)
addIncomes()
}
// EDIT FUNCTION
const editEntry = (entry) =>{
let Entry = entry_list[entry.id]
if(entry.type == "income"){
incomeAmount.value = Entry.amount;
incomeTitle.value = Entry.title;
}else if(entry.type == "expense"){
expenseAmount.value = Entry.amount;
expenseTitle.value = Entry.title;
}
deleteEntry(entry);
}
#import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght#400;700&family=Raleway:wght#400;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Open Sans', sans-serif;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.budget-container{
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100%;
background-color: #4F98CA;
}
.balance-container{
width: 360px;
height: 470px;
background-color: #50D890;
border-radius: 30px;
margin-right: 100px;
}
.app-title{
color: white;
margin-top: 1rem;
margin-left: 1rem;
}
.month{
color: white;
margin-top: 1rem;
text-align: center;
}
.budget-header{
display: flex;
flex-direction:column;
justify-content: center;
}
.balance{
margin-top: 1rem;
margin-left: 1rem;
}
.title{
color: white;
font-size: 1.25rem;
opacity: .75;
}
.value{
font-size: 1.75rem;
color: white;
font-weight: bold;
margin-left: 1rem;
}
.account{
margin-top: 2.5rem;
margin: 2.5rem 1.5rem 2.5rem 1.5rem;
display: flex;
justify-content: space-between
}
.income-total{
color: white;
text-align: center;
font-size: 1.5rem;
}
.outcome-total{
color: #4F98CA;
text-align: center;
font-size: 1.5rem;
}
/* DASHBOARD */
.budget-dashboard{
display: block;
width: 360px;
height: 470px;
position: relative;
border-radius: 30px;
background-color: white;
}
.dash-title{
margin-top: 2rem;
margin-left: 1rem;
font-size: 1.5rem;
}
.toggle{
margin: 1rem;
display: flex;
cursor: pointer;
}
.toggle .tab2, .tab3{
margin-left: 1rem;
cursor: pointer;
}
.clicked{
font-weight: bold !important;
}
.hidden{
display: none !important;
}
/* EXPENSES TAB */
.expense-tab{
display: flex;
justify-content: center;
}
.expense-input-container{
position: absolute;
top: 400px;
border-top: solid 1px gray;
width: 100%;
}
.expense-amount-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.expense-title-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.add-expense{
color: none;
background-color: none;
border: none;
outline: none;
color: inherit;
}
/* INCOME TAB */
.income-tab{
display: flex;
justify-content: center;
}
.income-input-container{
position: absolute;
top: 400px;
border-top: solid 1px gray;
width: 100%;
}
.input{
display: flex;
justify-content: space-between;
align-items: center;
margin: 1rem;
}
.income-amount-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.income-title-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.add-income{
color: none;
background-color: none;
border: none;
outline: none;
}
.plus-img{
width: 40px;
}
/* li */
ul{
width: 360px;
height: 255px;
list-style: none;
margin-top:20px;
overflow-x: auto;
}
/* BUTTON ICONS */
.edit{
background-image: url('media/Icons/icons8-edit-48.png');
background-size: contain;
width: 25px;
height: 25px;
background-repeat: no-repeat;
margin-right: 10px;
}
.delete{
background-image: url('media/Icons/icons8-trash-can-48 (2).png');
background-size: contain;
width:25px;
height: 25px;
background-repeat: no-repeat;
}
.income{
width:250px;
height: auto;
padding-left: 20px;
margin-bottom: 10px;;
word-wrap: break-word;
color: black
}
.expense{
width:250px;
height: auto;
padding-left: 20px;
margin-bottom: 10px;;
word-wrap: break-word;
font-family: 'Gilroy Bold';
color: #4F98CA;
}
li{
display: flex;
justify-content: space-between;
width: 100% !important;
padding-right: 20px;
}
.icon-container{
display: flex;
}
#media (max-width:900px){
.budget-container{
display: inline-block;
position: relative
}
.balance-container{
position: absolute;
top: 10%;
left: 25%;
}
.budget-dashboard{
position: absolute;
left: 25%;
top: 40%;
}
}
<!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="style.css">
<title>Budgetrr</title>
</head>
<body>
<main class="budget-container">
<section class="balance-container">
<div class="app-title">
<p>Budgetrr</p>
</div>
<h1 class="month">OCTOBER</h1>
<section class="budget-header">
<div class="balance">
<div class="title">
Balance
</div>
<div class="value">
<small>$</small>0
</div>
</div>
<div class="account">
<div class="budget-income">
<div class="title">
Income
</div>
<div class="income-total">
<small>$</small>0
</div>
</div>
<div class="chart"></div>
<div class="budgetoutcome">
<div class="title">
Expenses
</div>
<div class="outcome-total">
<small>$</small>0
</div>
</div>
</div>
</section>
</section>
<section class="budget-dashboard">
<div class="dash-title">Dashboard</div>
<div class="toggle">
<div class="tab1 clicked">Expenses</div>
<div class="tab2">Income</div>
<!-- <div class="tab3 clicked">All</div> -->
</div>
<div class="income-tab hidden">
<ul class="list"></ul>
<div class="income-input-container">
<form class="input">
<input type="text" class="income-title-input" name="title" placeholder="Title">
<input type="number" class="income-amount-input" name="amount" placeholder="$0">
<button type = "button" class="add-income"><img class= "plus-img"src="media/Icons/icons8-add-new-48.png" alt=""></button>
</form>
</div>
</div>
<div class = "expense-tab">
<ul class="list"></ul>
<div class="expense-input-container">
<div class="input">
<input type="text" class="expense-title-input" name="title" placeholder="Title">
<input type="number" class="expense-amount-input" name="amount" placeholder="$0">
<button type="button" class="add-expense"><img class= "plus-img" src="media/Icons/icons8-add-new-48.png" alt=""></button>
</div>
</div>
</div>
</section>
</main>
<script src="JavaScript/budget.js"></script>
</body>
</html>
I've tried to use .splice() but I can't seem to get it to work.
Your entry is an object. And entry has an id property with Date type.
Your delete function calls this:
entry_list.splice(entry.id, 1)
Javascript splice function
function takes number as argument(s).
You should find the id of element you want to delete and get its index. After that you can delete the element with splice method.
Here is how to delete:
// Find the index of object at the given list
const index = entry_list.findIndex(x => x.id === entry.id);
// Starting from index of element to delete, remove 1 element.
entry_list.splice(index, 1);

Error return as the JS file is looking for top function in all HTML files

I'm going to keep this simple:
1 JS File
3 HTML Files (named: Cars, Trees, House)
1 CSS files.
All the functions are thrown into the JS file. But the problem is if I click on the submit 'button' in Cars the JS File will start with the (tree's) function at the top and will look for the addEventListener, if it can't find it it will come back with error 'Cannot read property 'addEventListener' of null' - problem is at:
tree_form.addEventListener('submit', e => {
I just want the Js file to execute the function that the HTML file is asking it to.
So in this case its the 'Car' functions that follow the tree functions.
If I separate everything and put it into individual projects or throw the JS in with the referenced HTML file it all works fine, problem occurs only when I put all functions in one JS file.
HTML Cars
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#300;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<title>Car Form</title>
</head>
<body>
<div class="cars-body">
<div class="car_container">
<div class="car_heading_form">
<h2> Car Form</h2>
</div>
<form id="car_form" class="car_form">
<div class="car-form-control">
<label for="carName">Car Name</label>
<input type="text" placeholder="hank" id="carName" />
<i class="fas fa-check-circle"></i>
<i class="fas fa-exclamation-circle"></i>
<small>Error message</small>
</div>
<div class="car-form-control">
<label for="carColor">Car Color</label>
<input type="text" placeholder="Gold" id="carColor" />
<i class="fas fa-check-circle"></i>
<i class="fas fa-exclamation-circle"></i>
<small>Error message</small>
</div>
<button>Submit</button>
</form>
</div>
</div>
</body>
<script src="script.js"></script>
</html>
JS
// Tree Form
const tree_form = document.getElementById('tree_form');
const treeName = document.getElementById('treeName');
const treeHeight = document.getElementById('treeHeight');
tree_form.addEventListener('submit', e => {
e.preventDefault();
tree_Inputs();
});
function tree_Inputs() {
//trim to remove the whitespaces
const treerNameValue = treeName.value.trim();
const treeHeightValue = treeHeight.value.trim();
if (treeNameValue === '') {
setErrorForTree(treeName, 'Please enter a name');
} else {
setSuccessForTree(treeName);
}
if (treeHeightValue === '') {
setErrorForTree(treeHeight, 'Please enter a number.');
} else {
setSuccessForTree(treeHeight);
}
}
function setErrorForTree(input, message) {
const formControlTree = input.parentElement;
const small = formControlTree.querySelector('small');
formControlTree.className = 'tree-form-control error';
small.innerText = message;
}
function setSuccessForTree(input) {
const formControlTree = input.parentElement;
formControlCar.className = 'tree-form-control success';
}
// Car Form
const car_form = document.getElementById('car_form');
const carName = document.getElementById('carName');
const carColor = document.getElementById('carColor');
car_form.addEventListener('submit', e => {
e.preventDefault();
car_Inputs();
});
function car_Inputs() {
//trim to remove the whitespaces
const carNameValue = carName.value.trim();
const carColorValue = carColor.value.trim();
if (carNameValue === '') {
setErrorForCar(carName, 'Please enter a name');
} else {
setSuccessForCar(carName);
}
if (carColorValue === '') {
setErrorForCar(carColor, 'Please a color.');
} else {
setSuccessForCar(carColor);
}
}
function setErrorForCar(input, message) {
const formControlCar = input.parentElement;
const small = formControlCar.querySelector('small');
formControlCar.className = 'car-form-control error';
small.innerText = message;
}
function setSuccessForCar(input) {
const formControlCar = input.parentElement;
formControlCar.className = 'car-form-control success';
}
CSS
/***** CONTACT US PAGE CSS *****/
* {
box-sizing: border-box;
}
.car-body, tree-body {
min-height: 1300px;
width: 100%;
background-color: blue;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin: 0px;
}
.car_container, .tree_container {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 5px rgb(0 0 0 / 30%);
overflow: hidden;
width: 600px;
max-width: 100%;
}
.car_heading_form, .tree_heading_form {
border-bottom: 1px solid #f0f0f0;
background-color: #f7f7f7;
padding: 20px 40px;
}
.car_heading_form h2 {
margin: 0px;
color: Blue;
}
.tree_heading_form h2 {
margin: 0px;
color: green;
}
.car_form, .tree_form {
padding: 30px 40px;
}
.car-form-control, .tree-form-control {
margin-bottom: 10px;
padding-bottom: 20px;
position: relative;
}
.car-form-control label, .tree-form-control label {
display: inline-block;
margin-bottom: 5px;
font-weight: 530;
font-size: 17px;
}
.car-form-control input, .tree-form-control input {
border: 2px solid #f0f0f0;
border-radius: 4px;
display: block;
font-size: 14px;
padding: 10px;
width: 100%;
}
.car-form-control input:focus, .tree-form-control input:focus {
outline: 0;
border-color: #777;
}
.car-form-control.success input, .tree-form-control.success input {
border-color: green;
}
.car-form-control.error input, .tree-form-control.error input {
border-color: red;
}
.car-form-control i, .tree-form-control i {
visibility: hidden;
position: absolute;
top: 40px;
right: 10px;
}
.car-form-control.success i.fa-check-circle, .tree-form-control.success i.fa-check-circle {
color: green;
visibility: visible;
}
.car-form-control.error i.fa-exclamation-circle, .tree-form-control.error i.fa-exclamation-circle {
color: red;
visibility: visible;
}
.car-form-control small, .tree-form-control small {
color: red;
position: absolute;
bottom: 0;
left: 0;
visibility: hidden;
}
.car-form-control.error small, .tree-form-control.error small {
visibility: visible;
}
.car_form button {
background-color: rgb(31, 136, 229);
border: 2px solid rgb(128, 128, 128, 0.199);
border-radius: 4px;
color: #fff;
display: block;
font-size: 16px;
padding: 10px;
margin-top: 20px;
width: 50%;
cursor: pointer;
}
.car_form button:hover {
cursor: pointer;
box-shadow: 1px 1px 1px rgb(25, 60, 173);
}
There are two ways to solve this issue.
I would prefer to create a namespace in JS if there is lots of things I need to add in just a single JS.
var yourNamespace = {
Car: function() {
},
Tree: function() {
},
House: function() {
}
};
and in last call it yourNamespace.Car() when you click on submit.
This is a working scenario:
var yourNamespace = {};
yourNamespace = {
Tree: function() {
const tree_form = document.getElementById('tree_form');
const treeName = document.getElementById('treeName');
const treeHeight = document.getElementById('treeHeight');
tree_form.addEventListener('submit', e => {
e.preventDefault();
tree_Inputs();
});
function tree_Inputs() {
//trim to remove the whitespaces
const treerNameValue = treeName.value.trim();
const treeHeightValue = treeHeight.value.trim();
if (treeNameValue === '') {
setErrorForTree(treeName, 'Please enter a name');
} else {
setSuccessForTree(treeName);
}
if (treeHeightValue === '') {
setErrorForTree(treeHeight, 'Please enter a number.');
} else {
setSuccessForTree(treeHeight);
}
}
function setErrorForTree(input, message) {
const formControlTree = input.parentElement;
const small = formControlTree.querySelector('small');
formControlTree.className = 'tree-form-control error';
small.innerText = message;
}
function setSuccessForTree(input) {
const formControlTree = input.parentElement;
formControlCar.className = 'tree-form-control success';
}
},
Car: function() {
const car_form = document.getElementById('car_form');
const carName = document.getElementById('carName');
const carColor = document.getElementById('carColor');
car_form.addEventListener('submit', e => {
e.preventDefault();
car_Inputs();
});
function car_Inputs() {
//trim to remove the whitespaces
const carNameValue = carName.value.trim();
const carColorValue = carColor.value.trim();
if (carNameValue === '') {
setErrorForCar(carName, 'Please enter a name');
} else {
setSuccessForCar(carName);
}
if (carColorValue === '') {
setErrorForCar(carColor, 'Please a color.');
} else {
setSuccessForCar(carColor);
}
}
function setErrorForCar(input, message) {
const formControlCar = input.parentElement;
const small = formControlCar.querySelector('small');
formControlCar.className = 'car-form-control error';
small.innerText = message;
}
function setSuccessForCar(input) {
const formControlCar = input.parentElement;
formControlCar.className = 'car-form-control success';
}
},
House: function() {
}
};
* {
box-sizing: border-box;
}
.car-body, tree-body {
min-height: 1300px;
width: 100%;
background-color: blue;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin: 0px;
}
.car_container, .tree_container {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 5px rgb(0 0 0 / 30%);
overflow: hidden;
width: 600px;
max-width: 100%;
}
.car_heading_form, .tree_heading_form {
border-bottom: 1px solid #f0f0f0;
background-color: #f7f7f7;
padding: 20px 40px;
}
.car_heading_form h2 {
margin: 0px;
color: Blue;
}
.tree_heading_form h2 {
margin: 0px;
color: green;
}
.car_form, .tree_form {
padding: 30px 40px;
}
.car-form-control, .tree-form-control {
margin-bottom: 10px;
padding-bottom: 20px;
position: relative;
}
.car-form-control label, .tree-form-control label {
display: inline-block;
margin-bottom: 5px;
font-weight: 530;
font-size: 17px;
}
.car-form-control input, .tree-form-control input {
border: 2px solid #f0f0f0;
border-radius: 4px;
display: block;
font-size: 14px;
padding: 10px;
width: 100%;
}
.car-form-control input:focus, .tree-form-control input:focus {
outline: 0;
border-color: #777;
}
.car-form-control.success input, .tree-form-control.success input {
border-color: green;
}
.car-form-control.error input, .tree-form-control.error input {
border-color: red;
}
.car-form-control i, .tree-form-control i {
visibility: hidden;
position: absolute;
top: 40px;
right: 10px;
}
.car-form-control.success i.fa-check-circle, .tree-form-control.success i.fa-check-circle {
color: green;
visibility: visible;
}
.car-form-control.error i.fa-exclamation-circle, .tree-form-control.error i.fa-exclamation-circle {
color: red;
visibility: visible;
}
.car-form-control small, .tree-form-control small {
color: red;
position: absolute;
bottom: 0;
left: 0;
visibility: hidden;
}
.car-form-control.error small, .tree-form-control.error small {
visibility: visible;
}
.car_form button {
background-color: rgb(31, 136, 229);
border: 2px solid rgb(128, 128, 128, 0.199);
border-radius: 4px;
color: #fff;
display: block;
font-size: 16px;
padding: 10px;
margin-top: 20px;
width: 50%;
cursor: pointer;
}
.car_form button:hover {
cursor: pointer;
box-shadow: 1px 1px 1px rgb(25, 60, 173);
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#300;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="cars-body">
<div class="car_container">
<div class="car_heading_form">
<h2> Car Form</h2>
</div>
<form id="car_form" class="car_form">
<div class="car-form-control">
<label for="carName">Car Name</label>
<input type="text" placeholder="hank" id="carName" />
<i class="fas fa-check-circle"></i>
<i class="fas fa-exclamation-circle"></i>
<small>Error message</small>
</div>
<div class="car-form-control">
<label for="carColor">Car Color</label>
<input type="text" placeholder="Gold" id="carColor" />
<i class="fas fa-check-circle"></i>
<i class="fas fa-exclamation-circle"></i>
<small>Error message</small>
</div>
<button onClick="yourNamespace.Car()">Submit</button>
</form>
</div>
</div>
check on id which form is currently visible (not preferable in your situation, better to use features that JS provide)
It seems you're expecting the JavaScript to magically know which form it's on and which code to run. Sorry. JavaScript is not magic.
Try something like
const tree_form = document.getElementById('tree_form');
const car_form = document.getElementById('car_form');
if (tree_form) {
// all the tree code
}
else if (car_form) {
// all the car code
}
If you hit the submit button a second time with no value in the other input field then the message has to be shown correct. This is the javascript for the car without your css.
// Car Form
const car_form = document.getElementById('car_form');
const carName = document.getElementById('carName');
const carColor = document.getElementById('carColor');
car_form.addEventListener('submit', e => {
e.preventDefault();
car_Inputs();
});
function car_Inputs() {
//trim to remove the whitespaces
const carNameValue = carName.value.trim();
const carColorValue = carColor.value.trim();
setErrorForCar(carName, 'Message');
if (carNameValue === '') {
setErrorForCar(carName, 'Please enter a name');
} else {
setSuccessForCar(carName);
}
setErrorForCar(carColor, 'Message');
if (carColorValue === '') {
setErrorForCar(carColor, 'Please enter a color.');
} else {
setSuccessForCar(carColor);
}
}
function setErrorForCar(input, message) {
const formControlCar = input.parentElement;
const small = formControlCar.querySelector('small');
formControlCar.className = 'car-form-control error';
small.innerText = message;
}
function setSuccessForCar(input) {
const formControlCar = input.parentElement;
formControlCar.className = 'car-form-control success';
}
<div class="cars-body">
<div class="car_container">
<div class="car_heading_form">
<h2> Car Form</h2>
</div>
<form id="car_form" class="car_form">
<div class="car-form-control">
<label for="carName">Car Name</label>
<input type="text" placeholder="hank" id="carName" />
<i class="fas fa-check-circle"></i>
<i class="fas fa-exclamation-circle"></i>
<small>Message</small>
</div>
<div class="car-form-control">
<label for="carColor">Car Color</label>
<input type="text" placeholder="Gold" id="carColor" />
<i class="fas fa-check-circle"></i>
<i class="fas fa-exclamation-circle"></i>
<small>Message</small>
</div>
<button>Submit</button>
</form>
</div>
</div>

Autofocus after <input> and again after all inputs

Creating a check for entered numbers on the right div with random numbers on the left div
I don't understand how to make sure that:
after entering smth in the first input, it must focus on the second and etc.
And how after all filled inputs, it must focus again on the first input
sorry for my english
do not offer jquery, please
'use strict';
let codeNum = document.querySelectorAll('.codeNumber'),
inputNum = document.querySelectorAll('input');
function randomCode() {
codeNum.forEach(function(item) {
item.textContent = randomInteger(0, 9);
})
function randomInteger(min, max) {
// получить случайное число от (min-0.5) до (max+0.5)
let rand = min - 0.5 + Math.random() * (max - min + 1);
return Math.round(rand);
}
}
randomCode();
let new1 = [];
let new2 = [];
function checkInput() {
for (var i=0;i<codeNum.length;i++) {
new1[i] = codeNum[i].innerHTML;
new2[i] = inputNum[i].value;
}
if (JSON.stringify(new1)==JSON.stringify(new2)) {
randomCode();
}
console.log(JSON.stringify(new1));
console.log(JSON.stringify(new2));
}
for (var i=0;i<codeNum.length;i++) {
inputNum[i].addEventListener('input', checkInput)
}
#import url('https://fonts.googleapis.com/css?family=Raleway:200');
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: space-around;
height: 100%;
background: #1D1F20;
}
.text {
width: 25px;
height: 47px;
border: 1px solid #a7a7a7;
border-radius: 4px;
background-color: #1D1F20;
outline: none;
font-size: 2.5rem;
font-family: 'Raleway';
text-align: center;
color: #fff;
vertical-align: middle;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
/* display: none; <- Crashes Chrome on hover */
-webkit-appearance: none;
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}
span {
position: absolute;
top: 6%;
}
#box {
display: flex;
align-items: center;
justify-content: space-around;
width: 400px;
height: 200px;
color: white;
font-family: 'Raleway';
font-size: 2.5rem;
}
.gradient-border {
--borderWidth: 3px;
background: #1D1F20;
position: relative;
border-radius: var(--borderWidth);
}
.gradient-border:after {
content: '';
position: absolute;
top: calc(-1 * var(--borderWidth));
left: calc(-1 * var(--borderWidth));
height: calc(100% + var(--borderWidth) * 2);
width: calc(100% + var(--borderWidth) * 2);
background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
border-radius: calc(2 * var(--borderWidth));
z-index: -1;
animation: animatedgradient 3s ease alternate infinite;
background-size: 300% 300%;
}
#keyframes animatedgradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pin-Pan! by Asad</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="gradient-border" id="box">
<div class="numbers codeNumber">1</div>
<div class="numbers codeNumber">1</div>
<div class="numbers codeNumber">1</div>
<div class="numbers codeNumber">1</div>
</div>
<div class="gradient-border box-2" id="box">
<span>password:</span>
<div class="numbers">
<input type="number" autofocus class="text" maxlength="1" pattern="/^-?\d+\.?\d*$/" onKeyPress="if(this.value.length==1) return false;">
</div>
<div class="numbers">
<input type="number" class="text" maxlength="1" pattern="/^-?\d+\.?\d*$/" onKeyPress="if(this.value.length==1) return false;">
</div>
<div class="numbers">
<input type="number" class="text" maxlength="1" pattern="/^-?\d+\.?\d*$/" onKeyPress="if(this.value.length==1) return false;">
</div>
<div class="numbers">
<input type="number" class="text" maxlength="1" pattern="/^-?\d+\.?\d*$/" onKeyPress="if(this.value.length==1) return false;">
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>
I’m not sure if I understood you question, but here’s my approach:
I’ d use recursive functions to ensure it’s called after the user did something:
function rec(num){
if (num<NumberOfElements){
let el=document.querySelectorAll(".text")[num]//select current element
el.addEventListener("input", function(){//check for input
//do something
//. /do something
num++
rec(num)//recall the recursive function (“loop again”)
}
}}
I didn’t tried the code and you’ll have to customise this for your needs.

Dynamically Create a Modal for a Note Taker App

I am working on a simple note taking app using vanilla javascript. I am trying to have the program add the note with a modal that when clicked would show the text. With what I have so far it is adding the note below the input box and along with the modal button. When I click the modal button it does nothing the first click. On the second click the text and modal button disappear.
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Note Tracker</title>
<style>
body {font-family: Arial, Helvetica, sans-serif;}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
/* The Close Button */
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.success {
background-color: #ddffdd;
border-left: 6px solid #4CAF50;
}
</style>
</head>
<body>
<h1>Note Tracker Web App</h1>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<label for="iNote">Input Note:</label><br>
<br>
<textarea id="inote" name="inote" rows="4" cols="50">
</textarea>
<br>
<button type="button" id="btn" onclick="addNote()">Add Note</button>
<br><br>
<div id="noteList">
<span class="close">×</span>
</div>
<script src="scripts.js"></script>
</body>
Javascript is the below that creates the note and then add it along with the modal
function addNote(){
var item = document.getElementById("inote").value
var text = document.createTextNode(item)
var newItem = document.createElement("P")
newItem.appendChild(text)
document.getElementById("noteList").appendChild(newItem)
var x = document.createElement("BUTTON");
x.id = "someId";
//x.onclick ="modalOpen()";
x.onclick = function(){
var modal = document.getElementById("noteList");
var btn = document.getElementById("someId");
btn.onclick = function() {
modal.style.display = "none";
}
};
var t = document.createTextNode("Open Modal");
x.appendChild(t);
document.getElementById("noteList").appendChild(x);
var z = document.createElement("BR");
document.getElementById("noteList").appendChild(z);
var newElem = document.createElement("BR");
document.getElementById("noteList").appendChild(newElem);
}
on first time, you are just attach event listener of click, simply put x.onclick outside the function
Hopefully this one will help.
So we have the "note-list" to handle the list.
I create a modal element that can activate when we click on the "new note" button.
In here I play with opacity and z-index to show this modal. Can be better than this.
const newNote = document.getElementById('new-note'),
addNote = document.getElementById('add-note');
let myModal = document.getElementById('my-modal');
newNote.addEventListener('click', () => {
myModal.style.zIndex = 99;
myModal.style.opacity = 1;
});
addNote.addEventListener('click', () => {
let note = document.getElementById('note'),
noteList = document.getElementById('note-list');
if (note.value !== '') {
let _el = document.createElement('li');
_el.innerHTML = note.value;
let _a = document.createElement('a');
_a.innerHTML = 'delete';
_el.appendChild(_a);
noteList.appendChild(_el);
note.value = '';
myModal.style.zIndex = -1;
myModal.style.opacity = 0;
_a.addEventListener('click', (e) => {
e.target.parentNode.remove();
});
} else {
alert('note can not empty');
}
});
#my-modal {
width: 100%: height: 100%;
z-index: -1;
opacity: 0;
position: absolute;
background: rgba(0, 0, 0, 0.5);
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.modal-wrapper {
border-radius: .5rem;
background: #fff;
display: block;
padding: 1rem;
margin-top: 20%;
}
ul {
display: block;
}
#note-list li {
display: block;
margin-bottom: .5rem;
border: 1px solid #efefef;
background: #f7f7f7;
border-radius: .5rem;
position: relative;
padding: 1rem;
width: 70%;
}
#note-list li a{
position: absolute;
right: 0;
top: 0;
background: tomato;
padding: 1rem;
color: #fff;
}
.modal-wrapper * {
display: block;
margin: .5rem auto;
width: 90%;
text-align: center;
}
<h1>Note Taker App</h1>
<div class="note-wrapper">
<ul id="note-list">
</ul>
<button id="new-note">New Note</button>
</div>
<div id="my-modal">
<div class="modal-wrapper">
<label for="note">Your Note</label>
<input type="text" name="note" id="note">
<button id="add-note">add note</button>
</div>
</div>

Categories