Is there a way to set up one function that can be used across different HTML buttons?

As a newcomer to JS, I've taken on the challenge of creating a size comparison tool for practice. In my HTML file, I have multiple buttons representing different US sizes that should display the corresponding UK, EU, and CM size when clicked inside a designated <div>.

In my current implementation, I've assigned unique IDs to each button and written separate functions for each, which has resulted in inefficient and repetitive code. I'm now seeking a more streamlined approach to make my code more efficient.

const sizeAll = [
   {  US: 4,     UK: 3.5,   EU: 36,     CM: 22    },
   {  US: 4.5,   UK: 4,     EU: 36.5,   CM: 22.5  },
   //other size objects removed from here
   {  US: 14,    UK: 13,    EU: 48.5,   CM: 32    }   
];  

// Size elements
let sizeElements = document.querySelectorAll('.size-button');
let us = document.getElementById('current');
let uk = document.getElementById('uk');
let ukNumber = document.getElementById('ukNumber');
let eu = document.getElementById('eu');
let euNumber = document.getElementById('euNumber');
let cm = document.getElementById('cm');
let cmNumber = document.getElementById('cmNumber');

size.forEach(function(sizeElement, index) {
    sizeElement.addEventListener('click', function() {
        us.textContent = 'US' + ' ' + sizeAll[index].US + ':';
        uk.textContent = 'UK';
        ukNumber.textContent = sizeAll[index].UK;
        eu.textContent = 'EU';
        euNumber.textContent = sizeAll[index].EU;
        cm.textContent = 'CM';
        cmNumber.textContent = sizeAll[index].CM;
    });
});

<div class="buttons">
       <button class='size-button' value="4">4</button>
       <button class='size-button' value="4.5">4.5</button>
<!--I took out all other buttons for demonstration purposes-->      
       <button id='Fourteen' value="14">14</button>
</div>

<div>
       <h2 id="current"></h2>
           <h3 id="uk"></h3>
               <p id="ukNumber"></p>
           <h3 id="eu"></h3>
               <p id="euNumber"></p>
           <h3 id="cm"></h3>
               <p id="cmNumber"></p>          
</div>

To avoid unnecessary repetition, I am looking for an efficient way to handle this code instead of writing out individual functions like comparison45(), comparison5(), etc., for each button.

Answer №1

Ensure all the buttons have a common class so that you can cycle through them and attach the same event listener function. This function can utilize e.target to access the specific button that was clicked.

Modify sizeAll into an object where the IDs of the size buttons serve as keys.

const compareSizes = (e) => {
  var selectedSize = sizeAll[e.target.id];
  us.textContent = 'US' + ' ' + e.target.value + ':';
  uk.textContent = 'UK';
  ukNumber.textContent = selectedSize.UK;
  eu.textContent = 'EU';
  euNumber.textContent = selectedSize.EU;
  cm.textContent = 'CM';
  cmNumber.textContent = selectedSize.CM;
};

document.querySelectorAll(".size").forEach(el => el.addEventListener('click', compareSizes));

let us = document.getElementById('current');
//uk
let uk = document.getElementById('uk');
let ukNumber = document.getElementById('ukNumber');
//eu
let eu = document.getElementById('eu');
let euNumber = document.getElementById('euNumber');
//cm
let cm = document.getElementById('cm');
let cmNumber = document.getElementById('cmNumber');

const sizeAll = {
  Four: {
    US: 4,
    UK: 3.5,
    EU: 36,
    CM: 22
  },
  FourPointFive: {
    US: 4.5,
    UK: 4,
    EU: 36.5,
    CM: 22.5
  },
  //other size objects removed from here
  Fourteen: {
    US: 14,
    UK: 13,
    EU: 48.5,
    CM: 32
  }
};
<div class="buttons">
  <button id='Four' class="size" value="4">4</button>
  <button id='FourPointFive' class="size" value="4.5">4.5</button>
  <button id='Fourteen' class="size" value="14">14</button>
</div>

