javascripthtmlnumber-formatting

How to Automatically Format Numbers as Indian Numeration in HTML Input Fields?


I am working on a financial web application targeted at an Indian audience, and I need to allow users to enter monetary amounts in input fields that automatically format the numbers into Indian numeration style (e.g., "1,00,000" for one lakh). The goal is to have the input field format the number dynamically as the user types, reflecting commas according to Indian numbering system (lakhs and crores).

I've tried using basic JavaScript to manipulate the input value, but I'm encountering issues with cursor positioning and handling backspaces that make the input erratic. Here's the basic code I've been experimenting with:

document.getElementById('myInput').addEventListener('input', function (e) {
    var x = e.target.value.replace(/,/g, '');
    x = x.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    e.target.value = x;
});

This script does not handle cursor positions well, especially when deleting characters, and it can reset the cursor to the end of the line, which is not user-friendly.

How can I improve this script to handle cursor positions intelligently while maintaining the Indian numeration format? Are there any libraries or plugins that can simplify this functionality? Any help or pointers towards solving this would be greatly appreciated!


Solution

  • I am not sure your transformation is correct, because it converts 100000 into 100,000, shouldn't that be 1,00,000?

    Anyway, the following scheme should work for any transformation that adds non-digits while preserving the digits. It stores the number of digits before the cursor in offset, then executes the transformation and places the cursor after the offsetth digit again.

    In order to locate and set the position of the cursor, it uses the Selection interface on an editable <div> rather than an <input> element.

    onload = () => document.querySelector("div").focus();
    function transformation(input) {
      return input.replace(/,/g, "")
        .replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
    document.querySelector("div").addEventListener("input", function(event) {
      var offset = event.target.textContent.substring(0, getSelection().focusOffset).match(/\d/g)?.length || 0;
      var s = transformation(event.target.textContent);
      event.target.textContent = s;
      getSelection().setPosition(event.target.firstChild, s.match(new RegExp(`^(\\D*\\d){${offset}}`))[0].length);
    });
    <div contenteditable></div>