0

I have an input field of length 14 into which the user types a value. As the user types into it, I would like a space to be added automatically after first 2 characters and then after next 3 characters and then after next 3 characters. so if the user wants to enter 12345678901, it should be formatted to 12 345 678 901.

Also when user uses backspace to clear the characters, the space should automatically be removed. So in the above case when the cursor reaches 9 and user hits backspace, the cursor should move two places to left clearing 9 and the space before it.

I tried following the credit card formatting here Format credit card number but couldn't understnd how it is done. The code from above link is

formatInput(event: any) {
    var v = event.value.replace(/\s+/g, '').replace(/[^0-9]/gi, '')
    var matches = v.match(/\d{4,16}/g);
    var match = matches && matches[0] || ''
    var parts = []

    for (let i=0, len=match.length; i<len; i+=4) {
       parts.push(match.substring(i, i+4))
    }

    if (parts.length) {
      (<HTMLInputElement>document.getElementById("txtInput")).value = 
        parts.join(' ')
    } else {
        (<HTMLInputElement>document.getElementById("txtInput")).value 
          = event.value;
    }
}

The above code generates spaces after every 4 digits. My requirement is to accept any characters and generate spaces after first 2 characters and then after next 3 characters and then after next 3 characters. Please help me out with this.

4
  • You should share your current code in order to see where you are going wrong. Commented Mar 8, 2021 at 12:42
  • There are too many nuances with these solutions, and they all depend on your current code. So, please start on it, do something, and then please come back with a more specific question. Commented Mar 8, 2021 at 12:47
  • I added the code now in the question Commented Mar 8, 2021 at 12:55
  • Maybe var matches = v.split(/(?<=^\d{2})|\B(?=(?<=\d{4})(?:\d{3})+$)/)? Commented Mar 8, 2021 at 13:14

1 Answer 1

1

this is a working example that solves your problem.

function format(str) {
 if (str.length < 2) return str
  else {
    let [fl,sl,...lstr] = str
    lstr =lstr.reduce((acc, el, i) => (i % 3 ? acc[acc.length - 1]+=el : acc.push(el), acc),[])
  return `${fl}${sl} ${lstr.join(' ')}`.trim()
  }
}



const [input,result]= document.querySelectorAll('#input,#result')
input.oninput =()=>{
    const i = input.value.replace(/\s/g, '');
    input.value= format(i)
  }
<input type=text id=input />
<p id="result"></p>

Sign up to request clarification or add additional context in comments.

5 Comments

Abdel: Your solution fixed the problem. Thank you so much :)
There is one issue I noticed. If the value is 12 345 678 901 and if I focus the cursor to just after any space i.e before 3 or 6 or 9 and click backspace, the cursor moves to the end of the value i.e after last 1. For example if I focus the cursor to just before 3 and click backspace, the cursor moves to end of the value without actually deleting the space. How to fix this issue?
this behavior is expected because deleting a space retrigger the function that reformats the input so space takes its place again
Okay. Thank you.
Hi Abdel. Can you also please elaborate on what each line does in the above function?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.