<div>
  <h2 id="current"></h2>
  <h3 id="uk"></h3>
  <p id="ukNumber"></p>
  <h3 id="eu"></h3>
  <p id="euNumber"></p>
  <h3 id="cm"></h3>
  <p id="cmNumber"></p>
</div>

Answer №2

An efficient approach in my opinion is to utilize the event parameter passed to the addEventListener callback function - specifically event.target which represents the button that triggered the event. By doing this, it eliminates the need for explicit variable references to each button in your code. Here's an example:

const sizeAll = [{
  US: 4,
  UK: 3.5,
  EU: 36,
  CM: 22
}, {
  US: 4.5,
  UK: 4,
  EU: 36.5,
  CM: 22.5
}, {
  US: 14,
  UK: 13,
  EU: 48.5,
  CM: 32
}];

let us = document.getElementById('current');
let uk = document.getElementById('uk');
let ukNumber = document.getElementById('ukNumber');
let eu = document.getElementById('eu');
let euNumber = document.getElementById('euNumber');
let cm = document.getElementById('cm');
let cmNumber = document.getElementById('cmNumber');

// Utilize the event argument passed by the browser to the addEventListener callback
const comparison = (e) => {
  // e.target.value refers to the button that was clicked to trigger the event
  const [sizeEl] = sizeAll.filter(size => size.US == e.target.value);
  // Note: There might be a more efficient way to structure your data so filtering is not needed, but this works for now

  us.textContent = 'US' + ' ' + sizeEl.US + ':';
  uk.textContent = 'UK';
  ukNumber.textContent = sizeEl.UK;
  eu.textContent = 'EU';
  euNumber.textContent = sizeEl.EU;
  cm.textContent = 'CM';
  cmNumber.textContent = sizeEl.CM;
};

document.querySelector('#Four').addEventListener('click', comparison);
document.querySelector('#FourPointFive').addEventListener('click', comparison);
document.querySelector('#Fourteen').addEventListener('click', comparison);
<div class="buttons">
  <button id='Four' value="4">4</button>
  <button id='FourPointFive' value="4.5">4.5</button>
  <!-- I removed other buttons for brevity -->
  <button id='Fourteen' value="14">14</button>
</div>

<div>
  <h2 id="current"></h2>
  <h3 id="uk"></h3>
  <p id="ukNumber"></p>
  <h3 id="eu"></h3>
  <p id="euNumber"></p>
  <h3 id="cm"></h3>
  <p id="cmNumber"></p>
</div>

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

Google App Engine does not properly interpret PHP code when making AJAX requests

I am currently facing an issue with using AJAX request on Google App Engine. In my local development environment, everything works fine and the request is correctly interpreted. However, when I deploy the code to production, the AJAX request renders the co ...

What steps can I take to convert my React class into a function in order to incorporate Material UI components effectively?

