Отформатируйте номер телефона как пользовательский тип, используя чистый JavaScript

У меня есть поле ввода в теле моего документа, и мне нужно отформатировать его по типу пользователя. Он должен иметь скобки вокруг кода области и тире между тремя и четырьмя цифрами после этого.

Пример: (123) 456 - 7890

Как пользовательский тип, он должен выглядеть примерно так:

(12
(123)
(123) 456
(123) 456 - 78
(123) 456 - 7890

Ответ 1

Новый ответ ES6

Вы все еще можете сделать это, используя простой JavaScript.

HTML

<input id="phoneNumber" maxlength="16"/>

JavaScript (ES6)

const isNumericInput = (event) => {
    const key = event.keyCode;
    return ((key >= 48 && key <= 57) || // Allow number line
        (key >= 96 && key <= 105) // Allow number pad
    );
};

const isModifierKey = (event) => {
    const key = event.keyCode;
    return (event.shiftKey === true || key === 35 || key === 36) || // Allow Shift, Home, End
        (key === 8 || key === 9 || key === 13 || key === 46) || // Allow Backspace, Tab, Enter, Delete
        (key > 36 && key < 41) || // Allow left, up, right, down
        (
            // Allow Ctrl/Command + A,C,V,X,Z
            (event.ctrlKey === true || event.metaKey === true) &&
            (key === 65 || key === 67 || key === 86 || key === 88 || key === 90)
        )
};

const enforceFormat = (event) => {
    // Input must be of a valid number format or a modifier key, and not longer than ten digits
    if(!isNumericInput(event) && !isModifierKey(event)){
        event.preventDefault();
    }
};

const formatToPhone = (event) => {
    if(isModifierKey(event)) {return;}

    // I am lazy and don't like to type things more than once
    const target = event.target;
    const input = target.value.replace(/\D/g,'').substring(0,10); // First ten digits of input only
    const zip = input.substring(0,3);
    const middle = input.substring(3,6);
    const last = input.substring(6,10);

    if(input.length > 6){target.value = '(${zip}) ${middle} - ${last}';}
    else if(input.length > 3){target.value = '(${zip}) ${middle}';}
    else if(input.length > 0){target.value = '(${zip}';}
};

const inputElement = document.getElementById('phoneNumber');
inputElement.addEventListener('keydown',enforceFormat);
inputElement.addEventListener('keyup',formatToPhone);

И если вы хотите возиться с этим:
https://jsfiddle.net/rafj3md0/

Отказ от ответственности:
Стоит отметить, что это немного странно, если вы пытаетесь изменить середину числа из-за того, как браузеры обрабатывают размещение в каратах после установки значения элемента. Решение этой проблемы выполнимо, но потребовало бы больше времени, чем у меня сейчас, и есть библиотеки, которые обрабатывают подобные вещи.


Старый ES5 Ответ

Вы можете сделать это с помощью быстрой функции JavaScript.

Если ваш HTML выглядит так:
<input type="text" id="phoneNumber"/>

Ваша функция JavaScript может быть просто:

// A function to format text to look like a phone number
function phoneFormat(input){
        // Strip all characters from the input except digits
        input = input.replace(/\D/g,'');

        // Trim the remaining input to ten characters, to preserve phone number format
        input = input.substring(0,10);

        // Based upon the length of the string, we add formatting as necessary
        var size = input.length;
        if(size == 0){
                input = input;
        }else if(size < 4){
                input = '('+input;
        }else if(size < 7){
                input = '('+input.substring(0,3)+') '+input.substring(3,6);
        }else{
                input = '('+input.substring(0,3)+') '+input.substring(3,6)+' - '+input.substring(6,10);
        }
        return input; 
}

Конечно, вам понадобится прослушиватель событий:

document.getElementById('phoneNumber').addEventListener('keyup',function(evt){
        var phoneNumber = document.getElementById('phoneNumber');
        var charCode = (evt.which) ? evt.which : evt.keyCode;
        phoneNumber.value = phoneFormat(phoneNumber.value);
});

И если вы не можете хранить телефонные номера в виде отформатированных строк (я не рекомендую этого), вы должны очистить нечисловые символы перед отправкой значения примерно так:
document.getElementById('phoneNumber').value.replace(/\D/g,'');

Если вы хотите увидеть это в действии с бонусной фильтрацией ввода, проверьте эту скрипку:
http://jsfiddle.net/rm9vg16m/

Ответ 2

Ранее ответы не учитывали, что происходит, когда пользователь делает ошибку и удаляет некоторые из введенных цифр.

Для тех, кто ищет решение jQuery, он переформатирует в каждом событии keyup и удаляет дополнительные символы и пробелы, когда пользователь редактирует номер.

$('#phone').keyup(function(e){
    var ph = this.value.replace(/\D/g,'').substring(0,10);
    // Backspace and Delete keys
    var deleteKey = (e.keyCode == 8 || e.keyCode == 46);
    var len = ph.length;
    if(len==0){
        ph=ph;
    }else if(len<3){
        ph='('+ph;
    }else if(len==3){
        ph = '('+ph + (deleteKey ? '' : ') ');
    }else if(len<6){
        ph='('+ph.substring(0,3)+') '+ph.substring(3,6);
    }else if(len==6){
        ph='('+ph.substring(0,3)+') '+ph.substring(3,6)+ (deleteKey ? '' : '-');
    }else{
        ph='('+ph.substring(0,3)+') '+ph.substring(3,6)+'-'+ph.substring(6,10);
    }
    this.value = ph;
});

Ответ 3

Я не поклонник нарезки. Я бы посоветовал использовать .replace(), передать ему регулярное выражение, захватить фрагменты номера телефона и затем выводить его так, как вам нужно. Если вы можете читать регулярное выражение, это гораздо лучший программный способ подойти к проблеме, а мертвый просто изменить формат.

var phoneNumber = "1234567899";

var formatted = phoneNumber.replace(/(\d{1,2})(\d{1})?(\d{1,3})?(\d{1,4})?/, function(_, p1, p2, p3, p4){
  let output = ""
  if (p1) output = `(${p1}`;
  if (p2) output += `${p2})`;
  if (p3) output += ` ${p3}`
  if (p4) output += ` ${p4}`
  return output;
});

Примечание. Я не добавил ни одного пробела, но не номера, но вы также можете добавить это.

Ответ 4

Чтобы добавить некоторую дополнительную легкость для пользователя, я бы фактически обновил строку, чтобы автоматически включать ")" или "-", когда пользователь достигает определенных символов, чтобы они не добавляли, скажем, две тире. (555) 555--5555

if(size === 0) {
    input = input;
} 
else if (size === 3) {
    input = '('+input.substring(0,3)+') '
}
else if (size < 4) {
    input = '('+input;
}
else if (size === 6) {
    input = '('+input.substring(0,3)+') '+input.substring(3,6)+' -';
}
else if (size > 6) {
    input = '('+input.substring(0,3)+') '+input.substring(3,6)+' - '+input.substring(6,10);
}
return input

Ответ 5

let telEl = document.querySelector('#phoneNum')

telEl.addEventListener('keyup', (e) => {
  let val = e.target.value;
  e.target.value = val
    .replace(/\D/g, '')
    .replace(/(\d{1,4})(\d{1,3})?(\d{1,3})?/g, function(txt, f, s, t) {
      if (t) {
        return '(${f}) ${s}-${t}'
      } else if (s) {
        return '(${f}) ${s}'
      } else if (f) {
        return '(${f})'
      }
    });
})
Phone Number: <input type="text" id="phoneNum" maxlength="14" />