简体   繁体   中英

Character counter in input field not working - Javascript

I am playing around with a little project as I am learning JS and I made a plate calculator.

Long story short, you enter your name and every letter costs 5 dollars, so your name's length * 5 dollars = cost of the plate. (little project seen on "Javascript & Jquery" book by Jon Duckett).

As said in the title, I can't seem to get the input's value lenght. When I click on calculate button I get 'Your plate costs NaN dollars'.

I'm pretty sure I'm doing something stupidly obvious, but can't figure out what. .length seemed like the most logical option to me.

Also , why in the event listener for the refresh button, when I tried writing personName = '' didn't work, but when I wrote document.querySelector('.input').value = ''; worked? Why it didn't accept the variable declared at the beggining?

Here the JS code

let personName = document.querySelector('.input').value;
let btn = document.querySelector('.button')
let cost = document.querySelector('.cost')
let yourPlate = document.querySelector('.yourplate')
let refresh = document.querySelector('.refresh')


btn.addEventListener('click', () => {
    cost.innerText = personName.lenght * 5;
    yourPlate.classList.add('show')
})

refresh.addEventListener('click', ()=> {
  document.querySelector('.input').value = '';
  yourPlate.classList.remove('show')
})

And HERE the snippet

 let personName = document.querySelector('.input').value; let btn = document.querySelector('.button') let cost = document.querySelector('.cost') let yourPlate = document.querySelector('.yourplate') let refresh = document.querySelector('.refresh') btn.addEventListener('click', () => { cost.innerText = personName.lenght * 5; yourPlate.classList.add('show') }) refresh.addEventListener('click', ()=> { document.querySelector('.input').value = ''; yourPlate.classList.remove('show') })
 * { margin: 0; padding: 0; box-sizing: border-box; font-family: verdana; } body { background: url('utah2.jpg'); background-size: cover; background-repeat: no-repeat; height: 100vh; background-blend-mode: darken; } .body { position: absolute; width: 100vw; height: 100vh; background: rgba(20,0,0,.5); } .container { height: 55vh; min-width: 90vw; padding: 30px; display: flex; flex-direction: column; justify-content: space-between; align-items: center; text-align: center; padding-top: 20px; background: url('utah.jpg'); background-size: cover; background-position: fixed; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border-radius: 20px; box-shadow: 3px 3px 10px black; } .calculate { display: flex; flex-direction: column; justify-content: space-around; align-items: center; padding-bottom: 20px; width: 100%; } .yourplate { color: white; text-shadow: 0 0 10px black, 0 0 10px black; font-size: 1.4em; position: absolute; top: 43%; display: none; } .yourplate.show { display: block; } .cost { color: white; text-shadow: 0 0 10px black, 0 0 10px black; font-size: 1.8em; } h1 { border-bottom: 1px solid black; } h3 { position: relative; top:-25px; } .input { outline: none; border: none; border-radius: 5px; height: 2em; width: 70%; } .button { padding: .5em 1em; border-radius: 5px; border: none; background: white; box-shadow: 3px 3px 10px rgba(0,0,0,.5); outline: none; font-size: .9em; letter-spacing: .5px; } .refresh { padding: .5em 1em; border-radius: 5px; border: none; background: white; box-shadow: 3px 3px 10px rgba(0,0,0,.5); outline: none; font-size: .9em; letter-spacing: .5px; position: relative; top: 20px; background: lightgreen; } .button:active { transform: scale(.95); background: rgba(0,147,255,0.5); outline: none; } .dot1, .dot2, .dot3, .dot4 { width: 15px; height: 15px; background: radial-gradient(rgba(150,150,150,.7), rgba(50,50,50)); border-radius: 50%; position: absolute; box-shadow: 1px 1px 5px black, 0 0 10px rgb(183, 65, 14); } .dot1 { top: 20px; left: 20px; } .dot2 { bottom: 20px; right: 20px; } .dot3 { bottom: 20px; left: 20px; } .dot4 { top: 20px; right: 20px; }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <title>Plate Cost</title> </head> <body> <div class="body"></div> <div class="container"> <div class="dot1"></div> <div class="dot2"></div> <div class="dot3"></div> <div class="dot4"></div> <h1>PLATE CALCULATOR</h1> <h3>Enter your name and calculate the cost</h3> <p class="yourplate">Your plate costs <span class="cost"></span> dollars</p> <div class="calculate"> <input type="text" class="input"><br> <button type="submit" class="button">Calculate</button> <button class="refresh">Refresh</button> </div> </div> <script src="main.js"></script> </body> </html>

