Checkbox summation system not working

Asked

Viewed 233 times

-2

I have a summation system using checkbox and radio button always used it and it always worked, but I tried to put it on another page I have and it stopped working the code is this one:

function formatCurrency(num) { // função original - sem modificação
  num = num.toString().replace(/\$|\,/g, '');
  if (isNaN(num)) num = "0";
  cents = Math.floor((num * 100 + 0.5) % 100);
  num = Math.floor((num * 100 + 0.5) / 100).toString();
  if (cents < 10) cents = "0" + cents;
  for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
    num = num.substring(0, num.length - (4 * i + 3)) + ',' + num.substring(num.length - (4 * i + 3));
  return ("" + num + "." + cents);
}

var form = document.forms[0];
var inputs = form.querySelectorAll('input[type=checkbox],input[type=radio]');
// iterar todos os inputs
for (var i = 0; i < inputs.length; i++) {
  // vincular função ao evento "change"
  inputs[i].addEventListener('change', function() {
    var soma = 0;
    for (var j = 0; j < inputs.length; j++) {
      if (inputs[j].checked) {
        // interpreta como float, usando parseFloat ao invés de eval
        soma += parseFloat(inputs[j].value);
      }
    }
    form.hiddentotal.value = soma; // atribui valor ao campo oculto
    form.total.value = formatCurrency(soma) // exibe valor formatado
  }, false);
}
label {
  display: inline-block;
  width: 210px;
  float: left;
}
<form name="myform">
  <label><input type="radio" name="tamanho" value="9.25">250GR</label>
  <label><input type="radio" name="tamanho" value="11.25">400GR</label>
  <label><input type="radio" name="tamanho" value="14.25">600GR</label>
  <label><input type="checkbox" name="valor" value="2">L. Ninho</label>
  <label><input type="checkbox" name="valor" value="3">Nutella</label>
  <label><input type="checkbox" name="valor" value="3">Chantilly</label>
  <label><input type="checkbox" name="valor" value="1.5">L. Condensado</label>
  <label><input type="checkbox" name="valor" value="1.5">S. Valsa</label>
  <label><input type="checkbox" name="valor" value="2.5">Sorvete</label>
  <div>
    <span>Valor Total:</span>
    <input name="total" type="text" readonly disabled>
    <input type="hidden" name="hiddentotal" value="0">
  </div>
</form>

Here by the snippet it works normal, but when I put on the site it does not work.

  • What happens when you try to use it on your page? Shows error? Have any messages in the browser console?

  • It’s very likely to be a conflict, could you post the rest of the page code ? take a look if these selectors are already running another task.

  • See in Chrome’s Inspect Element or another browser if there is a script error.

  • Look at this example in Jsfiddle. Want me to adapt to a radio button and checkbox version? Or you can from there?

  • 1

    Try to be more specific and put less code that so we can’t even edit the question. The question is being discussed at the finish line for that very reason: When editing the question you have more than 30000 characters allowed

1 answer

3


Like you said, your code is working but something on your other page is making it break into it.

In this case, what I can advise you is to define a scope for your script, including when searching for elements on the page.

You can both achieve this by implementing a "Class", IIFE, eventHandler, etc.

Follow an example using a "Class".

var containers = document.querySelectorAll("[data-calc]");

var Calculadora = function(container) {
  var self = this;
  self.container = container;

  self.hiddentotal = self.container.querySelector("input[name='hiddentotal']");
  self.total = self.container.querySelector("input[name='total']");
  self.tamanhos = [].slice.call(self.container.querySelectorAll("input[name='tamanho[]']"));
  self.valores = [].slice.call(self.container.querySelectorAll("input[name='valor[]']"));

  var onChange = function (event) {
    self.onInputChange(event);  
  }

  this.tamanhos.forEach(function (tamanho, indice) {
    tamanho.addEventListener("change", onChange);
  });

  this.valores.forEach(function (valor, indice) {
    valor.addEventListener("change", onChange);
  });
}

Calculadora.prototype.onInputChange = function (event) {
  //recuperando o valor do radio tamanho selecionado.
  var tamanho = this.tamanhos.filter(function (tamanho, indice) {
    return tamanho.checked
  })[0];  
  tamanho = tamanho ? parseFloat(tamanho.dataset.valor) : 0;

  //somando os valores selecionados.
  var valor = this.valores.reduce(function (atual, proximo, indice) {
    var valor = atual;
    if (atual instanceof HTMLElement) {
      valor = atual.checked ? parseInt(atual.dataset.valor) : 0;
    }
    if (proximo.checked) {
      valor += parseInt(proximo.dataset.valor)
    }
    return valor;
  });

  //não entendi o pq do seu total ser a soma do tamanho com os valores, mas isto já forge a parte tecnica.
  var total = tamanho + valor;
  
  //formando o total como currency.
  //este metodo não é suportado pelo IE abaixo do 11, assim como pelo Safari.
  //para os browsers acima citados, é necessario uar um Polyfill (sugestão: https://github.com/andyearnshaw/Intl.js)
  var format = total.toLocaleString("pt-BR", { style: 'currency', currency: 'BRL' });

  this.hiddentotal.value = total
  this.total.value = format;  
};

var calculadoras = [];
[].forEach.call(containers, function (container, indice) {
  var calculadora = new Calculadora(container);
  calculadoras.push(calculadora);
});
label {
  display: inline-block;
  width: 210px;
  float: left;
}
<form name="myform">
  <div data-calc>
    <label>
      <input type="radio" name="tamanho[]" value="250GR" data-valor="9.25" />
      250GR
    </label>
    <label>
      <input type="radio" name="tamanho[]" value="400GR" data-valor="11.25" />
      400GR
    </label>
    <label>
      <input type="radio" name="tamanho[]" value="600GR" data-valor="14.25" />
      600GR
    </label>
    <label>
      <input type="checkbox" name="valor[]" value="L. Ninho" data-valor="2" />
      L. Ninho
    </label>
    <label>
      <input type="checkbox" name="valor[]" value="Nutella" data-valor="3" />
      Nutella
    </label>
    <label>
      <input type="checkbox" name="valor[]" value="Chantilly" data-valor="3" />
      Chantilly
    </label>
    <label>
      <input type="checkbox" name="valor[]" value="L. Condensado" data-valor="1.5" />
      L. Condensado
    </label>
    <label>
      <input type="checkbox" name="valor[]" value="S. Valsa" data-valor="1.5" />
      S. Valsa
    </label>
    <label>
      <input type="checkbox" name="valor[]" value="Sorvete" data-valor="2.5" />
      Sorvete
    </label>
    <div>
      <span>Valor Total:</span>
      <input name="total" type="text" readonly disabled />
      <input type="hidden" name="hiddentotal" value="0" />
    </div>
  </div>
</form>

Note that I added an element div[data-calc] to help delimit the scope.

  • It worked fine, but it has how to make the sum be made through the ID, because I use value to send the name of chekcbox....

  • Look, you mean this stretch <input type="checkbox" name="adicional[]" value="Nutella" id="3.00" hidden> ? first I would remind you that the property hidden is not valid, if you use it as the CSS selector to hide this input, then swap it for a class .hidden, if you use it for selection in JS, then the ideal is a data-custom (eg.: data-hidden)... another point, store values in the id, is not a good idea, because the id needs to be unique on the page, again use a data-custom (eg.: data-value)

  • in any case, I made a change to the valor not be stored in the HtmlElement.value... if you want just adapt the same to use the ID (do not recommend).

  • Since it is not recommended, what form do I add the value and also send the item name to the database?

  • @Alfredolima, I believe my previous comment answers your question

Browser other questions tagged

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