Struggling with a Javascript problem where a button appears to be unresponsive when clicked. How can I fix this issue

I'm facing an issue with a web interface I am designing for configuring remotes to control ESP32 functions. The problem seems to be related to the Javascript part of the interface, as the code on the ESP32 is working fine. Here's how it works: the interface has tabs where you can select different options by clicking on the menu items which then show or hide corresponding dividers.

There is a specific tab for remote configuration. Upon loading the page, a websocket command is sent to the controller to request the remote configuration data. Once the data is received, my Javascript inserts it into the divider as an HTML table list showing the paired remotes along with device information and buttons to edit or delete each one, as well as a back button.

Currently, the delete functionality is not implemented as I want to focus on getting everything else working smoothly first.

When clicking the edit button, a command is passed to the controller, which then loads a new table with editable data and a list of buttons associated with that particular remote.

The list of buttons also have edit and delete functionalities similar to the above, along with a back button.

The back button within the 'edit' function is causing me trouble. After navigating through editing a remote, then a button, and trying to go back, it seems to send an unnecessary edit button command.

The real issue lies in the flow of commands being sent when using the edit and back buttons, especially when multiple levels deep into editing remotes and buttons. It should not trigger an unnecessary edit button command.

To reproduce this problem without access to the controller, I have provided a link to a JSFiddle example below. I have also added alert messages to indicate what is happening at each step.

Any assistance in resolving this issue would be highly appreciated.

Link to JSFiddle example: https://jsfiddle.net/kb1sph/37epovwg/

My code is too long to include here, but I needed a snippet to add the JSFiddle link, so here's a placeholder snippet.

Answer №1

By delegating (targeting the button itself), there is no need to loop over the buttons.

An added benefit of this method is that if you add buttons later, the container will still handle the event.

This approach also prevents adding eventHandlers multiple times to the same buttons.

const remotegrid = document.getElementById('remotegrid');
remotegrid.addEventListener("click", (e) => {
  const tgt = e.target.closest("button"); // you can click anywhere on the button
  if      (tgt.matches(".remedit")) editrem(tgt);
  else if (tgt.matches(".btnedit")) editbtn(tgt);
  else if (tgt.matches(".remdel"))  delrem(tgt);
  else if (tgt.matches(".btndel"))  delbtn(tgt);
});

To simplify your code, consider loading fontawesome onto the device and using

<i class="fal fa-pencil"></i>
instead of SVG icons.

You could use even smaller code like:

 <button class='btnedit' title='Edit Button'>✎</button>
 <button class='btndel' title='Delete Button'>🗑</button>

Consider refactoring this function for improved readability and efficiency:

const ChangeTab = (evt, tabName) => {
  const currenttab = evt.currentTarget;
  document.querySelectorAll(".tabcontent")
    .forEach(content => content.style.display = "none");
  document.querySelectorAll(".tablinks")
    .forEach(tablink => tablink.classList.toggle("active",tablink === currenttab));
  document.getElementById(tabName).style.display = "grid";
};

Another enhanced event handler:

remotegrid.addEventListener("change", (e) => {
  const tgt = e.target;
  if (!tgt.matches("[name=remoteenabled]")) return; 
  SendCmd(`<RemoteEnabled MAC="${tgt.id}" Enabled="${tgt.value}"/>`);
});

Several improvements have been made in this updated version.

While some functionality may be affected, the code does not throw any errors. For further optimization, explore the use of template elements.

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

Adding the node_modules directory to a global npm package: A step-by-step guide

I've developed an npm package with numerous dependencies. However, when I test my app using npm install -g ./, the application is added to the global npm directory without the node-modules folder. As a result, when the app is launched from the termina ...

What is the best way to eliminate an object from an array of objects that fulfills a specific condition?

Upon receiving an object in my function containing the information below: { "name": "Grand modèle", "description": "Par 10", "price": 0, "functional_id": "grand_modele_par_10", "quantity": 2, "amount": 0 } I must scan the next array of objec ...

TensorflowJS Error: The property 'fetch' cannot be read as it is undefined

