Estoy tratando de hacer un sitio web simple, donde tienes un botón y cada vez que presionas el botón, se crea una entrada. También puede deshacerse de la entrada (eliminarla) con una cruz al lado (el botón y la cruz [agregar y eliminar elementos] no son objeto de esta pregunta, por lo que no se muestran en la captura de pantalla).
Ahora las entradas tienen un valor porcentual que puede cambiar. De forma predeterminada, si tiene una entrada, su valor es 100, cuando tiene 4 entradas, el valor es 25 y así sucesivamente... Al agregar una nueva entrada, todas las entradas que no se hayan editado manualmente (nosotros llegaremos a ellas) deberían recuperarse correspondientemente . Puede cambiar el valor de entrada (cualquiera de ellos) para establecer un porcentaje, que permanece igual. Piense en ello como una "oportunidad". Si una entrada es 50, las otras (por ejemplo, otras 2 entradas) deben tener un porcentaje de 25 cada una (ya que tiene 50 establecidas, quedan 50, entonces las divide entre esas entradas).
Puede establecer múltiples valores fijos y siempre contaría. Puede eliminar una entrada (editada o no) y debe contar el resto (pero no otras editadas).
Ejemplo:
Tienes 5 entradas, editaste 1. y 2. una con valores 40 y 30. Entonces te quedan 30 (%). Se reparte entre las 3 entradas restantes con 10 (%) cada una.
Mi acercamiento:
var inputs = document.querySelector(".ratio:not(.fresh)"); //.ratio is class of the inputs and .fresh is a class that all inputs have when created, but loose when edited var sum = 0; //sum of the edited inputs $(inputs).each(function(){ sum += +$(this).val(); }); var summary = 100 - sum; //Summary is the remaining value that is to be divided between the not edited inputs ratio = summary/($(".fresh").length+1); //ratio is the new value of .ratio input and is created when dividing Summary by all un-edited elements $(".fresh").val(ratio);Pero, sinceramente, debería estar en una función, ya que solo debe llamar para contarlo al agregar/eliminar. Y no funciona correctamente (lo hace, pero no con más de 1 entrada editada). Y estoy atascado con eso.
¿Alguna ayuda? ¡Gracias!
EDITAR:
Agregar más fragmentos de código:
estructura:
<button class="adder">Create input</button> <div class="inputs"></div>agregando entradas:
var component = document.createElement('div'); component.className = "component"; component.innerHTML = '<img class="delete" src="../images/icons/delete_component.svg" alt="Delete Component"><input class="ratio fresh" type="number" placeholder="'+ratio+'" name="ratio[]" value="'+ratio+'"><p class="percentage">%</p>' inputs.appendChild(component);Aquí hay una solución Vanilla JS. Espero haber entendido sus requisitos correctamente.
function recalc(){ const inps=[...cont.querySelectorAll("input")].reduce((a,c)=>{ if(!c.classList.contains("fresh")) a.sum=+c.value+(a.sum||0); else a.push(c); return a; }, []); const v=(100-(inps.sum||0))/inps.length; inps.forEach(inp=>inp.value=v); } const cont=document.querySelector("div"); document.querySelector("button").onclick=ev=>{ const div=document.createElement("div"); div.innerHTML=`<input type="number" class="fresh"><button> x </button>`; cont.append(div); recalc(); } cont.onclick=ev=>{ if (ev.target.tagName=="BUTTON"){ ev.target.closest("div").remove(); recalc() } } cont.addEventListener("input",ev=>{ ev.target.classList.remove("fresh"); recalc(); }) <button> + </button> <div class="container"></div> var inputsContainer = document.querySelector(".inputs"); var inputs = Array.from(inputsContainer.querySelectorAll("input")); var inputsTouched = new Array(inputs.length).fill(false); function add() { var num = inputs.length; var component = document.createElement("div"); component.className = "component"; component.innerHTML = '<img class="delete" src="../images/icons/delete_component.svg" alt="Delete Component">' + '<input id="i' + num + '" class="ratio fresh" type="number" placeholder="0" name="ratio[]" ' + 'value="0" onchange="update(' + num + ')"><span class="percentage">%</span>'; inputsContainer.appendChild(component); inputsTouched.push(false); inputs = Array.from(inputsContainer.querySelectorAll("input")); reevaluate(); } function reevaluate() { var touched = inputs.filter((el, i) => inputsTouched[i]); var notTouched = inputs.filter((el, i) => !inputsTouched[i]); var sum = touched.reduce((prev, curr) => prev + +curr.value, 0); var ratio = (100 - sum) / notTouched.length; if (ratio < 0.0001) { ratio = 0 } notTouched.forEach(el => el.value = ratio); } function update(num) { inputsTouched[num] = true; } <button class="adder" onclick="add()" type="button">Create input</button> <div class="inputs"></div>