1

I'm trying to emulate <input type="text"> to behave like <input type="number"> (up/down arrow keys increase/decrease value)

So far it works fine, except when value reaches Number.MAX_SAFE_INTEGER (9007199254740992) it stops increasing, but type="number" can go beyond that number. Is there a way I can somehow bypass this limitation in javascript?

const input = document.querySelector('input[type="text"]'),
      step = {ArrowUp: 1, ArrowDown: -1};

input.addEventListener("keydown", (e) =>
{
  if (step[e.key])
  {
    input.value = Number(input.value) + step[e.key];
    return e.preventDefault();
  }
});
<table>
  <tr>
    <td>type="text"</td>
    <td><input type="text" value="9007199254740990"></td>
    <td>use UP/DOWN arrow keys</td>
  </tr>
  <tr>
    <td>type="number"</td>
    <td><input type="number" value="9007199254740990"></td>
  </tr>
</table>

As per @CertainPerformance answer BigInt() seems to be a good work around, however it doesn't allow use float numbers. Also, with float numbers if step is set to for example 1.4, it shows some weird numbers like 4.199999999999999

vanowm
  • 9,466
  • 2
  • 21
  • 37

1 Answers1

1

Simply using BigInt notation instead looks to do the trick:

const input = document.querySelector('input[type="text"]'),
      step = {ArrowUp: 1n, ArrowDown: -1n};

input.addEventListener("keydown", (e) =>
{
  if (step[e.key])
  {
    input.value = BigInt(input.value) + step[e.key];
    return e.preventDefault();
  }
});
<table>
  <tr>
    <td>type="text"</td>
    <td><input type="text" value="9007199254740990"></td>
    <td>use UP/DOWN arrow keys</td>
  </tr>
  <tr>
    <td>type="number"</td>
    <td><input type="number" value="9007199254740990"></td>
  </tr>
</table>

If you're concerned about obsolete browsers, you can use an alternative implementation replicating BigInt.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thank you! It even better than the native type="number" input... For whatever reason when I've tried it before it was giving me error `Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions`. Weirdly your example works fine... – vanowm May 19 '21 at 02:32
  • You might've missed to change the `ArrowUp: 1` to `ArrowUp: 1n` etc - that'll allow the `+ step[e.key]` to work. – CertainPerformance May 19 '21 at 02:38
  • Yes, yes, I was using regular numbers for that. – vanowm May 19 '21 at 04:20
  • Hmmm this method however doesn't support float numbers... – vanowm May 19 '21 at 23:50
  • Yeah, it's BigInt, not BigDecimal. If you want large decimals, consider: https://stackoverflow.com/questions/16742578/bigdecimal-in-javascript – CertainPerformance May 19 '21 at 23:51