0

I'm brand new to Angular.
I tried several approaches to dealing with large numbers using the input number type.

<input type="number" step="1" (change)="handleChange($event)"/>

When I enter the number 1234567890123456789 (a very large number) into this input box and click the arrow up or arrow down, it is frozen as scientific notation.

For exmaple:
I put this number 1234567890123456789. enter image description here

When I click the arrow up to increase the value, it will look like this, and the value 1234567890123456800 will be returned to my handleChange function (already lost precision).
enter image description here

As a result, text-type input is the solution. However, if I change the type from number to text, my spin box (arrows up and down) will disappear. I want to use text input while keeping the spin box and modifying its behavior. Is this something that can be done?
enter image description here

Thank you in advance.

Sunny
  • 167
  • 1
  • 3
  • 13
  • try create as type="text" adding manually the "spins" like this [SO](https://stackoverflow.com/questions/68023973/creating-a-number-spinner-with-angular-material/68026306#68026306) – Eliseo Dec 23 '22 at 13:21

1 Answers1

1

A proper solution will likely avoid numeric <input> fields for numbers that are larger than Javascript precision allows (as suggested in Eliseo's comment).

But, just for completeness, here is an approach that works with a numeric <input> and the native spinner. It manipulates the step so that a change in the value by one step can be detected although a change of +/- 1 is beyond the precision of a Javascript number. And based on whether it has detected an "up" or "down" spin, it increases the BigInt value of the input by +/- 1.

After each value change, the step is the numeric value, as seen by Javascript, even if this does not exactly match the string value (which is what counts when the form is submitted). But it matches closely enough to avoid a step mismatch.

This is probably more of a curiosity, especially since intermediate numbers during the "step detection" are visible.

function xstep(input) {
  input.oldValue = input.value;
  input.step = Number(input.value);
}
function nstep(input) {
  var delta = input.valueAsNumber - (Number(input.oldValue) || 0);
  if (delta > 0) delta = 1n;
  else if (delta < 0) delta = -1n;
  else return;
  try {
    var v = BigInt(input.oldValue);
  } catch(e) {
    v = BigInt(Number(input.oldValue));
  }
  input.value = (v + delta).toString();
  xstep(input);
}
<html>
<body>
  <input type="number" onkeyup="xstep(this)" onchange="nstep(this)"/>
</body>
</html>
Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • Thank you so much. It works when I change the value by pressing the arrow up or arrow down on my keyboard. When I spin the spinner, however, a sufficient notation appears before the correct value. Can we avoid it, or is it a limitation? – Sunny Dec 25 '22 at 16:03
  • Sorry, I mean "scientific notation". I spelled it incorrectly. Actually, it will display 0 when I click arrow down, also. – Sunny Dec 27 '22 at 08:54
  • See my edited answer. Of course you lose precision if you use scientific notation. – Heiko Theißen Dec 27 '22 at 09:09
  • Thank you so much. Can't we, however, avoid displaying 0 before the correct value? – Sunny Dec 27 '22 at 10:26
  • 1
    I'm afraid not. As I said, this solution is more of a curiosity. – Heiko Theißen Dec 27 '22 at 10:52