Home > Software engineering >  Why is my function to change the innerText of a targeted button changing the innerText of all the bu
Why is my function to change the innerText of a targeted button changing the innerText of all the bu

Time:05-30

This is my first JS project.
I am creating a study scheduler where the user inputs a to-do item and assigns it to a day.
JS creates the necessary elements (input field, trash button, completed button, start time button and end time button). I'm having a problem with the time picker.
I wrote a function that unhides a clock (that I wrote in html) when the user clicks on a startButton (that is created in JS). There can be unlimited startButtons so I wrote an eventListener for the array of these buttons.
The user picks the hour, minutes, and am/pm, which all get stored in variables, and then when they click the setTimeButton, the targeted startButton.innerText should update to show this time. The first time I run the function it works. After that, it is changing the targeted startButton plus every previous startTime button that I have clicked.
Here is the code:

document.addEventListener('DOMContentLoaded', () => 
  Array.from(startButton).forEach(element => 
    element.addEventListener('click', showTimePicker)
) );

function showTimePicker(e) { 

  let startOrEndTimeButton = e.target           
  // show clock
  Array.from(time).forEach(element => element.classList.toggle('hide')) 

  // click setTimeButton to insert time into targeted start time or end time button
  setTimeButton.addEventListener('click', function() {

    startOrEndTimeButton.innerText = chosenHour.innerText 
                                    ':'   chosenMinutes.innerText 
                                    " "   chosenAmPm.innerText;
    startOrEndTimeButton.style.backgroundColor = '#39ff14';
    startOrEndTimeButton.style.color = 'white';   
    Array.from(time).forEach(element => element.classList.toggle('hide')); 
  })
} 

CodePudding user response:

Here's a simplified version of your app's logic and the problematic behaviour that you describe:

  • Clicking on one of the buttons and then clicking the Set button, will change the value of that particular button
  • Clicking on another button and then clicking on the Set button will change the value of the selected button and also the value of the previously selected button.

const setTimeButton = document.getElementById("set");
const startButton = document.querySelectorAll("button.st");
document.addEventListener( 'DOMContentLoaded', () => 
    Array.from( startButton )
    .forEach( element => element.addEventListener( 'click', showTimePicker ) ) );

function showTimePicker( e ) {

    let startOrEndTimeButton = e.target
    setTimeButton.addEventListener( 'click', function () {

      startOrEndTimeButton.innerText = (Math.random() * 1000).toFixed();

    })

}
<button >Start 1</button>
<button >Start 2</button>
<button >Start 3</button>
<button id="set">Set</button>

Here are the changes you should make, in order for the app to work as expected:

  1. Define the startOrEndTimeButton variable outside the showTimePicker.
  2. Move the setTimeoutButton outside the showTimePicker.

As Mister Jojo correctly pointed out, you do not want to set an Event Listener on the setTimeoutButton every time you click on a startButton.

You can Run the code snippets in these two examples and check the resulting behavior yourself. Study the code carefully in order to understand why the suggested changes affect the behavior of the program and leave a comment in case you have any question about the suggested changes.

const setTimeButton = document.getElementById("set");
const startButton = document.querySelectorAll("button.st");
document.addEventListener( 'DOMContentLoaded', () => 
    Array.from( startButton )
    .forEach( element => element.addEventListener( 'click', showTimePicker ) ) );

let startOrEndTimeButton;

function showTimePicker( e ) {
    startOrEndTimeButton = e.target
}

setTimeButton.addEventListener( 'click', function () {
  startOrEndTimeButton.innerText = (Math.random() * 1000).toFixed();
})
<button >Start 1</button>
<button >Start 2</button>
<button >Start 3</button>
<button id="set">Set</button>

  • Related