I calculate javascript

Asked

Viewed 101 times

0

I’m trying to make a sum of measures where each input has its specific value, eg: input 1 size 0.6 input 2 size 1.2 and so on, the idea is to take the value of the input recorded through the buttons + and - multiply by their size and then sum up all the total sizes recorded and present in the total measurement field.

At the point I am, after doing some isolated tests I believe that the function is maintaining the value of the inputs and multiplying by the added value.

I believe that first I will have to calculate and multiply individually each input or group of inputs that contain the same values and then add these totals, but I’m having a lot of trouble finding this logic in js, can someone give me a hand ? from now on thank.

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, valor) {
  document.querySelector('.resultado').innerHTML = ((calc_elementos() + num) * valor).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;
}

h3 {
  display: flexbox;
}
<main>
  <section class="itens">

    <div class="number-input">
      <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1, 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, 1))" class="plus"></button>
    </div>

    <div class="number-input">
      <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1, 0.6))" 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, 0.6))" class="plus"></button>
    </div>

    <div class="number-input">
      <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1, 1.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, 1.1))" class="plus"></button>
    </div>

    <div class="number-input">
      <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1, 0.2))" 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, 0.2))" class="plus"></button>
    </div>

    <div class="number-input">
      <button onclick="this.parentNode.querySelector('input[type=number]').stepDown(calculo(-1, 0.5))" 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, 0.5))" class="plus"></button>
    </div>

  </section>

  <h3>Medida Total</h3>
  <h3 class="resultado">0</h3>
</main>

  • The measure of buttons is the second parameter of the calculation function.

1 answer

0


I hope to help. I believe your mistake is in ParseInt, that rounds its floating point values.

I created some functions to try to improve your code.

var inputs;
var medidas = [
    { value: 1, amount: 0 },
    { value: 0.6, amount: 0 },
    { value: 1.1, amount: 0 },
    { value: 0.2, amount: 0 },
    { value: 0.5, amount: 0 }
]

function plus(idx) {
    let medida = this.medidas[idx];
    medida.amount = Number((medida.amount + 1).toFixed(1));
    this.change(idx);
}

function down(idx) {
    let medida = this.medidas[idx];
    if (medida.amount > 0) {
        medida.amount = Number((medida.amount - 1).toFixed(1));
    }
    this.change(idx);
}

function calc() {
    var soma = 0;
    for (const medida of this.medidas) {
        soma = Number((soma + (medida.value * medida.amount)).toFixed(1));
    }
    document.getElementById('result').innerHTML = soma;
}

function change(idx) {
    let input = this.inputs.item(idx)
    input.value = medidas[idx].amount;
    this.calc();
}

function createElements(){
    let itens = document.getElementsByClassName('itens')[0];
    for (let idx = 0; idx < this.medidas.length; idx++) {
        let div = document.createElement("div");
        div.classList.add("number-input");
        let down = document.createElement("button");
        down.setAttribute("onclick", `down(${idx})`);
        down.classList.add('down');
        let plus = document.createElement("button");
        plus.setAttribute("onclick", `plus(${idx})`);
        plus.classList.add('plus');
        let input = document.createElement('input');
        input.setAttribute("onchange", `change(${idx})`)
        input.setAttribute("min", "0")
        input.setAttribute("name", `valor${idx + 1}`)
        input.setAttribute("type", "number")
        input.setAttribute("value", "0")
        input.classList.add("valor")
        div.appendChild(down)
        div.appendChild(input)
        div.appendChild(plus)
        itens.appendChild(div);
    }
    this.inputs = document.getElementsByClassName('valor');
}

document.onload = (this.createElements());
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;
}

h3 {
  display: flexbox;
}
    <main>
        <section class="itens"></section>
        <h3>Medida Total</h3>
        <h3 id="result">0</h3>
    </main>

  • Our show, yesterday I was trying something with objects so I created 'Let medidas = {media1: 1, measured2: 0.6}', but not so soon I was going to arrive at his logic, 2 doubts in the html part, 1. I saw that in the "result" you changed from class to id outside that there was some other change ? 2. In the inputs function I declared the second parameter that would be the measures need to keep them or in that their logic does not need ?

  • @paulo I changed the "result" from class to id and removed the Divs to be created via script. I made no changes to the CSS. The way I did, the functions do not need more parameters, because the variable medidas is global and therefore all functions can read and change.

  • then I let the normal Section inside it remove all Divs getting just the input button blocks ?

  • you can leave all the <section> empty. The function createElements() will create the div, inputs and Buttons for you, and dynamically, because when changing the measured variable html will continue to work. But if you prefer to have all static inputs in html you can remove the function createElements() and only initialize the variable inputs.

  • That’s what I thought but when removing the contents of the Section all buttons are gone :/ and on the console appears this error Uncaught Typeerror: Cannot read Property 'appendchild' of Undefined at createElements ai points error at line 61 and 66 which are itens.appendChild(div); and document.onload = (this.createElements());

  • checks if the Section tag is from class="items";

  • this, the same way I posted here only changed the script, the result id and deleted all the content from Section getting <main>&#xA; <section class="itens"></section>&#xA;&#xA; <h3>Medida Total</h3>&#xA; <h3 id="result">0</h3>&#xA;</main>

  • i removed the create function and kept the Divs, now the buttons are working with the quantities, but I’m not getting the full measure in the result, know what could be ?

Show 3 more comments

Browser other questions tagged

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