With Emailjs set up successfully, my next step is integrating Material UI text fields (link: https://material-ui.com/components/text-fields/#text-field) to enhance the design of my project. The challenge I'm facing is incorporating Material UI classe ...

Assign the callback function to execute when the select element loses focus

Is there a way to trigger a function when the user clicks out of a select menu without selecting an option, even though I know about the onChange and onFocus event listeners associated with the select HTML element? ...

Learn how to default export React with withRouter, all while taking advantage of Material UI's makeStyles

I have been working on integrating Material UI makeStyles with class components, passing useStyles as props while default exporting it in an arrow function. export default () => { const classes = useStyles(); return ( <LoginClass classes={cl ...

OpenLayers had trouble handling the mouse event in Ionic

I am attempting to handle a double mouse click event on OpenStreetMaps by utilizing the code below: const map = new OpenLayers.Map("basicMap"); const mapnik = new OpenLayers.Layer.OSM(); const fromProjection = new OpenLayers.Projection("EPSG:4326"); // ...

Understanding how to implement action logic in React Redux to control visibility of specific categories

Seeking guidance on how to implement action logic for displaying and hiding elements based on user interaction. Currently, all categories and subcategories are shown at once, but I would like them to be displayed only when a user clicks on them. When a use ...

Is there a way to manually stop a file upload (stream) using a XMLHttpRequest on the server?

Utilizing XMLHttpRequest (Level 2) to transfer a file to a node.js server, I am currently examining the file-stream for valid headers on the server side. The goal now is to halt the upload if any errors are encountered during streaming. My XMLHttpRequest c ...

Error in C# and JQuery: Object reference is not pointing to an instance of an object

Recently, I have been faced with an issue while trying to call a web service in c# from my jQuery script. Here is the snippet of the c# web service: [WebMethod] [ScriptMethod(UseHttpGet = true)] public void LoadService2Daily(string fromDate, string toDat ...

An issue arises with ReactJS MaterialUI Stepper when there is an overflow

My struggle with the Material UI Stepper component persists as I attempt to make it suit my requirements, specifically to display multiple steps and handle overflow. However, it stubbornly continues to misbehave by showing unusual separators when there is ...

Maintaining the consistent structure of build directories within a Docker container is crucial, especially when compiling TypeScript code that excludes the test

Our application is built using TypeScript and the source code resides in the /src directory. We have tests located in the /tests directory. When we compile the code locally using TSC, the compiled files are deposited into /dist/src and /dist/test respectiv ...

Retrieve only the final number within the sequence using JavaScript

I am receiving a series of numbers from an API. Here is how they look: 1,2,3,4,5,6 My goal is to only display the last digit instead of all of them. How can I achieve this? I know that I need to add .slice at the end, but I'm unsure about what to p ...

Ways to include additional assurances depending on a specific circumstance

When my code is executed in edit mode, I have a selection of API calls that need to be made, as well as one specific API call that must be made in both create and edit modes. Here is the current code snippet: // other controller code var config = {}; ...

The 'Required' attribute in HTML is malfunctioning

The 'required' attribute is not functioning properly when I try to submit the form. I've searched online for a solution, but none of them have resolved my problem. Take a look at the code snippet below - I've used the required attribute ...

Transform a string into an array that is then passed as an argument to AjaxManager

I am facing an issue while trying to transmit an array from jQuery on an .aspx page to a method in the codebehind using Telerik AjaxManager. My difficulty lies in converting the string to a list or an array using C#. The string (generated after using Json. ...

Utilizing Jquery to Access the Third Tag

I am in need of assistance to trigger a third party tag on my website when a specific message, "Choisissez la finition," is displayed on a webpage. The div containing this message is: <div id="vw_dbs_ihdcc_TrimSelector" class="container containerColQu ...

Caution: The task 'default' could not be located by Grunt. Consider using the --force option to proceed

Recently started setting up Grunt and encountered an immediate issue. Warning: Task "default" not found. Use --force to continue. Expanded error message: >> Error: Unable to parse "package.json" file (Unexpected token c). Warning: Task "default" n ...

Tips for creating a unified user interface framework for various web applications sharing a consistent design

Struggling to create a user interface framework for multiple web applications, I'm faced with the challenge of setting up the infrastructure in our unique situation: We have 7 (or more) different web applications built using asp.net mvc Some of thes ...

Python - Incorporating an additional row into an array argument

Looking for a way to add a row of 0 to an array parameter in a function. MNWE : import numpy as np def addrow(A): n,p = A.shape temp = np.zeros((n+1,p)) temp[:n,:] = A A = temp Struggling with defining A as a local variable and raising a ...

Using Three.js BVHLoader in React/React Native applications

I am currently working on developing an application or website for displaying BVH animation. I came across a BVHLoader example in Three.js that I found interesting: BVHLoader example. I am aware that React and React Native can be used with Three.js as we ...

Utilizing Angular directives to trigger functions within nested child directives

Seeking guidance on implementing a hierarchical structure in Angular, where a directive (<partition>) can trigger a method on a child directive's controller (<property-value>). Sample example provided: https://jsfiddle.net/95kjjxkh/1/ ...