Automatic calculation of buttons

Asked

Viewed 72 times

1

I’m with an item calculation project where by clicking the buttons + or - I have a field that does the calculations automatically.

The problem is that this way I have to create a variable for each item and in total there are more than 40 items, then it is impossible to create this much of variables outside also do the calculations.

I wanted to ask for your help to evaluate the code and see if you can get a more viable logic.

function up() {

var valor1 = parseInt(document.querySelector('.valor1').value,10);
var valor2 = parseInt(document.querySelector('.valor2').value,10);
var valor3 = parseInt(document.querySelector('.valor3').value,10);
document.querySelector('.resultado').innerHTML = (((valor1 + valor2 + valor3)+1)*0.30).toFixed(2);

}


function down() {

var valor1 = parseInt(document.querySelector('.valor1').value,10);
var valor2 = parseInt(document.querySelector('.valor2').value,10);
var valor3 = parseInt(document.querySelector('.valor3').value,10);
document.querySelector('.resultado').innerHTML = (((valor1 + valor2 + valor3)-1)*0.30).toFixed(2);

}
input[type="number"] {
    -webkit-appearance: textfield;
    -moz-appearance: textfield;
    appearance: textfield;
}

    input[type=number]::-webkit-inner-spin-button,
    input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
}

    .number-input {
    border: 1px solid #ddd;
    display: inline-flex;
}

    .number-input button.plus {
    background-color: #2eb82e ;
}

    .number-input button.down {
    background-color: gainsboro ;
}

    .number-input,
    .number-input * {
    box-sizing: border-box;
}

    .number-input button {
    outline:none;
    -webkit-appearance: none;
    background-color: transparent;
    border: none;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    cursor: pointer;
    margin: 0;
    position: relative;
}

    .number-input button:before, 
    .number-input button:after {
    display: inline-block;
    position: absolute;
    content: '';
    width: 0.5rem;
    height: 1px;
    background-color: #212121;
    transform: translate(-50%, -50%);
}

    .number-input button.plus:after {
    transform: translate(-50%, -50%) rotate(90deg);
}

    .number-input input[type=number] {
    font-family: sans-serif;
    max-width: 2rem;
    padding: .1rem;
    border: solid #ddd;
    border-width: 0 1.5px;
    font-size: 1rem;
    height: 1rem;
    text-align: center;
}
<main>
<section class="itens">

    <div class="number-input">
        <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(down())" class= "down"></button>
        <input class="valor1" min="0" name="valor1" value="0" type="number">
        <button onclick="this.parentNode.querySelector('input[type=number]').stepUp(up())" class="plus"></button>
    </div>

    <div class="number-input">
        <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(down())" class= "down"></button>
        <input class="valor2" min="0" name="valor2" value="0" type="number">
        <button onclick="this.parentNode.querySelector('input[type=number]').stepUp(up())" class="plus"></button>
    </div>

    <div class="number-input">
        <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(down())" class= "down"></button>
        <input class="valor3" min="0" name="valor3" value="0" type="number">
        <button onclick="this.parentNode.querySelector('input[type=number]').stepUp(up())" class="plus"></button>
    </div>

    <h3 class="resultado">0</h3>

</section>
</main>

1 answer

0


You can assign the same class to all inputs, select them with querySelectorAll and then go through one by one foreach to make the calculation:

const elements = document.querySelectorAll('.valor'); // classe utilizada para os inputs
var soma = 0;
Array.from(elements).forEach((element, index) => {
   soma += parseInt(element.value, 10);
});

This way, whenever you want to add a new one, just remember to put the class you have chosen.

I also noticed that your two functions up()and down() do practically the same thing, changing only the value -1 or +1. To optimize things, it’s always good to reuse a code that you will use many times, making it easier to maintain, read, etc. Follow a suggestion:

function calc_elementos() {
      const elements = document.querySelectorAll('.valor');
      var soma = 0;
      Array.from(elements).forEach((element, index) => {
        soma += parseInt(element.value, 10);
      });
      return soma;
    }
    function calculo(num){
      document.querySelector('.resultado').innerHTML = (((calc_elementos())+num)*0.30).toFixed(2);
    }
