Calculation with comma in Javascript

Asked

Viewed 451 times

1

I am redoing a system of Agricultural Measurement and I am finding it difficult to perform some calculations, initially prepared the input´s to receive only números, then I formatted them to receive a vírgula and a decimal place when you receive values, until then everything works. When trying to make a sum and then the average one of my function is error. I’ll try not to complicate by posting the commented code.

This is my form:

<div class="row">
   <section class="col col-2">
      <label class="input">
      <input type="text" name="deterVal1" id="deterVal1" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onKeyUp="FormataValor(this,5,event)">
      </label>
   </section>
   <section class="col col-2">
      <label class="input">
      <input type="text" name="deterVal2" id="deterVal2" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onKeyUp="FormataValor(this,5,event)">
      </label>
   </section>
   <section class="col col-2">
      <label class="input">
      <input type="text" name="deterVal3" id="deterVal3" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onKeyUp="FormataValor(this,5,event)">
      </label>
   </section>
   <section class="col col-2">
      <label class="input">
      <input type="text" name="deterVal4" id="deterVal4" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onKeyUp="FormataValor(this,5,event)">
      </label>
   </section>
   <section class="col col-2">
      <label class="input">
      <input type="text" name="deterVal5" id="deterVal5" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onKeyUp="FormataValor(this,5,event)">
      </label>
   </section>
   <section class="col col-2">
      <label class="input">
      <input type="text" name="MediaFinal" id="MediaFinal" value="" class="form-control " onfocus="calMediaAfericao(this)" onKeyPress="SomenteNumeros(this)" onKeyUp="FormataValor(this,5,event)">
      </label>
   </section>
</div>

Function to allow only numbers:

function SomenteNumeros(input) {
	if ((event.keyCode < 48) || (event.keyCode > 57))
		event.returnValue = false;
}

Insert comma and decimal place

function FormataValor(campo, tammax, teclapres) {

	var tecla = teclapres.keyCode;
	var vr = campo.value;
	vr = vr.replace("/", "");
	vr = vr.replace("/", "");
	vr = vr.replace(",", "");
	vr = vr.replace(".", "");
	vr = vr.replace(".", "");
	vr = vr.replace(".", "");
	vr = vr.replace(".", "");
	tam = vr.length;

	if (tam < tammax && tecla != 8) {
		tam = vr.length + 1;
	}

	if (tecla == 8) {
		tam = tam - 1;
	}

	if (tecla == 8 || (tecla >= 48 && tecla <= 57) || (tecla >= 96 && tecla <= 105)) {
		if (tam <= 1) {
			campo.value = vr;
		}
		tam = tam - 1;
		if ((tam > 1) && (tam <= 5)) {
			campo.value = vr.substr(0, tam - 1) + ',' + vr.substr(tam - 1, tam);
		}

		if ((tam > 5) && (tam <= 8)) {
			campo.value = vr.substr(0, tam - 1) + ',' + vr.substr(tam - 1, tam);
		}
	}
}

Before I sum and calculate the mean I call a function that replaces the comma by a point, this function is accusing a failure, what I try to do is this:

function calMediaAfericao() {

	var vlrDet1 = parseInt(document.getElementById('deterVal1').value, 10);
	var vlrDet2 = parseInt(document.getElementById('deterVal2').value, 10);
	var vlrDet3 = parseInt(document.getElementById('deterVal3').value, 10);
	var vlrDet4 = parseInt(document.getElementById('deterVal4').value, 10);
	var vlrDet5 = parseInt(document.getElementById('deterVal5').value, 10);

	vlrDet1 = Number(substituiVirgula(vlrDet1));
	vlrDet2 = Number(substituiVirgula(vlrDet1));
	vlrDet3 = Number(substituiVirgula(vlrDet1));
	vlrDet4 = Number(substituiVirgula(vlrDet1));
	vlrDet5 = Number(substituiVirgula(vlrDet1));

	document.getElementById('MediaFinal').value = (vlrDet1 + vlrDet2 + vlrDet3 + vlrDet4 + vlrDet5) / 5;

}

The function substituiVirgula and the one who is accusing error, as can be seen here:

VM11866:284 Uncaught TypeError: valor.indexOf is not a function
    at substituiVirgula (eval at globalEval (jquery.min.js:2), <anonymous>:284:13)
    at calMediaAfericao (eval at globalEval (jquery.min.js:2), <anonymous>:338:20)
    at HTMLInputElement.onfocus (VM11873 iAfericaoAgricola-novo.php:1)

