Summation system with checkbox does not work [closed]

-2

I have a sum system using checkbox and radio button I've always used it and it always worked, but I tried putting it on another page that I have and it stopped working the code here:

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 it on the site it does not work.

    
asked by anonymous 10.12.2015 / 12:06

1 answer

3

As you said, your code is working but something on your other page is causing it to break into it.

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

You can either 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 a div[data-calc] element to help narrow the scope.

    
10.12.2015 / 13:21