I am working on an Angular 7 application and attempting to load the mobilenet model by following the instructions in this example. To do this, I first installed tensorflowjs using the command npm install @tensorflow/tfjs (based on the steps provided in th ...

AngularJs throws an error: "Received an unexpected value when passing a number

Whenever I try to assign a value to $scope.formData.field_happy.und.0.value, I encounter the following error. An unexpected SyntaxError occurs: Unexpected number However, if I bind it to a model, everything works fine. I can't seem to figure out w ...

Creating a callback function within stored procedures using JavaScript Language Integrated Query in documentDB: A step-by-step guide

According to the documentation, the code snippets below are considered equivalent. However, I have observed that in the first case, I am able to perform operations on multiple documents within the callback function, whereas the map function in the latter s ...

Tips for preventing harmful messages in a chat room app

As I am working on a chat room website, users are able to input any content they want into the entry field and then send it to all online users. However, I have concerns about security - what if malicious individuals try to inject harmful HTML or JavaScrip ...

Working with ReactJS, Material-UI, and Javascript: Facing challenges in applying rounded borders to TableRow components

I've been trying to achieve rounded borders on a TableRow element, but adding the style "borderRadius: 5" doesn't seem to have any effect. When I try wrapping the TableRow in a Box element with borderRadius, it does make the borders rounded but m ...

After a push to the router, scrolling is disabled

While working on a Vuejs project, I encountered an issue when trying to change the page of my PWA using this.$router.push();. It seems to work fine everywhere else except when doing it from a modal within a component. The pushed page loads but scrolling is ...

Upgrade to the most recent versions of packages using npm

When using npm install --save <package_name>, it typically installs the latest stable version of the package. If you want to specifically install the most recent release, such as Bootstrap v4, you would need to use npm install <a href="/cdn-cgi/l ...

Utilizing JQuery AJAX for Effortless Caching with PHP Endpoints

I am currently working on improving the speed of the ajax requests on my website. The site operates using live filtering, so when a user interacts with a form element, the data will adjust accordingly. While the functionality works well, I find that it&apo ...

Creating interactive tooltips in Shiny applications with the help of ShinyBS

I am attempting to incorporate the shinyBS package into my basic app. My goal is to generate dynamic tooltip text based on each radioButton selection. To better illustrate my issue, I have drafted a simple code snippet in HTML & JS. While I came acro ...

How can I prevent list items in jQuery Mobile from being truncated with ellipses?

Here is the list I am working with: <ul id="linksList" data-role="listview" data-inset="true" data-filter="true"> <!-- Dynamic contents! --> </ul> This list pulls its data from a local XML file (RSS feed). I am looking f ...

Troubleshooting: Why isn't setMetadata working in NestJS from authGuards

When I call my decorators, I want to set metadata for logging purposes. Within my controller, the following decorators are used: @Post("somePath") @Permission("somePermission") @UseGuards(JwtAuthGuard) @HttpCode(200) @Grafana( ...

Using asynchronous functions in React Native still generates a promise despite the presence of the 'await' keyword

After making an API call, my react-native component is supposed to return some SVG. Despite using an async function with await, the function still returns a promise that has not resolved yet. I have seen similar questions asked before, but I am puzzled as ...

Getting to the values within a JSON object that contains multiple arrays

Is there a way to retrieve array data from the json object data? const [data, setData] = useState([]) const getData = () => { axiosInstance .get(url + slug) .then(result => setData(result.data)) } useEffect(() = ...

Issue with Bing Maps Infobox mouseout event: Problem arises when attempting to change the htmlContent asynchronously

Can anyone provide assistance? I am currently utilizing the latest Bing Maps version (v8), and I have encountered an issue. When creating a custom Infobox and populating its contents using an async request such as setTimeout/ajax, the mouseout event is tr ...

Experiencing difficulty when attempting to save a zip file to the C drive

I came across this code snippet on SO and decided to use it for my project. The goal is to send a simple 1.5mb zip file and save it on my C drive by making a request through Postman with the binary option enabled, sending the zip file to localhost:3012. c ...

Div element to animate and vanish in a flash

I'm attempting to create a smooth slide effect for a div element before it disappears. Below is the code I am currently using: function slideLeft(element) { $("#" + element).animate({ left: "510" }, { duration: 750 }); document.getEle ...

Angular 2: trigger a function upon the element becoming visible on the screen

How can I efficiently trigger a function in Angular 2 when an element becomes visible on the screen while maintaining good performance? Here's the scenario: I have a loop, and I want to execute a controller function when a specific element comes into ...

Oops! Hardhat Test Error "Error: Virtual Machine Exception occurred while processing transaction: reverted with reason 'Please deposit additional funds'."

Encountering an issue with the following error message: Error: VM Exception while processing transaction: reverted with reason string 'deposit more' in the Hardhat Test.js file Test.js -> it("should be able to withdraw if no one appl ...