Home > other >  Vanilla javascript to auto-format an input field with only numbers and allows leading zeros
Vanilla javascript to auto-format an input field with only numbers and allows leading zeros

Time:02-03

Similar questions on SO, but mine's a bit unique. I want to limit an input text field to 9 characters in length (currently solved with maxlength attribute), only allow typing in numeric values and the hyphen character. Sort of handled with this code returning "True":

/^\d*\-?\d*$/.test(value)

Where I'm stuck is I want the input text field to auto-format the value as the user types in the format:

12345-123

Where it's 5 digits (may have leading zeros or not depending on how user inputs it), followed by a hyphen, then always 3 digits. I'd like it to pad the first 5 with zeros if user enters something like "123-495" manually, so it would become "00123-495".

I'm not sure how to add in the auto-zero padding, or placement of the hyphen automatically.

Not opposed to using jQuery, but would prefer vanilla.

EDIT: Thought it might be useful to add. This is for an access card number entry box. So value will always be a positive number, and will always have 3 digits after the single hyphen. The card number will always be 5-digits in length, but again, may be padded with zeros to make it that length. Ideal output should always be "xxxxx-xxx".

EDIT 2: This seems to work, but there's an issue where user can enter non-numeric characters at first and after the 1st entry, only then does it clear it out. It also doesn't seem to let me hit backspace past the hyphen... There a way to prevent it from allowing alpha characters completely?

// Restricts input for the given textbox to the given inputFilter function.
function setInputFilter(textbox, inputFilter) {
    ["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop"].forEach(function(event) {
        textbox.addEventListener(event, function() {
            if (inputFilter(this.value)) {
                // Current value
                new_val = '';
                if (this.value.includes('-') && this.value.slice(this.value.indexOf('-')).length == 4) {
                    console.log("Value not hyphenated yet");
                    pad_needed = 5 - this.value.indexOf('-');
                    console.log('Pad needed: '   pad_needed);

                    new_val = this.value.padStart(9, '0');
                    this.value = new_val;
                } else if (this.value.length >= 5 && this.value.includes('-') && this.value.slice(this.value.indexOf('-')).length == 4) {
                    if (this.value.slice(5, 1) == '-') {
                        // Already a hyphen added, just add rest of numbers
                        new_val = this.value.slice(0, 6)   this.value.slice(6);
                    } else {
                        // Needs hyphen added
                        new_val = this.value.slice(0, 5)   '-'   this.value.slice(6);
                    }
                    this.value = new_val;
                } else if (this.value.length >= 5 && !this.value.includes('-')) {
                    // Needs hyphen added
                    new_val = this.value.slice(0, 5)   '-'   this.value.slice(6);
                    this.value = new_val;
                }

                this.oldValue = this.value;
                this.oldSelectionStart = this.selectionStart;
                this.oldSelectionEnd = this.selectionEnd;
            } else if (this.hasOwnProperty("oldValue")) {
                this.value = this.oldValue;
                this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
            } else {
                this.value = "";
            }
        });
    });
}

setInputFilter(document.getElementById("card-number"), function(value) {
    return /^\d*\-?\d*$/.test(value); // Allow digits and '-' only
});

CodePudding user response:

function getSanitizedInputValue(value) {
  value = value
    .trim()
    .replace(/^[-] /, '')
    .replace(/[-] /, '-');

  let [
    first,
    ...rest
  ] = (value.match(/[-\d] /g) ?? [])
    .join('')
    .split('-')

  let joiner = '';

  if (first.length >= 6) {
    joiner = '-';

    rest.unshift(first.slice(5));
    first = first.slice(0, 5);

  } else if (rest.length >= 1) {
    joiner = '-';

    first = first.padStart(5, '0');
  }
  return [
    first,
    rest.join(''),
  ]
  .join(joiner)
  .slice(0,9);
}

function handleInput({ currentTarget: control }) {
  let { selectionStart, selectionEnd } = control;

  const value = getSanitizedInputValue(control.value);
  const maxLength = value.length;

  control.value = getSanitizedInputValue(value);

  control.selectionStart = Math.min(maxLength, selectionStart);
  control.selectionEnd = Math.min(maxLength, selectionEnd);
}
document
  .querySelector('[type="text"]')
  .addEventListener('input', handleInput);
<input type="text" maxlength="9" />

CodePudding user response:

const phone = "123-495"
const fixed = phone.replace(/(\d )\-?(\d{3})/g, function (match, p1, p2) {
    const zero = 5 - p1.length;
    for (let z = 0; z < zero; z  ) {
        p1 = 0   p1;
    }
    return `${p1}-${p2}`;
});

console.log(fixed)
  •  Tags:  
  • Related