input[type="number"] {
    -webkit-appearance: textfield;
    -moz-appearance: textfield;
    appearance: textfield;
}

    input[type=number]::-webkit-inner-spin-button,
    input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
}

    .number-input {
    border: 1px solid #ddd;
    display: inline-flex;
}

    .number-input button.plus {
    background-color: #2eb82e ;
}

    .number-input button.down {
    background-color: gainsboro ;
}

    .number-input,
    .number-input * {
    box-sizing: border-box;
}

    .number-input button {
    outline:none;
    -webkit-appearance: none;
    background-color: transparent;
    border: none;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    cursor: pointer;
    margin: 0;
    position: relative;
}

    .number-input button:before, 
    .number-input button:after {
    display: inline-block;
    position: absolute;
    content: '';
    width: 0.5rem;
    height: 1px;
    background-color: #212121;
    transform: translate(-50%, -50%);
}

    .number-input button.plus:after {
    transform: translate(-50%, -50%) rotate(90deg);
}

    .number-input input[type=number] {
    font-family: sans-serif;
    max-width: 2rem;
    padding: .1rem;
    border: solid #ddd;
    border-width: 0 1.5px;
    font-size: 1rem;
    height: 1rem;
    text-align: center;
}
<main>
      <section class="itens">
      
          <div class="number-input">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1))" class= "down"></button>
              <input class="valor" min="0" name="valor1" value="0" type="number">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepUp(calculo(1))" class="plus"></button>
          </div>
      
          <div class="number-input">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1))" class= "down"></button>
              <input class="valor" min="0" name="valor2" value="0" type="number">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepUp(calculo(1))" class="plus"></button>
          </div>
      
          <div class="number-input">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1))" class= "down"></button>
              <input class="valor" min="0" name="valor3" value="0" type="number">
              <button onclick="this.parentNode.querySelector('input[type=number]').stepUp(calculo(1))" class="plus"></button>
          </div>
      
          <h3 class="resultado">0</h3>
      
      </section>
      </main>

  • Our ball show really got much better, thanks for the answer. I put your fixes in the full code worked 100% but I came up with a new difficulty, I will explain a little the purpose of all this, basically these buttons will simulate a calculator of cubic meters of furniture, where the sum of all added furniture will give me the total calculation of the measures.

  • The difficulty now is that I have several measurements and I’m not being able to sum between them, in the example we use the value 0.30, but how would I add input 1 to each click and 2 add 0.60 for example and so on ? thought to separate by class the group of equal values and apply the value in the calculation of this class, tried with if and Else if, two functions calling different classes and in the end adding the values but without success.

  • You can do it in a lot of ways. You can add a second value parameter to the function that does the calculation, then it takes this parameter and calculates within the function itself. For example: calculo(1, 0.6). Then goes to the calc_elements that receives the same number and makes the sum.

  • I passed the values as a parameter in the html function, called these two parameters in the js function so that I calculated (num, value) then used these two parameters in calc_elements so that ((calc_elements() + in a) * value). toFixed(2). Until the addition of the third item works, from there the calculation no longer works, as I keep adding items that sum values totally out and have items that subtract even me by clicking on +...

  • I think I have identified where the problem is, I believe it is in the calculation with the calc_elements function -> ((calc_elementos() + num) * valor) I was doing some isolated tests I believe that in this case the quantities are being maintained but when adding a new item it takes the quantity that already exists multiplies by the new value returning a calculation divergent from the expected, which in this case would be the isolated multiplication of the quantity of each item and then take all these totals and sum to present the total measure of all items.

  • In the case now the ideal would be to actually close this question for you to open another, since via comment is very bad to understand and solve the problem and considering that the initial problem has been solved.

  • Perfect, to finish I need to do something? Taking advantage of the help, greatly advanced the project I’m developing.

  • You’re welcome Just mark mine as an answer "accept" if you’ve helped and if you still need to post the new question

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.