Sumar input en tiempo real con JavaScript

  • Autor Autor Felipe
  • Fecha de inicio Fecha de inicio
Felipe

Felipe

Iota
Redactor
Verificación en dos pasos activada
Hola amigos, necesito que al crear una nueva linea con Jquery estas llamen a la función multiplicar y se muestre el resultado en tiempo real en el input que lleva por nombre acumu. El problema que tengo es que cuando a la función multiplicar le entrego los valores fijos funciona, cuando lo dejo con los argumentos tal cual está en el código, no funciona. 🙁

Para ejecutarlo: https://jsfiddle.net/wuu1n6hL/

¿Qué hago mal?

El código que tengo es el siguiente:

HTML:
<!DOCTYPE html>
<html lang="es_ES">
<head>
	<meta charset="UTF-8">
	<title>Nota - 4</title>
	
	<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
	<script src="js/jquery-3.1.1.min.js" type="text/javascript"></script> 

	<script type="text/javascript">
		var nextinput = 0;
		function AgregarCampos(){
			nextinput++;
			campo = '<li id="idLi'+nextinput+'"><input type="number" size="20" id="nota'+nextinput+'" name="nota'+nextinput+'" step="any" onChange="multiplicar(nota'+nextinput+',pondera'+nextinput+',acumu'+nextinput+');" value=0 /> x <input type="number" size="20" id="pondera'+nextinput+'" name="pondera'+nextinput+'" step="any" onChange="multiplicar(nota'+nextinput+',pondera'+nextinput+',acumu'+nextinput+');" value=0 /> = <input type="number" size="20" id="acumu'+nextinput+'" name="acumu'+nextinput+'" step="any"/></li>';
			$("#campos").append(campo);
		}

		function multiplicar(nota,pondera,acumu){
			m1 = document.getElementById("nota").value;
			m2 = document.getElementById("pondera").value;
			r = m1*m2;
			document.getElementById("acumu").value = r;
		}
	</script>

</head>
<body>
	<form id="form" name="form" method="post">
	<a href="#" onclick="AgregarCampos();">Agregar Nota</a>
	<div id="campos"></div>
	</form>
</form>

</body>
</html>
 
Última edición:
CÓDIGO SOLUCIONADO
HTML:
<!DOCTYPE html>
<html lang="es_ES">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
	<script type="text/javascript">

		var nextinput = 0;
		function AgregarCampos(){
			nextinput++;
			campo = '<li id="idLi'+nextinput+'"><input type="number" size="20" id="nota'+nextinput+'" name="nota'+nextinput+'" step="any" onChange="multiplicar(\'nota'+nextinput+'\',\'pondera'+nextinput+'\',\'acumu'+nextinput+'\');" value=0 /> x <input type="number" size="20" id="pondera'+nextinput+'" name="pondera'+nextinput+'" step="any" onChange="multiplicar(\'nota'+nextinput+'\',\'pondera'+nextinput+'\',\'acumu'+nextinput+'\');" value=0 /> = <input type="number" size="20" id="acumu'+nextinput+'" name="acumu'+nextinput+'" step="any"/></li>';
			$("#campos").append(campo);
		}

		function multiplicar(nota,pondera,acumu){
			m1 = document.getElementById(nota).value; //Dejo fijo los input y resulta.
			m2 = document.getElementById(pondera).value; //Así funciona... pero cuando le entrego valores variables, no
			r = m1*m2;
			document.getElementById(acumu).value = r;
		}
        
	</script>

</head>
<body>
	<form id="form" name="form" method="post">
	<a href="#" onclick="AgregarCampos();">Agregar Nota</a>
	<ul id="campos"></ul>
	</form>

</body>
</html>



CÓDIGO RECOMENDADO
HTML:
<!DOCTYPE html>
<html lang="es_ES">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript">
	$(function() {
		$(document).on('keyup', '#campos input', function(e){
		 var p = $(this).parent().find('input');
		 p.eq(2).val(p.eq(0).val()*p.eq(1).val());
		});
			
		$(document).on('click', '#agregar', function(e){    
		 $('#campos').append('<li><input type="number" value="0" /> x <input type="number" value="0" /> = <input type="number" /></li>');
		 e.preventDefault();
		});
	});
</script>
</head>
<body>
	<form id="form" name="form" method="post">
		<a href="#" id="agregar">Agregar Nota</a>
		<ul id="campos"></ul>
	</form>
</body>
</html>
 
¡Muchísimas gracias!
¿Realmente era quitar las comillas de mi función? ¡Vaya error!.

