Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

346
Vistas
¿Cómo se calcula un valor de salida que debe actualizarse a partir de varios elementos de control de forma mediante reglas de cálculo específicas de control?

Necesito ayuda ya que soy bastante nuevo en JavaScript.

Deseo crear una función que calcule una cuota de membresía

Intenté crear una función en JavaScript que verifica si solo se ha seleccionado una opción, pero no tengo idea de cómo hacerlo para poder calcular la tarifa si un usuario es elegible para más de uno o todos los descuentos. Todavía no hay JS actual para la condición de edad (entre 60 y 80) ya que no estoy seguro de cómo hacerlo.

 function feeCalc() { var ans = document.getElementById("answer"); if (document.getElementById('medicalCond-yes').checked) { ans.value = calculate('medicalCond-yes'); } if (document.getElementById('empstatus-yes').checked) { ans.value = calculate('empstatus-yes'); } if (document.getElementById('empstatus-no').checked) { ans.value = calculate('empstatus-no'); } if (document.getElementById('medicalCond-no').checked) { ans.value = calculate('medicalCond-no'); } } function calculate(action) { var standardRate = 10; var ageRate = 0.1; var medicalRate = 0.4; var unemployedRate = 0.3; var result; switch (action) { case 'medicalcond-yes': discount = (standardRate * studentRate); result = standardRate - discount; break; case 'empstatus-yes': discount = (standardRate * unemployedRate); result = standardRate - discount; break; case 'empstatus-no': result = standardRate; break; case 'medicalcond-no': result = standardRate; break; } return result; }
 <div class="form"> <label> Age </label> <input type="range" value="50" min="1" max="100" class="slider" id="age"/> </div> <div class="form"> <label> Do you have any long-term medical conditions that can affect daily life </label> <br/> <input type="radio" name="status" value="yes" id="medicalCond-yes"/>Yes <input type="radio" name="status" value="no" id="medicalCond-no"/>No </div> <div class="form"> <label> Are you currently employed? </label> <br/> <input type="radio" name="empstatus" value="yes" id="empstatus-yes"/>Yes <input type="radio" name="empstatus" value="no" id="empstatus-no"/>No </div> <div class="form"> <label> Membership Fee </label> <br/> Total Fee: <input type="text" id="answer" readonly/> <input type="button" value="Calculate" onclick="feeCalc()"/> </div>

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

En lugar de cambiar el enrutamiento de casos a una sola sucursal, probablemente desee verificar todos los casos de una sola vez.

 function feeCalc() { var ans = document.getElementById("answer"); ans.value = calculateRate(); } function calculateRate() { let discount = 0; const age = Number(document.getElementById('age').value); if (age >= 60 && age <= 80) { discount += 0.1; } if (document.getElementById('medicalCond-yes').checked) { discount += 0.4; } if (document.getElementById('empstatus-no').checked) { discount += 0.3; } return 1 - discount; }
 <div class="form"> <label> Age </label> <input type="range" value="50" min="1" max="100" class="slider" id="age"/> </div> <div class="form"> <label> Do you have any long-term medical conditions that can affect daily life </label> <br/> <input type="radio" name="status" value="yes" id="medicalCond-yes"/>Yes <input type="radio" name="status" value="no" id="medicalCond-no"/>No </div> <div class="form"> <label> Are you currently employed? </label> <br/> <input type="radio" name="empstatus" value="yes" id="empstatus-yes"/>Yes <input type="radio" name="empstatus" value="no" id="empstatus-no"/>No </div> <div class="form"> <label> Membership Fee </label> <br/> Total Fee: <input type="text" id="answer" readonly/> <input type="button" value="Calculate" onclick="feeCalc()"/> </div>

over 4 years ago · Santiago Trujillo Denunciar

0