There are a couple of problems with your code.

  1. You need to wait for the DOM ready event. That is the point when you can start to query the DOM.
  2. You are querying the personName value on the start of your script (so it's always empty), but in fact you should do it when you click the button.
  3. You had a typo in code (length not lenght)

 document.onreadystatechange = function () { if (document.readyState === 'interactive') { let personName = document.querySelector('.input'); let btn = document.querySelector('.button') let cost = document.querySelector('.cost') let yourPlate = document.querySelector('.yourplate') let refresh = document.querySelector('.refresh') btn.addEventListener('click', () => { cost.innerText = personName.value.length * 5; yourPlate.classList.add('show') }) refresh.addEventListener('click', ()=> { document.querySelector('.input').value = ''; yourPlate.classList.remove('show') }) } }
 * { margin: 0; padding: 0; box-sizing: border-box; font-family: verdana; } body { background: url('utah2.jpg'); background-size: cover; background-repeat: no-repeat; height: 100vh; background-blend-mode: darken; } .body { position: absolute; width: 100vw; height: 100vh; background: rgba(20,0,0,.5); } .container { height: 55vh; min-width: 90vw; padding: 30px; display: flex; flex-direction: column; justify-content: space-between; align-items: center; text-align: center; padding-top: 20px; background: url('utah.jpg'); background-size: cover; background-position: fixed; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); border-radius: 20px; box-shadow: 3px 3px 10px black; } .calculate { display: flex; flex-direction: column; justify-content: space-around; align-items: center; padding-bottom: 20px; width: 100%; } .yourplate { color: white; text-shadow: 0 0 10px black, 0 0 10px black; font-size: 1.4em; position: absolute; top: 43%; display: none; } .yourplate.show { display: block; } .cost { color: white; text-shadow: 0 0 10px black, 0 0 10px black; font-size: 1.8em; } h1 { border-bottom: 1px solid black; } h3 { position: relative; top:-25px; } .input { outline: none; border: none; border-radius: 5px; height: 2em; width: 70%; } .button { padding: .5em 1em; border-radius: 5px; border: none; background: white; box-shadow: 3px 3px 10px rgba(0,0,0,.5); outline: none; font-size: .9em; letter-spacing: .5px; } .refresh { padding: .5em 1em; border-radius: 5px; border: none; background: white; box-shadow: 3px 3px 10px rgba(0,0,0,.5); outline: none; font-size: .9em; letter-spacing: .5px; position: relative; top: 20px; background: lightgreen; } .button:active { transform: scale(.95); background: rgba(0,147,255,0.5); outline: none; } .dot1, .dot2, .dot3, .dot4 { width: 15px; height: 15px; background: radial-gradient(rgba(150,150,150,.7), rgba(50,50,50)); border-radius: 50%; position: absolute; box-shadow: 1px 1px 5px black, 0 0 10px rgb(183, 65, 14); } .dot1 { top: 20px; left: 20px; } .dot2 { bottom: 20px; right: 20px; } .dot3 { bottom: 20px; left: 20px; } .dot4 { top: 20px; right: 20px; }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <title>Plate Cost</title> </head> <body> <div class="body"></div> <div class="container"> <div class="dot1"></div> <div class="dot2"></div> <div class="dot3"></div> <div class="dot4"></div> <h1>PLATE CALCULATOR</h1> <h3>Enter your name and calculate the cost</h3> <p class="yourplate">Your plate costs <span class="cost"></span> dollars</p> <div class="calculate"> <input type="text" class="input"><br> <button type="submit" class="button">Calculate</button> <button class="refresh">Refresh</button> </div> </div> <script src="main.js"></script> </body> </html>

Just need some minor changes to your addEventListener . Your personName.length had spelling issues :

btn.addEventListener('click', () => {
    cost.innerText = personName.length * 5;
    yourPlate.classList.add('show');
});

Also it is better for long term to try to name all of your functions so that maintaining the code will be easier later on :

const calculatePrice = () => {
    cost.innerText = personName.length * 5;
    yourPlate.classList.add('show');
}
btn.addEventListener('click',calculatePrice, false);

I also assumed that you have already added the jQuery library to your project.

You shloud place this:

let personName = document.querySelector('.input').value;

in your Method:

btn.addEventListener('click', () => {

Because else it will be executed on site load (where it will be empty)

EDIT

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM