简体   繁体   中英

How to simplify JS variables and getting `<input>`s by class, then sum their values?

If I have many <input> s like this:

<input class="BUBU-1">
<input class="BUBU-2">
...
<input class="BUBU-1000">

how can I make variables similar to these:

var NEW1 = document.get...(" BUBU-1 ");
// ...
var NEW1000 = document.get...(" BUBU-1000 ");

but instead something like these (if it's possible):

var SMTH = 1..1000;
var NEW[SMTH] = document.get...(" BUBU-[SMTH] ");

And then sum them, like NEW1 + NEW2 + ... + NEW1000 , but with some function, which says “take all NEW[SMTH] and sum them” .

  1. Put all input elements in a NodeList using document.querySelectorAll('[class^=BUBU-]'); and make that an array using array destructuring operator ... (NodeList is an array-like structure, so it can be transformed to an array easily which allows to use methods available for Arrays on it, see step 2). ( [class^=BUBU-] matches all elements that have a class attribute starting with BUBU- ).

  2. Use Array.prototype.reduce() to accumulate the values. Remember the values are always strings on inputs, so convert them to Number before adding.

 const inputs = [...document.querySelectorAll('[class^=BUBU-]')] function sum(collection) { return collection.reduce((acc,val) => { return acc+Number(val.value) }, 0) } console.log(sum(inputs)); 
 <input class="BUBU-1" value="1"> <input class="BUBU-2" value="2"> ... <input class="BUBU-1000" value="1000"> 

Seeing that in your JSFiddle you're using id instead of class , simply adjust the selector to document.querySelectorAll('[id^=BUBU-]' )`.

You can simply get a single element like this:

let n = 1;

document.querySelector(".BUBU-" + n); // This yields `<input class="BUBU-1">`.

You can take the sum of their values, by building an array of numbers first, mapping them to the numeric values of their inputs of their selectors, then reduce them to a sum:

const sum = Array.from({
    length: 1000
  }, (_, index) => Number(document.querySelector(".BUBU-" + (index + 1)).value))
    .reduce((result, value) => result + value, 0);

console.log(sum);

If you want to remove empty or non-numeric fields before calculating the sum, use .filter((value) => !isNaN(value)) before the .reduce line; this filters NaN values .

If you want just an array of the numeric values, remove the reduce step. If you want the values as strings, rather than numbers, remove the Number call. If you want just the elements, rather than their values, use just document.querySelector(".BUBU-" + (index + 1)) .


If all <input> s are all children of a parent element , eg a <div id="allInputs"> , selecting and summing them becomes easier:

const sum = Array.from(document.querySelector("#allInputs input"), ({value}) => Number(value))
  .reduce((result, value) => result + value, 0);

console.log(sum);

If your <input> s should only contain numbers, consider giving them the type="number" attribute. Then, you can also use something like Array.from(document.querySelector("#allInputs input"), ({valueAsNumber: number}) => number) , etc.


Seeing your JSFiddle , make sure that your selectors are correct. .BUBU-1 selects elements with class="BUBU-1" , #BUBU-1 selects the (first) element with id="BUBU-1" .

If you want to listen to change events, consider using event delegation:

In vanilla JavaScript:

document.body.addEventListener("change", function(e){
  if(e.target.matches("input")){
    // Calculate sum, etc.
  }
});

In jQuery:

$("body").on("change", "input", function(e){
  // Calculate sum, etc.
});

As your JSFiddle appears to be more complex than your question, but you just asked about summing input fields with class names of a common pattern, if you do have a question about a more complex problem , consider asking a new question.

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