Aunque para el problema del OP parece un exceso de ingeniería, el código proporcionado por el OP es lo suficientemente pequeño como para demostrar las ventajas de los enfoques (más) genéricos que son ...

  1. Ser forzado a trabajar con un marcado/estructura HTML limpio como DOM y/o base de datos.
  2. Código de desacoplamiento (validación) de datos específicos de casos muy (comerciales) como... no depender más...
    • en consultas de elementos DOM muy específicas,
    • en datos "integrados" para, por ejemplo, validación y manejo de casos extremos.
  3. A largo plazo, es más fácil de mantener (en términos de datos comerciales modificados) y de adaptarse, por ejemplo, a nuevas opciones de descuento.

Especialmente el código JavaScript que implementa un enfoque/comportamiento de causa genérico es más grande desde el principio que su competidor escrito muy explícitamente. Pero el primero no tiende a crecer o ni siquiera necesita ser tocado para nuevas opciones de descuento o valores de descuento modificados. Esta parte queda cubierta por subestructuras más limpias y genéricas (por lo tanto, reutilizables) de la superestructura de la calculadora también genérica.

Además, este enfoque basado en componentes genéricos permite automáticamente el uso de más de un componente en/dentro de un mismo documento.

 function parseJson(str) { let result; try { result = JSON.parse(str); } catch (exc) { result = null; } return result; } function getDevaluationFactorFromRange(formControl, range) { let factor = 0; range = parseJson(range); if (range !== null) { const controlValue = parseFloat(formControl.value); Object .entries(range) .some(([devaluationKey, { min, max }]) => { let isStopIteration = false; if ( (controlValue >= parseFloat(min)) && (controlValue <= parseFloat(max)) ) { factor = parseFloat(devaluationKey); isStopIteration = true; } return isStopIteration }); } return Number.isFinite(factor) ? factor : 0; } function getDevaluationFactor(formControl) { const { dataset } = formControl; let rawRange = dataset.devaluationRange ?? null; let rawFactor = dataset.devaluationFactor ?? null; let factor = (rawRange !== null) ? getDevaluationFactorFromRange(formControl, rawRange) : 0; factor = ( (factor === 0) && (rawFactor !== null) && parseFloat(rawFactor) ) || factor; factor = Number.isFinite(factor) ? factor : 0; if (factor !== 0) { const { type } = formControl; if ((type === 'radio') || (type === 'checkbox')) { factor = formControl.checked ? factor : 0; } } return factor; } function computeCurrentFee(rootNode, elmFee, baseFee) { return Array // array from `HTMLFormControlsCollection` .from(rootNode.elements) // calculate currrent fee from each form element's data .reduce((currentFee, formControl) => { return currentFee - (baseFee * getDevaluationFactor(formControl)); }, baseFee); } function updateCurrentValueAtBoundFeeContext(/*evt*/) { const { rootNode, elmFee, baseFee } = this; elmFee.value = computeCurrentFee(rootNode, elmFee, baseFee); } function displayCurrentValueAtBoundAgeContext(/*evt*/) { const { elmRange, elmOutput } = this; elmOutput.value = elmRange.value; } function initializeCurrentAgeDisplay(rootNode) { const ageNode = rootNode.querySelector('[data-age-range]'); if (ageNode) { const elmRange = ageNode.querySelector('input[type="range"]'); const elmOutput = ageNode.querySelector('output'); if (elmRange && elmOutput) { const target = { elmRange, elmOutput }; const boundContextHandler = displayCurrentValueAtBoundAgeContext.bind(target); elmRange.addEventListener('input', boundContextHandler); rootNode.addEventListener('reset', () => // decouple custom dom refresh from the system's one. setTimeout(boundContextHandler, 0) ); // display initial age value. // // displayCurrentValueAtBoundAgeContext.call(target); boundContextHandler(); } } } function initializeMembershipFeeCalculator(rootNode) { const DEFAULT_BASE_FEE = 10; initializeCurrentAgeDisplay(rootNode); const elmFeeValue = rootNode.querySelector('[data-fee-value]'); if (elmFeeValue) { const baseFee = parseFloat(rootNode.dataset.baseFee); const target = { rootNode, elmFee: elmFeeValue, baseFee: Number.isFinite(baseFee) ? baseFee : DEFAULT_BASE_FEE, }; const boundContextHandler = updateCurrentValueAtBoundFeeContext.bind(target); rootNode.addEventListener('input', boundContextHandler); rootNode.addEventListener('reset', () => // decouple custom dom refresh from the system's one. setTimeout(boundContextHandler, 0) ); // compute initial fee value. // // updateCurrentValueAtBoundFeeContext.call(target); boundContextHandler(); rootNode.addEventListener('submit', evt => { evt.preventDefault(); return false; }); } } function main() { document .querySelectorAll('form[data-membership-fee-calculator]') .forEach(initializeMembershipFeeCalculator); } main();
 body, form { margin: 0; padding: 0; } form { float: left; width: 50%; margin-top: -2px; } fieldset { position: relative; margin: 0 0 2px 0; padding: 0 10px 2px 10px; } fieldset p { margin: 1px 0 2px 0; } fieldset output { color: #333; font-weight: bolder; } label { display: inline-block; } input[type="range"] { width: 70%; } [data-age-range] output { display: inline-block; overflow: hidden; max-width: 25%; max-height: 1.2em; position: relative; top: 1px; } [type="reset"] { position: absolute; right: 4px; top: -4px; }
 <form data-membership-fee-calculator data-base-fee="10"> <fieldset data-age-range> <legend> Age </legend> <input type="range" name="age" id="age" value="50" min="1" max="100" data-devaluation-range='{"0.1":{"min":60,"max":80}}' /> <output for="age">### not yet computed ###</output> </fieldset> <fieldset> <p> Do you have any long-term medical conditions that can affect daily life? </p> <label> <input type="radio" name="status" value="yes" data-devaluation-factor="0.4" /> <span class="label-copy"> Yes </span> </label> <label> <input type="radio" name="status" value="no" /> <span class="label-copy"> No </span> </label> </fieldset> <fieldset> <p> Are you currently employed? </p> <label> <input type="radio" name="empstatus" value="yes" data-devaluation-factor="0.3" /> <span class="label-copy"> Yes </span> </label> <label> <input type="radio" name="empstatus" value="no" /> <span class="label-copy"> No </span> </label> </fieldset> <fieldset> <legend> Membership Fee </legend> <label> <span class="label-copy"> Total Fee: </span> <output data-fee-value>### not yet computed ###</output> </label> <button type="reset">Restore base fee</button> </fieldset> </form> <form data-membership-fee-calculator data-base-fee="20"> <fieldset data-age-range> <legend> Age </legend> <input type="range" name="age" id="age" value="21" min="1" max="100" data-devaluation-range= '{"0.05":{"min":60,"max":69},"0.1":{"min":70,"max":79},"0.2":{"min":80,"max":120}}' /> <output for="age">### not yet computed ###</output> </fieldset> <fieldset> <p> Do you have any long-term medical conditions that can affect daily life? </p> <label> <input type="radio" name="status" value="yes" data-devaluation-factor="0.3" /> <span class="label-copy"> Yes </span> </label> <label> <input type="radio" name="status" value="no" /> <span class="label-copy"> No </span> </label> </fieldset> <fieldset> <p> Are you currently employed? </p> <label> <input type="radio" name="empstatus" value="yes" data-devaluation-factor="0.3" /> <span class="label-copy"> Yes </span> </label> <label> <input type="radio" name="empstatus" value="no" /> <span class="label-copy"> No </span> </label> </fieldset> <fieldset> <legend> Membership Fee </legend> <label> <span class="label-copy"> Total Fee: </span> <output data-fee-value>### not yet computed ###</output> </label> <button type="reset">Restore base fee</button> </fieldset> </form>

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda