Home > Net >  Is there a way to show a calculated result (updating anytime there is a change) from a few input box
Is there a way to show a calculated result (updating anytime there is a change) from a few input box

Time:12-14

I am currently writing a simple calculator as an exercise.

I have a few input fields where the user can put certain values, then clicking a button a function is triggered where it does some calculations and shows the output in a table.

The input I am interested in is the following:

<p>Total eligible voters:
    <input type="text" id="totalVoters" name="totalVoters" placeholder="0">
</p>

<p>Voter turnout:
    <input type="text" id="voterTurnout" name="voterTurnout" placeholder="0">
</p>

<p>Percentage of ineligible bulletins:
    <input type="text" id="ineligibleBulletins" name="ineligibleBulletins" placeholder="0">
</p>
<br><br>

Once that data is filled, the user has to fill however many votes they wish each party to receive. I can't figure out (a simple) way to show however many votes are still unaccounted for.

For example, if the user puts totalVoters = 1000 , voterTurnout = 50% , ineligibleBulletins = 10% the total unaccounted votes are (1-0.1)(0.51000) = 450.

And as the user starts filling the other field for voters per each party, say party1 = 50, I want to show (somewhere) however many (unaccounted) votes there are left, in this case 400.

I was considering some kind of a loop, but can't really figure out how to update the unaccountedVotes once a change occurs. Using JS.

CodePudding user response:

I would try setting up an event listener for changes made to the inputs. Then have it update the output whenever a change is made. But I'm fairly new to programming and there could be a simpler way.

CodePudding user response:

explanation in progress

function updateUnaccountedVotesFromBoundContext() {
  const { output, total, turnout, ineligible } = this;
  output
    .value = Math.round(
      (1 - (ineligible.valueAsNumber / 100)) *
      (turnout.valueAsNumber / 100) *
      total.valueAsNumber
    );
}

function updateRangePseudoContent({ currentTarget }) {
  currentTarget.setAttribute('value', currentTarget.value);
}
document
  .querySelectorAll('[type="range"]')
  .forEach(elmNode =>
    elmNode.addEventListener('input', updateRangePseudoContent)
  );

document
  .querySelectorAll('fieldset')
  .forEach(rootNode => {

    const output = rootNode
      .querySelector('output');
    const total = rootNode
      .querySelector('[data-name="total-voters"]');
    const turnout = rootNode
      .querySelector('[data-name="voter-turnout"]');
    const ineligible = rootNode
      .querySelector('[data-name="ineligible-bulletins"]');

    rootNode
      .addEventListener(
        'input',
        updateUnaccountedVotesFromBoundContext
          .bind({ output, total, turnout, ineligible })
      );

    // initialization from all current elements data.
    updateUnaccountedVotesFromBoundContext
      .call({ output, total, turnout, ineligible });
  });
fieldset { width: 70%; padding-top: 0; padding-bottom: 0; }
fieldset, label { margin: 5px 0; }
label { width: 90%; }
label, label > span, label > input {
  position: relative;
  display: block;
}
[type="range"] {
  width: calc(100% - 10px - 4em);
}
[type="range"]::after {
  position: absolute;
  left: calc(100%   10px);
  content: attr(value)' %';
  width: 4em;
  height: 1em,
}
output {
  font-weight: bolder;
}
<fieldset>
  <label>
    <span>Total eligible voters</span>
    <input type="number" min="0" step="1" value="1000" data-name="total-voters">
  </label>

  <label>
    <span>Voter turnous</span>
      <input type="range" min="0" max="100" value="50" step="0.1" data-name="voter-turnout">
  </label>

  <label>
    <span>Percentage of ineligible bulletins</span>
      <input type="range" min="0" max="100" value="10" step="0.1" data-name="ineligible-bulletins">
  </label>

  <label>
    <span>Unaccounted votes</span>
    <output>0</output>
  </label>
</fieldset>

<fieldset>
  <label>
    <span>Total eligible voters</span>
    <input type="number" min="0" step="1" value="25000" data-name="total-voters">
  </label>

  <label>
    <span>Voter turnous</span>
      <input type="range" min="0" max="100" value="70" step="0.1" data-name="voter-turnout">
  </label>

  <label>
    <span>Percentage of ineligible bulletins</span>
      <input type="range" min="0" max="100" value="5" step="0.1" data-name="ineligible-bulletins">
  </label>

  <label>
    <span>Unaccounted votes</span>
    <output>0</output>
  </label>
</fieldset>

  • Related