Lo que no entiendo es porque las barras invertidas... Lo investigaré para entender mejor mi error.
¡Pero muchísimas gracias [MENTION=158595]ridemant[/MENTION]!
 
Muchas gracias [MENTION=65428]OLMID[/MENTION], también lo intenté de esa forma, pero para mi queda más entendible (aunque con más líneas) de la primera forma.

Lo que necesito ahora amigos [MENTION=65428]OLMID[/MENTION] y [MENTION=158595]ridemant[/MENTION] es mostrar la suma total de todos los campos "acumu" en un input independiente. Le agregué esta linea a la función multiplicar(), pero no me resultó, no podía ser tan simple jaja

function multiplicar(nota,pondera,acumu){
m1 = document.getElementById(nota).value;
m2 = document.getElementById(pondera).value;
r = m1*(m2/100);
var total = r + total;
document.getElementById('prome').value = total;

document.getElementById(acumu).value = r;
}

Captura de pantalla 2017-01-02 a las 09.53.08.webp
 
Prueba esto, no he conseguido que calcule la suma en tiempo real, solo mediante un botón

HTML:
<!DOCTYPE html>
<html lang="es_ES">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
	<script type="text/javascript">

		var nextinput = 0;
		function AgregarCampos(){
			nextinput++;
			campo = '<li id="idLi'+nextinput+'"><input type="number" size="20" id="nota'+nextinput+'" name="nota'+nextinput+'" step="any" onChange="multiplicar(\'nota'+nextinput+'\',\'pondera'+nextinput+'\',\'acumu'+nextinput+'\');" value=0 /> x <input type="number" size="20" id="pondera'+nextinput+'" name="pondera'+nextinput+'" step="any" onChange="multiplicar(\'nota'+nextinput+'\',\'pondera'+nextinput+'\',\'acumu'+nextinput+'\');" value=0 /> = <input class="importe_linea" type="number" size="20" id="acumu'+nextinput+'" name="acumu'+nextinput+'" step="any"/></li>';
			$("#campos").append(campo);
		}

		function multiplicar(nota,pondera,acumu){
			m1 = document.getElementById(nota).value;
			m2 = document.getElementById(pondera).value;
			r = m1*m2/100;
			document.getElementById(acumu).value = r;
		}
		function calcular_promedio() {
			importe_total = 0
			$(".importe_linea").each(
				function(index, value) {
				importe_total = importe_total + eval($(this).val());
				}
			);
			$("#total").val(importe_total);
		}
        
	</script>

</head>
<body>
	<form id="form" name="form" method="post">
	<a href="#" onclick="AgregarCampos();">Agregar Nota</a>
	<ul id="campos"></ul>
	<input type="button" value="Calcular Promedio" onclick="calcular_promedio()"/> <input type="text" id="total" value="0"/><br/>
	</form>
</body>
</html>

Un saludo
 
Prueba esto, no he conseguido que calcule la suma en tiempo real, solo mediante un botón


Un saludo

Hola, muchas gracias de verdad!
Al final si funciona de esta forma, sólo que me faltaba iniciar la variable total... ahora me quedan las validaciones, y un boton para borrar todo. 🙁

HTML:
	<script type="text/javascript" language="JavaScript">
		var nextinput = 0;
		var total = 0;
		function AgregarCampos(){
			nextinput++;
			campo = '<li id="idLi'+nextinput+'"><input type="number" size="20" id="nota'+nextinput+'" name="nota'+nextinput+'" step="any" onChange="multiplicar(\'nota'+nextinput+'\',\'pondera'+nextinput+'\',\'acumu'+nextinput+'\');" value=0 /> x <input type="number" size="20" id="pondera'+nextinput+'" name="pondera'+nextinput+'" step="any" onChange="multiplicar(\'nota'+nextinput+'\',\'pondera'+nextinput+'\',\'acumu'+nextinput+'\');" value=0 /> = <input type="number" size="20" id="acumu'+nextinput+'" name="acumu'+nextinput+'" step="any"/></li>';
			$("#campos").append(campo);
		}

		function multiplicar(nota,pondera,acumu){
			m1 = document.getElementById(nota).value;
			m2 = document.getElementById(pondera).value;
			r = m1 * (m2/100);
			total = total + r;
			document.getElementById(acumu).value = r;
			document.getElementById("promediof").value = total;
		}
	</script>

En el body:
HTML:
	<form id="form" name="form" method="post">
	<a href="#" onclick="AgregarCampos();">Agregar Nota</a>
	<ul id="campos">
	<li><input type="number" name="promedio" id="promediof" step="any"></li>
	</ul>
	</form>
 
