Troubleshooting a Dysfunctioning Character Counter Feature in a JavaScript Input Field

I've been working on a fun little project to practice my JavaScript skills - a plate calculator.

Here's the gist: you enter your name, and each letter costs $5, so the total cost of the plate is the length of your name multiplied by $5 (this project was inspired by the "Javascript & Jquery" book by Jon Duckett).

But, I've run into a problem that I can't seem to solve. Whenever I click the calculate button, I get 'Your plate costs NaN dollars'.

I'm convinced I'm missing something obvious, but I just can't figure it out. I thought using .length was the logical choice.

Another thing, I'm curious why, when I tried setting personName = '' in the event listener for the refresh button, it didn't work. However, when I used

document.querySelector('.input').value = '';
, it did work. Why couldn't it recognize the variable declared at the beginning?

Here is the JavaScript code 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')
})

And here's the HTML code snippet:

<!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>

Answer №1

Here are a few issues in your code that need to be addressed:

  1. Make sure to wait for the DOM ready event before querying the DOM.
  2. Query the value of personName when the button is clicked, not at the start of the script.
  3. Fix the typo in the code (it should be "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">
...
</html>

Answer №2

Just a few tweaks needed to your addEventListener. The personName.length had a few spelling errors:

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

It's also a good idea for future maintenance to give all your functions meaningful names:

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

I assumed you've already included the jQuery library in your project.

Answer №3

Make sure to insert the following code snippet:

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

within your function:

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

This is crucial to prevent it from being triggered upon page load (when the input field will be empty)

UPDATE

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorrect measurement of text size

My attempt at creating a basic font size changer was working perfectly until I integrated it with the bootstrap framework. Strangely, when I try to increase the font size, it actually decreases instead. var baseFontSize; (function () { "use strict"; ...

Additional forward slash appears within a JSON array

I am working on a project involving nestable drag and drop functionality. When I drag and drop tiles, it generates an array in a textarea that looks like this: [{},{"id":267},{"id":266}]. However, when I post this array on the action page, it gets posted ...

I'm having trouble with the calculator, unable to identify the issue (Typescript)

I'm struggling with programming a calculator for my class. I followed the instructions from our lesson, but it's not functioning properly and I can't pinpoint the issue. I just need a hint on where the problem might be located. The calculat ...

Display user input within a modal dialogue box

I have a subscription form that requires users to enter their name and email address. After clicking on "Compete Now," a pop-up appears asking for workshop information and postal code. The form is functioning correctly as intended. However, I want the em ...

mvc and ajax - failing to access model attributes

I'm encountering an issue where the inputs in my beginform are not being auto-posted successfully. Their values do not reach the model or controller and remain null (breakpoints are never hit). What could possibly be causing this? @model project.Mo ...

Is there a way to modify the commandlink image when the mouse hovers over it in PrimeFaces?

After implementing this code snippet, my commandlink seemed to vanish into thin air. Upon inspecting it with firebug, I discovered that it was present but had a size of 0 x 0 px. .myNewButton { width: 50px !important; height: 50px !important; background ...

Tips for creating a unique exception in AngularJS?

I have a customException.js script with the following service: app.service('CustomException', function() { this.CustomException1 = function (message) { if (!message) { message = "Custom Exception 1 occurred!"; } return { ...

Unable to loop through the "dataList" retrieved from a service call to the java backend within an Angular 9 application

After receiving JSON data from a Java backend service called houseguidelines, the information is sent to an Angular application via a service call. I am attempting to iterate over this returned JSON data and add it to an array I have created. Unfortunately ...

Elements with absolute positioning are preventing drag events from executing

Struggling to create a slider and encountering an issue. The problem lies in absolute items blocking slider drag events. I need a solution that allows dragging the underlying image through absolute positioned items. Any ideas on how to achieve this? MANY T ...

Is it possible to add additional text to an input field without modifying its existing value?

I have a numerical input field labeled "days" that I want to add the text " days" to without altering the actual numerical value displayed. <input type="number" class="days" (keyup)="valueChanged($event)"/> Users should only be able to edit the num ...

Gutenberg NPM remains in its original state without any alterations

I experienced some issues with the NPM when making changes in blocks or other elements as the changes were not working properly. Below is my gutenberg.php file: function MyBlocks() { wp_register_script('blocks-js', get_template_directory_ ...

Utilizing JQuery for real-time total updates

When a new div is created by clicking a button, I want to dynamically maintain an order system where the first div is labeled as 1 of 1, then as more divs are added it should change to 1 of 2, and so on. If a div is deleted, the numbering should reset back ...

Preventing an iframe from reloading when transferring it to a new parent using appendChild

I'm looking to relocate an iframe to a different parent element while maintaining the iframe's current state (including scroll position and any entered form data). Unfortunately, when I use appendChild() to move the iframe, it reloads and resets ...

Having trouble parsing JSON with Ajax in Pusher using PHP?

I am facing an issue while sending multiple parameters using the Pusher AJAX PHP library. This is the error I encounter: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data Here is my PHP and JS code: <script src="https: ...

Calculate the total number of pages within an epub document

As a beginner in the world of epub, I have acquired numerous files in different epub formats and now wish to make them easily readable online. I'm not quite sure what an epub file contains. Is there a method to determine the number of pages in my epub ...

Issue with updating bound property correctly when dynamically generating components using v-for in Vue.js

Encountered a challenge with vue.js and seeking guidance on the best approach to address it. Here's a concise summary of the issue: Situation Data is fetched from a rest API, handled by a class called DataLoader using javascript prototype syntax. Th ...

Changes made to CSS input box styles may not take effect immediately

When it comes to the input box styling: .inputBox { font-size: 5rem; background-color: red; } https://i.sstatic.net/pfCBi.jpg The font-size adjustment seems to affect the input box height only after clicking somewhere on the page, and the text appear ...

Optimizing table cell width in ASP.NET based on longest text content

Software: Visual Studio 2010, Asp.Net 4.0 I am working with multiple tables that are stacked vertically on top of each other, all generated dynamically in the codebehind. I would like to ensure that the first column in each table is the same width, based ...

What are the disadvantages of not incorporating the main CSS file directly into the web page?

Optimizing the loading time of my webpages is a priority for me, especially when it comes to first-time loading and from cache. Despite that, I still prefer to have the browser re-validate all resources to avoid any strange displays or update issues caused ...

The value retrieved from the event handler function's state does not match the anticipated value

While debugging, I often minimize this particular component to understand its behavior later on. It was quite challenging to pinpoint the issue due to some intricate logic in place. Nonetheless: import { useContext, useEffect, useState } from "react&q ...