Range addEventListner Input Updating too frequently - javascript

I am new to JavaScript for context.
I want to have a web page where the user has a base number, which is an input and can have unlimited subtractors, or "sources", that will bring the number down. It's like the user is listing all of his or her sources to pay for something expensive. Each source will have a name and a range, which goes from -100 to 100.
The problem with it is that it takes every change in input as a potential source, but I want only the value of the ranges to be sourced. In other words, if the user has added five ranges, then I only want there to be five subtractors/sources.
Is there anything I could do to make this change happen? It also may be helpful to know that when I change the event listener to 'mouseDown' the same thing happens.
Here is everything I have written.
const addBtn = document.querySelector(".solvePlusLogo")
function addSolvr() {
solvContain = document.querySelector('.solveContainer')
const solvDiv= document.createElement('div');
solvContain.appendChild(solvDiv);
const solvLabel = document.createElement('input');
solvDiv.appendChild(solvLabel);
const solvRange = document.createElement('input');
solvRange.type = "range";
solvRange.className = "range"
solvDiv.appendChild(solvRange);
}
addBtn.addEventListener('click', addSolvr)
let full = document.querySelector("#numInput").value
document.addEventListener('input', function(event) {
if(event.target.matches(".range")) {
const subtractors = []
subtractors.push(event.target.value)
for(let x of subtractors) {
full -= x
}
document.querySelector("#numDisplay").innerHTML = full
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<input type="number" id="numInput">
<h3 id="numDisplay">
$0
</h3>
<div class="solveContainer" style="font-family: 'IBM Plex Mono', momnospace;">
<div class="solveIntro">
<button class="solvePlusLogo">Add Source
</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

Every time the range changes, you're subtracting its current value from full. But full has previously had a different range value subtracting, so these subtractions are accumulating.
You need to get the current value of #numInput and subtract the range value from it.
Your subtractors array will just contain the value of the current range input. You need to loop over all the ranges and combine them.
const addBtn = document.querySelector(".solvePlusLogo")
function addSolvr() {
solvContain = document.querySelector('.solveContainer')
const solvDiv = document.createElement('div');
solvContain.appendChild(solvDiv);
const solvLabel = document.createElement('input');
solvDiv.appendChild(solvLabel);
const solvRange = document.createElement('input');
solvRange.type = "range";
solvRange.className = "range"
solvDiv.appendChild(solvRange);
}
addBtn.addEventListener('click', addSolvr)
document.addEventListener('input', function(event) {
if (event.target.matches(".range")) {
let full = document.querySelector("#numInput").value
const subtractors = document.querySelectorAll(".range");
subtractors.forEach(subtractor => full -= subtractor.value)
document.querySelector("#numDisplay").innerHTML = full
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<input type="number" id="numInput">
<h3 id="numDisplay">
$0
</h3>
<div class="solveContainer" style="font-family: 'IBM Plex Mono', momnospace;">
<div class="solveIntro">
<button class="solvePlusLogo">Add Source
</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

Related

Input Value showing as undefined

I'm fairly new to javascript and trying to make a simple To Do list work. I have the basic functionality down, but I'm trying to understand why the input value in my code is returning undefined?
The remove button adds just fine, so I know the function is working.
<!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="css/main.css" />
<title>To Do List</title>
</head>
<body>
<div class="content__container">
<div class="list__container">
<div class="header__container">
<h1 class="header__title">TO DO LIST</h1>
<input id="header__input" type="text" />
<button class="header__button">Add</button>
</div>
<div class="list__content"></div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
const btn = document.querySelector(".header__button");
const listContent = document.querySelector(".list__content");
let input = document.getElementById("header__input").value;
function addItem() {
const toDoItem = document.createElement("li");
const text = document.createTextNode(input);
const remove = document.createElement("button");
remove.textContent = "remove";
remove.classList.add("list__remove");
toDoItem.classList.add("list__items");
toDoItem.appendChild(text);
toDoItem.appendChild(remove);
listContent.appendChild(toDoItem);
}
btn.addEventListener("click", addItem);
Your script is getting the input value only when it start and not when the function is called.
const btn = document.querySelector(".header__button");
function addItem() {
const listContent = document.querySelector(".list__content");
let input = document.getElementById("header__input").value;
const toDoItem = document.createElement("li");
const text = document.createTextNode(input);
const remove = document.createElement("button");
remove.textContent = "remove";
remove.classList.add("list__remove");
toDoItem.classList.add("list__items");
toDoItem.appendChild(text);
toDoItem.appendChild(remove);
listContent.appendChild(toDoItem);
}
btn.addEventListener("click", addItem);
Moving listContent and the input variable into the function will ensure that you get the values ​​every time the function is executed.

How can I change the display a message depending on which number the user has selected?

I want when somebody input a number lower than 4.2, my app shows message as result, but i can't make it happen.
I already tried with return.
JS code
let resultEl = document.getElementById("results")
let numberEl = document.getElementById("number__select")
let message = "mAs: 0.5 y kV: 1.0"
function calculate() {
if (numberEl <= 4.2) {
resultEl.textContent = message;
} else {
resultEl.textContent = "error"
}
}
HTML code
<!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="styleRx.css"/>
<script src="Rxappjs.js"></script>
<title>HVDN Rx app</title>
</head>
<body>
<div class="container">
<header>
<h1>Valoraciones de Rx</h1>
</header>
<div class="box">
<form action="">
<div class="values">
<label for="peso" id="peso__label">Peso</label>
<input class="text__input" type="number" step="0.1" id="number__select" placeholder="Peso"
min="0" required>
</div>
<button id="calcular" onclick="calculate()">Calcular</button>
</form>
<p id="results"></p>
</div>
</div>
</body>
</html>
You have the variable numberEl set to an html element and therefor it will never be less than or equal too 4.2. Try to get the value of that element instead:
let resultEl = document.getElementById("results")
let numberEl = document.getElementById("number__select")
let message = "mAs: 0.5 y kV: 1.0"
function calculate() {
if (numberEl.value <= 4.2) {
resultEl.textContent = message;
} else {
resultEl.textContent = "error"
}
}

todos list with a saved array and then retrieve it stuck?

i started an app todoslist , after creating first code simply of adding new todos in DOM
now my task is this :
addtodo :
// grab todo value
// pu tit in the array
// tell the draw method to redraw the todos
drawtodo :
grab the array
for each text add a todo entry in the documen
the array
my html code
<!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" type="text/css" href="style.css">
<title>TodoList</title>
</head>
<body>
<div class="todolist_box">
<h3> To Do List </h3>
<div class="input">
<input type="text" id ="inp" placeholder="Add new Task">
<button onclick="newTodo()" ><i> enter </i></button>
<button onclick="newTodo()" ><i> save </i></button>
<button onclick="drawtodo()" ><i> load </i></button>
</div>
<ul id="myUL">
</ul>
</div>
<script src="script.js" type="application/javascript"></script>
</body>
</html>
and this is my javascript code
function newElement() {
// this code doesn't work, but it gives you an idea
const li = document.createElement("li")
const newEntry = document.getElementById("inp").value
const u = document.createTextNode(newEntry)
li.appendChild(u)
document.getElementById("myUL").appendChild(li)
document.getElementById("inp").value = "Nothing"
// something like thi
let todos = []
function newTodo() {
let inpvalue = document.getElementById('inp').value
todos.push(inpvalue)
// trigger draw event
}
function drawtodo() {
for (var i = todos.length - 1; i >= 0; i--) {
let li = document.createElement('li')
let newlist = li.appendChild(document.createTextNode(todos[i]))
inpvalue.appendChild(newlist)
}
}
document.onload = function() {
// this will excute when the document loads
}
}
Try using Javascript event listener instead of onclick attribute in html.
HTML:
<button id="load" ><i> load </i></button> // Removed onclick attribute
JS:
document.getElementById("load").addEventListener("click", drawtodo, false);
same with enter and save buttons, when click triggers the newTodo function.

input field won't clear up

I can't clear up my input field even tho i followed a tutorial step by step , i'm making this to do list and I want the input field to be clear anytime i submit a new to do . so what is wrong with my code ?
ps : i tried to clear the cache and nothing
let addButton=document.getElementById('addButton');
let toDoContainer = document.getElementById('ToDoContainer');
let inputField = document.getElementById('text');
//event listeners
addButton.addEventListener('click',addTodo);
//functions
function addTodo(event,title){
event.preventDefault();
//create the to do
let toDoDiv = document.createElement('div');
toDoDiv.classList.add('todo');
const newToDo =document.createElement('p');
newToDo.innerHTML=inputField.value;
newToDo.classList.add('todo-item');
toDoDiv.appendChild(newToDo);
toDoContainer.appendChild(toDoDiv);
//check mark button
const completedButton = document.createElement('button');
completedButton.innerHTML="success";
completedButton.classList.add("complete-btn");
toDoDiv.appendChild(completedButton);
//check delete button
const trashButton = document.createElement('button');
trashButton.innerHTML="delete";
trashButton.classList.add("complete-btn");
toDoDiv.appendChild(trashButton);
//append todo
toDoContainer.appendChild(tododiv);
inputField.value= "";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>to do list </title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<header>
<h1>This is your to do list </h1>
<div class="input">
<input type="text" placeholder="what to do ...?" id="text">
<input type="button" value="add" id="addButton">
</div>
</header>
<div id="ToDoContainer">
</div>
</div>
<script src="./script.js"></script>
</body>
</html>
here is a screenshot
sonEtLumiere is right, you have a typo. It should be:
toDoContainer.appendChild(toDoDiv);
Your variable is called toDoDiv, you have an error in this line (penultimate line):
toDoContainer.appendChild(tododiv);
This will work:
toDoContainer.appendChild(toDoDiv);

Add dynamic tags in js

Hope you are doing well.
I have an input and when I enter a number and press on button it should create *x p tags. When I update the value of input and press on button it should display new *x p tags but it does not remove the previous value and adds new one. Here is my code.
Thank you!
create.addEventListener("click" , () => {
let inp = inp1.value
for(let i = 0; i < inp ; i++){
let newELement = document.createElement("p")
newELement.innerHTML = i+1
document.body.append(newELement)
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" name="" id="inp1">
<br>
<button id="create">Create</button>
</body>
<script src="script.js"></script>
</html>
For this particular scenario , you can use a common class for all the creating elements
By doing this , we can get all the existing elements of that particular class and remove it in a single step.
create.addEventListener("click" , () => {
document.querySelectorAll('.nums').forEach(e => e.remove());
let inp = inp1.value
for(let i = 0; i < inp ; i++){
let newELement = document.createElement("p")
newELement.className += " " + "nums";
newELement.innerHTML = i+1
document.body.append(newELement)
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" name="" id="inp1">
<br>
<button id="create">Create</button>
</body>
<script src="script.js"></script>
</html>
As I see it, when a user clicks Create, you want to:
Remove the previous tags, if any exist
Create and add the new tags
You've gotten step 2 down already, but you just need to remove the tags before you render the new ones, to get your desired output.
The easiest way to do this would be to, instead of placing the tags directly in the body, place them in a separate div, specifically for tags. Then you just empty that div when Create is clicked.
So, in your HTML, you add a div specifically for the tags:
<body>
<input type="text" name="" id="inp1">
<br>
<button id="create">Create</button>
<div id="tags"></div>
</body>
<script src="script.js"></script>
...and, in your JS, you just place the tags in that div, instead of the body, whilst emptying it every time Create is clicked:
let tags = document.getElementById("tags")
create.addEventListener("click" , () => {
let inp = inp1.value
tags.innerHTML = "" // empty tags div first
for(let i = 0; i < inp ; i++){
let newELement = document.createElement("p")
newELement.innerHTML = i+1
tags.append(newELement) // add to tags div, not body
}
})
Run and edit this code online

Categories

Resources