Puedes usar esta funcion
Insertar CODE, HTML o PHP:
function formReset(){
document.form.reset();
}

Con este boton

HTML:
<input type="button" name="" value="Borrar" onclick="formReset()">

Saludos
 
Para el reset puedes añadir esta función:
Insertar CODE, HTML o PHP:
function resetear() {
  $('#form')[0].reset();
}

Y este HTML:
HTML:
<a href="#" onclick="resetear();">Limpiar formulario</a>

P.D: Si quieres que los campos se vayan insertando antes del promedio de la nota puedes cambiar
Insertar CODE, HTML o PHP:
$("#campos").append(campo);

Por:
Insertar CODE, HTML o PHP:
$("#campos").prepend(campo);

Aquí te dejo un ejemplo: https://jsfiddle.net/4Ld3p6be/4/
 
Última edición:
Para el reset puedes añadir esta función:
Insertar CODE, HTML o PHP:
function resetear() {
  $('#form')[0].reset();
}

Y este HTML:
HTML:
<a href="#" onclick="resetear();">Limpiar formulario</a>

Genial, muchas gracias en este hilo he aprendido mucho!
El enlace para limpiar el formulario funciona perfecto, pero la idea es que también se borren las "notas que se añadieron" (los input agregados). En eso estoy.

Muchas gracias nuevamente, me ha servido mucho vuestra ayuda!
 
Genial, muchas gracias en este hilo he aprendido mucho!
El enlace para limpiar el formulario funciona perfecto, pero la idea es que también se borren las "notas que se añadieron" (los input agregados). En eso estoy.

Muchas gracias nuevamente, me ha servido mucho vuestra ayuda!
Para hacer algo sencillo se me ocurre algo así: https://jsfiddle.net/4Ld3p6be/5/
 
Eso está de lujo, intentaré combinarlo con algo como eliminar por fila (Eliminar un <li></li> en específico) ¿Se puede? Yo creo que sí, lo he visto con tablas.
Claro, en la función AgregarCampos, cambias:
Insertar CODE, HTML o PHP:
campo = '<li id="idLi' + nextinput + '"><input type="number" size="20" id="nota' + nextinput + '" name="nota' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> x <input type="number" size="20" id="pondera' + nextinput + '" name="pondera' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> = <input type="number" size="20" id="acumu' + nextinput + '" name="acumu' + nextinput + '" step="any"/></li>';

Por:
Insertar CODE, HTML o PHP:
campo = '<li id="idLi' + nextinput + '"><input type="number" size="20" id="nota' + nextinput + '" name="nota' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> x <input type="number" size="20" id="pondera' + nextinput + '" name="pondera' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> = <input type="number" size="20" id="acumu' + nextinput + '" name="acumu' + nextinput + '" step="any"/><a href="#" onClick="$(this).parent().remove()">Borrar</a></li>';

Demo: https://jsfiddle.net/4Ld3p6be/6/
 
Claro, en la función AgregarCampos, cambias:
Insertar CODE, HTML o PHP:
campo = '<li id="idLi' + nextinput + '"><input type="number" size="20" id="nota' + nextinput + '" name="nota' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> x <input type="number" size="20" id="pondera' + nextinput + '" name="pondera' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> = <input type="number" size="20" id="acumu' + nextinput + '" name="acumu' + nextinput + '" step="any"/></li>';

Por:
Insertar CODE, HTML o PHP:
campo = '<li id="idLi' + nextinput + '"><input type="number" size="20" id="nota' + nextinput + '" name="nota' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> x <input type="number" size="20" id="pondera' + nextinput + '" name="pondera' + nextinput + '" step="any" onChange="multiplicar(\'nota' + nextinput + '\',\'pondera' + nextinput + '\',\'acumu' + nextinput + '\');" value=0 /> = <input type="number" size="20" id="acumu' + nextinput + '" name="acumu' + nextinput + '" step="any"/><a href="#" onClick="$(this).parent().remove()">Borrar</a></li>';

Demo: https://jsfiddle.net/4Ld3p6be/6/

¡wow! :love_heart: Gracias!
Ahora mi tarea es que se actualice el promedio una vez se borre la linea.

Mucísimas gracias!:welcoming:
 
Algo así:
https://jsfiddle.net/4Ld3p6be/7/

P.D: Le corregí tambien un par de bugs que tenía en el botón de resetear formulario. Disculpa 🙁

vaya! claro que sí, algo así!
Me queda una duda, al limpiar el formulario la variable total queda en memoria, entonces al agregar una nueva nota sin actualizar la página, este queda con el antiguo valor.

