How to format a US/CAN phone number using jQuery as you type?

javascript, jquery, phone-number, regex

Solution

I pieced together answers to other related questions, as well as my own code, and came up with this solution that seems to work well:

// Phone formatting: (555) 555-5555
$("#phone").on("keyup paste", function() {
    // Remove invalid chars from the input
    var input = this.value.replace(/[^0-9\(\)\s\-]/g, "");
    var inputlen = input.length;
    // Get just the numbers in the input
    var numbers = this.value.replace(/\D/g,'');
    var numberslen = numbers.length;
    // Value to store the masked input
    var newval = "";

    // Loop through the existing numbers and apply the mask
    for(var i=0;i<numberslen;i++){
        if(i==0) newval="("+numbers[i];
        else if(i==3) newval+=") "+numbers[i];
        else if(i==6) newval+="-"+numbers[i];
        else newval+=numbers[i];
    }

    // Re-add the non-digit characters to the end of the input that the user entered and that match the mask.
    if(inputlen>=1&&numberslen==0&&input[0]=="(") newval="(";
    else if(inputlen>=6&&numberslen==3&&input[4]==")"&&input[5]==" ") newval+=") ";
    else if(inputlen>=5&&numberslen==3&&input[4]==")") newval+=")";
    else if(inputlen>=6&&numberslen==3&&input[5]==" ") newval+=" ";
    else if(inputlen>=10&&numberslen==6&&input[9]=="-") newval+="-";

    $(this).val(newval.substring(0,14));
});

Problem

I have a phone field in an HTML form that needs to be formatted (555) 555-5555 Here's the field: ``` <input type="tel" id="phone" name="phone" placeholder="(555) 555-5555" autocomplete="off" maxlength="14" required="required"> ``` A few requirements: - It should auto-format as you type. - It should auto-format after pasting. - It should only allow digits, (, ), -, and spaces to be entered. - If the user types one of the non-digit characters that are part of the mask, it should allow those characters in the field so long as they're in the right position. Don't strip them. For example, if the first character they type into the field is an open parentheses, it should allow it. If it's a digit, it should update it to an open parentheses followed by that digit. If it's any other character, it should remove it. How can this type-as-you-go mask be applied with these requirements using jQuery/Javascript?

Original source