That’s the job of:

	function substituiVirgula(valor){
		if (valor.indexOf(",") >= 0) {
			var novoValor = valor.replace(",",".");
			return novoValor;
		} else {
			return valor;
		}				
	}

  • 1

    The problem is that it has some value that is not a String. Before the line if (valor.indexOf(",") >= 0) { put a valor = valor.toString();

  • 2

    You may want to use a number formatting library, such as Inputmask - this would avoid a lot of headache. Also Its formatting function has repeats and the code to allow only numbers is easily burlable.

  • 1

    @adventistapr, a tip, insert several snippets of executable code does not help to simulate anything of your doubt, because the snippets are executed alone. Next time put everything in just one snippet of code, as I did in my reply below.

  • Hello @Marco, it was in the concern of not missing arguments for the good understanding, but I appreciate the tip.

  • @adventistapr Yes, I even understood this, precisely why I did not edit your question, but it is not possible to run without us put in a single location.

  • 1

    If possible take advantage of @Renan’s tip and try using Inputmask, since I saw that you use jQuery, it will make it easier and much better to validate the fields.

  • Thanks @Marco, I’m already changing right now, thanks.

Show 2 more comments

1 answer

1


It was a set of small mistakes, but the main thing is that the function calMediaAfericao() that was called in the onfocus of the last field is who ended up returning the error valor.indexOf is not a function because you convert the values using parseInt (that should be parseFloat since it is a decimal value) and passed to function substituiVirgula a numerical type value where there is no method indexOf.

I have some reservations about the way you chose to call the calculation method, because I believe that a button for this would be more interesting functionally, but changing only to be functional for your goal, would be like this:

function SomenteNumeros(input) {
  if ((event.keyCode < 48) || (event.keyCode > 57))
    event.returnValue = false;
}

function FormataValor(campo, tammax, teclapres) {
  var tecla = teclapres.keyCode;
  var vr = campo.value;
  vr = vr.replace("/", "");
  vr = vr.replace("/", "");
  vr = vr.replace(",", "");
  vr = vr.replace(".", "");
  vr = vr.replace(".", "");
  vr = vr.replace(".", "");
  vr = vr.replace(".", "");
  tam = vr.length;

  if (tam < tammax && tecla != 8) {
    tam = vr.length + 1;
  }

  if (tecla == 8) {
    tam = tam - 1;
  }

  if (tecla == 8 || (tecla >= 48 && tecla <= 57) || (tecla >= 96 && tecla <= 105)) {
    if (tam <= 1) {
      campo.value = vr;
    }
    tam = tam - 1;
    if ((tam > 1) && (tam <= 5)) {
      campo.value = vr.substr(0, tam - 1) + ',' + vr.substr(tam - 1, tam);
    }

    if ((tam > 5) && (tam <= 8)) {
      campo.value = vr.substr(0, tam - 1) + ',' + vr.substr(tam - 1, tam);
    }
  }
}

function calMediaAfericao(campo) {
  var vlrDet1 = parseFloat(substituiVirgula(document.getElementById('deterVal1').value), 10);
  var vlrDet2 = parseFloat(substituiVirgula(document.getElementById('deterVal2').value), 10);
  var vlrDet3 = parseFloat(substituiVirgula(document.getElementById('deterVal3').value), 10);
  var vlrDet4 = parseFloat(substituiVirgula(document.getElementById('deterVal4').value), 10);
  var vlrDet5 = parseFloat(substituiVirgula(document.getElementById('deterVal5').value), 10);

  campo.value = (vlrDet1 + vlrDet2 + vlrDet3 + vlrDet4 + vlrDet5) / 5;
}

function substituiVirgula(valor) {
  if (valor.indexOf(",") >= 0) {
    var novoValor = valor.replace(",", ".");
    return novoValor;
  } else {
    return valor;
  }
}
<div class="row">
  <section class="col col-2">
    <label class="input">
      <input type="text" name="deterVal1" id="deterVal1" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onkeyup="FormataValor(this,5,event)">
    </label>
  </section>
  <section class="col col-2">
    <label class="input">
      <input type="text" name="deterVal2" id="deterVal2" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onkeyup="FormataValor(this,5,event)">
    </label>
  </section>
  <section class="col col-2">
    <label class="input">
      <input type="text" name="deterVal3" id="deterVal3" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onkeyup="FormataValor(this,5,event)">
    </label>
  </section>
  <section class="col col-2">
    <label class="input">
      <input type="text" name="deterVal4" id="deterVal4" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onkeyup="FormataValor(this,5,event)">
    </label>
  </section>
  <section class="col col-2">
    <label class="input">
      <input type="text" name="deterVal5" id="deterVal5" value="" class="form-control" onKeyPress="SomenteNumeros(this)" onkeyup="FormataValor(this,5,event)">
    </label>
  </section>
  <section class="col col-2">
    <label class="input">
      <input type="text" name="MediaFinal" id="MediaFinal" value="" class="form-control " onfocus="calMediaAfericao(this)" readonly />
    </label>
  </section>
</div>

Browser other questions tagged

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