Estaba mirando que con algo así: $.removeData(miVariable); puedo borrar una variable en memoria... ¿No? pero no me resulta.

Estaba haciendo cálculos con el nuevo código que me has entregado amigo [MENTION=108344]aperpen[/MENTION], del cual estoy totalmente agradecido, pero las sumas no cuadran.
 
vaya! claro que sí, algo así!
Me queda una duda, al limpiar el formulario la variable total queda en memoria, entonces al agregar una nueva nota sin actualizar la página, este queda con el antiguo valor.

Estaba mirando que con algo así: $.removeData(miVariable); puedo borrar una variable en memoria... ¿No? pero no me resulta.

Estaba haciendo cálculos con el nuevo código que me has entregado amigo [MENTION=108344]aperpen[/MENTION], del cual estoy totalmente agradecido, pero las sumas no cuadran.

Si, ese era el bug que solucione en teoría. Puedes borrar la variable poniendo simplemente:
Insertar CODE, HTML o PHP:
total = 0;

¿Con qué números no te cuadran las sumas?
 
Si, ese era el bug que solucione en teoría. Puedes borrar la variable poniendo simplemente:
Insertar CODE, HTML o PHP:
total = 0;

¿Con qué números no te cuadran las sumas?


Por ejemplo añadiendo una nota con ponderación del 20%, luego borrarla y añadir la misma nota y otra con ponderación del 80%, resulta lo siguiente:
Captura de pantalla 2017-01-02 a las 18.11.24.webp

Luego al borrar el de 80, el resultado es:
Captura de pantalla 2017-01-02 a las 18.11.37.webp

- - - Actualizado - - -

La variable total no se resetea o no se actualiza en conjunto con los eventos borrar o agregar... Esto, para mi al menos, resultó ser más complicado de lo que pensé... xD

Una vez lo hice pero con notas fijas, digamos que con 5 notas en total. Fue bastante fácil, pero ahora al volverla dinámica la aplicación resulta que tiene más de alguna complejidad.

Quiero agradecer vuestra ayuda, ¡muchas gracias!
 
Por ejemplo añadiendo una nota con ponderación del 20%, luego borrarla y añadir la misma nota y otra con ponderación del 80%, resulta lo siguiente:
Ver el archivo adjunto 91777

Luego al borrar el de 80, el resultado es:
Ver el archivo adjunto 91778

- - - Actualizado - - -

La variable total no se resetea o no se actualiza en conjunto con los eventos borrar o agregar... Esto, para mi al menos, resultó ser más complicado de lo que pensé... xD

Una vez lo hice pero con notas fijas, digamos que con 5 notas en total. Fue bastante fácil, pero ahora al volverla dinámica la aplicación resulta que tiene más de alguna complejidad.

Quiero agradecer vuestra ayuda, ¡muchas gracias!

Que raro, a mi me funciona bien esa suma en concreto.. También el problema puede ser por que JavaScript tiene una forma extraña de trabajar con números decimales language agnostic - Is floating point math broken? - Stack Overflow

De cualquier forma, he hecho esta versión que lo que hace es redondear los resultados, a ver si así se soluciona el problema: https://jsfiddle.net/4Ld3p6be/8/

Una cosa importante a tener en cuenta es que por como está hecha la función de multiplicar no se puede cambiar una nota ya escrita, es decir, tendrías que darle a borrar y luego a escribirla de nuevo, si no se descuadrará el promedio

Saludos
 
Que raro, a mi me funciona bien esa suma en concreto.. También el problema puede ser por que JavaScript tiene una forma extraña de trabajar con números decimales language agnostic - Is floating point math broken? - Stack Overflow

De cualquier forma, he hecho esta versión que lo que hace es redondear los resultados, a ver si así se soluciona el problema: https://jsfiddle.net/4Ld3p6be/8/

Una cosa importante a tener en cuenta es que por como está hecha la función de multiplicar no se puede cambiar una nota ya escrita, es decir, tendrías que darle a borrar y luego a escribirla de nuevo, si no se descuadrará el promedio

Saludos

Justamente eso es al parecer lo que sucede, debo quizás pensar una forma distinta de multiplicarlos, quizás con un botón que envíe los datos para luego mostrar el promedio... eso cambiaría un poco lo que quería lograr, pero me llevaría a lograrlo.

Bueno, como ejercicio para aprender Javascript creo que está bien igual, aunque no me rendiré. Lo voy a lograr.
 

Temas similares

Atrás
Arriba