-2

I have made a small calculator, where I want the sum in to be displayed with the format currency in the readonly input text. Since I'm new to javascript (and this forum), I can't get it to work. Thought my code below would work. Can anyone give me some pointers on how to make it work?

<h2>Calculator/h2>

<input
  type="text"
  id="number1"
  value="0"
  onchange="summa.value = (number1.value*1) + (number2.value*1)"
/>

<br>

<input
  type="text"
  id="number2"
  value="0"
  onchange="summa.value = (number1.value*1) + (number2.value*1)"
/>

<br/><br/>

<input
  type="text"
  readonly="readonly"
  id="summa"
  value="0"
  onchange="this.value.toLocaleString("sv-SE", {
    style:"currency", 
    currency:"SEK",
    currencyDisplay:"symbol",
    maximumFractionDigits: 0
  });"
/>


pa7ryk
  • 521
  • 6
  • 13
  • You should always format your code It helps us read it better Read this to learn more on [how to format code](https://meta.stackoverflow.com/questions/251361/how-do-i-format-my-code-blocks) – Golam Moula Feb 04 '23 at 10:30
  • Thanks! Now I know how to do that :-) – Hans Niklas Feb 04 '23 at 10:42
  • Quite a few typos, but also programatic changes to an input don't trigger an `on change` event. It will be far clearer to abstract your methods into its own script and then appropriately update the total. – pilchard Feb 04 '23 at 11:05

1 Answers1

1

Your code as posted shows quite a few typos, but the main reason it 'doesn't work' is that programatic changes to an input don't trigger a change event. It will be far clearer to abstract your methods into its own script and then appropriately handle the changes and update the total.

Here is a minimal example of your logic abstracted into html and a separate script. The inputs have been changed to type="number" to avoid entering non-numeric values. The script then queries the three inputs using getElementById and attaches change listeners to the two accepting input using addEventListener. Finally there is a single function declared to update the value of the third input with the formatted value.

const number1 = document.getElementById('number1');
const number2 = document.getElementById('number2');
const summa = document.getElementById('summa');

function updateTotal() {
  const total = Number(number1.value) + Number(number2.value);
  summa.value = total.toLocaleString('sv-SE', {
    style: 'currency',
    currency: 'SEK',
    currencyDisplay: 'symbol',
    maximumFractionDigits: 0,
  });
}

number1.addEventListener('change', updateTotal);
number2.addEventListener('change', updateTotal);
<h2>Calculator</h2>

<input type="number" id="number1" value="0"/>
<br />
<input type="number" id="number2" value="0" />
<br />
<input type="text"  id="summa" readonly="true" value="0"/>

note: your method of coercing a string to number is valid, but there are more transparent methods. Here I'm using the Number constructor directly but there are plenty of other methods


If you somehow feel that you need to do this all inline you can apply the same logic, but you'll instantly note the amount of duplicated code.

<h2>Calculator</h2>

<input type="number" id="number1" value="0" onchange="summa.value = (Number(number1.value) + Number(number2.value)).toLocaleString('sv-SE', {
    style: 'currency',
    currency: 'SEK',
    currencyDisplay: 'symbol',
    maximumFractionDigits: 0,
});" />
<br />

<input type="number" id="number2" value="0" onchange="summa.value = (Number(number1.value) + Number(number2.value)).toLocaleString('sv-SE', {
    style: 'currency',
    currency: 'SEK',
    currencyDisplay: 'symbol',
    maximumFractionDigits: 0,
});" />
<br />

<input type="text" readonly="readonly" id="summa" value="0" />

Alternatively you can include an inline script as a decent compromise.

<h2>Calculator</h2>

<input type="number" id="number1" value="0" />
<br />
<input type="number" id="number2" value="0" />
<br />
<input type="text" id="summa" readonly="true" value="0" />

<script type="module">
  const number1 = document.getElementById('number1');
  const number2 = document.getElementById('number2');
  const summa = document.getElementById('summa');

  function updateTotal() {
    const total = Number(number1.value) + Number(number2.value);
    summa.value = total.toLocaleString('sv-SE', {
      style: 'currency',
      currency: 'SEK',
      currencyDisplay: 'symbol',
      maximumFractionDigits: 0,
   });
  }

  number1.addEventListener('change', updateTotal);
  number2.addEventListener('change', updateTotal);
</script>
pilchard
  • 12,414
  • 5
  • 11
  • 23
  • Up vote, though I do wonder how this works when the country code is set to El Salvador (sv) and the currency is in Swedish krona (SEK). – Yogi Feb 04 '23 at 11:23
  • 1
    `sv-SE` is [Swedish (Sweden)](https://www.localeplanet.com/icu/sv-SE/index.html) confusion with `es-SV` [Spanish (El Salvador)](https://www.localeplanet.com/icu/es-SV/index.html) – pilchard Feb 04 '23 at 11:26
  • Thanks, you are correct. toLocaleString expects an [ISO-639](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1252447) language code and not an [ISO-3166](https://docs.oracle.com/cd/E13214_01/wli/docs92/xref/xqisocodes.html#wp1250799) country code. – Yogi Feb 04 '23 at 12:11