2016-11-23 3 views
1

Я пишу обычай bindingHandler в knockout для форматирования (US) телефонных номеров в следующем формате по мере их ввода.Форматируйте номер телефона при вводе (xxx) xxx - xxxx

(ххх) ххх - хххх

HTML код ...

<input type="text" data-bind="phoneNumber: phone" /> 

И связывающий обработчик ...

ko.bindingHandlers.phoneNumber = { 
    init: function(element, valueAccessor, allBindings) { 
     ko.bindingHandlers.value.init(element,valueAccessor, allBindings); 
     },  
    update: function(element, valueAccessor) { 
     var phone = ko.utils.unwrapObservable(valueAccessor()); 
     if (!phone) return; 
     var output; 
     input = phone; 
     input = input.replace(/[^0-9]/g, ''); 
     var areaCode = input.substr(0, 3); 
     var nextThreeDigits = input.substr(3, 3); 
     var lastFourDigits = input.substr(6, 4); 

     if (areaCode.length < 3) { 
      output = "(" + areaCode; 
     } else if (areaCode.length == 3 && nextThreeDigits.length < 3) { 
      output = "(" + areaCode + ")" + " " + nextThreeDigits; 
     } else if (areaCode.length == 3 && nextThreeDigits.length == 3) { 
      output = "(" + areaCode + ")" + " " + nextThreeDigits + "-" + lastFourDigits; 
     } 

     var phoneObs = valueAccessor(); 
     phoneObs(output); 
    } 
}; 

Следующий код работает, как ожидалось. Одним потоком с таким подходом является удаление номера телефона с использованием backspace. Как только он удаляет последние четыре цифры и удаляет -, он не может удалить - или (), так как я динамически добавляю - и () в зависимости от длины. Я могу использовать клавиши со стрелками или щелкать перед этими символами и начинать удаление, или я могу выделить текстовое поле и удалить все сразу. Но мне нужно иметь возможность удалять символы по обратному пространству или имитировать и удалять его из кода динамически.

Любые предложения о том, как я могу решить эту проблему?

UPDATE

Вот JSFIDDLE. Единственная проблема, с которой я столкнулся в этой скрипке, - это не обновление значений при изменении значения. Он обновляется только в том случае, если вы нажимаете клавишу ввода или оставляете текстовое поле. Не уверен. Если мне не хватает чего-то еще ...

Я обновил свою логику, чтобы учесть проблему, которую я испытываю, которая исправлена. Но я заметил, что у обеих логик есть еще одна проблема.

Если у меня есть номер телефона

(123) 456-7890

Если удалить 1 из код зоны, курсор не остается в том же месте (до 2). Он перемещается в конец строки, и все сдвигает одно число вниз.

if (areaCode.length <= 3 && nextThreeDigits == "") { 
    output = "(" + areaCode; 
} else if (areaCode.length == 3 && nextThreeDigits < 3) { 
    output = "(" + areaCode + ")" + " " + nextThreeDigits; 
} else if (areaCode.length == 3 && nextThreeDigits.length <= 3 && lastFourDigits.length == "") { 
    output = "(" + areaCode + ")" + " " + nextThreeDigits; 
} else if (areaCode.length == 3 && nextThreeDigits.length == 3 && lastFourDigits.length <= 4) { 
    output = "(" + areaCode + ")" + " " + nextThreeDigits + "-" + lastFourDigits; 
} 
+0

Есть ли jsFiddle мы могли бы играть с? ^^ – Whothehellisthat

+0

@Whothehellisthat, я обновил вопрос и добавил jsfiddle. – smr5

ответ

1

как об использовании маски ввода (Jasny имеет приятный один http://www.jasny.net/bootstrap/) и пользовательские привязки.

вот скрипка, где я это сделал.http://jsfiddle.net/vL59q8e1/2/

вот Javascript для связывания

ko.bindingHandlers.inputmask = { 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
    ko.bindingHandlers.value.init(element, valueAccessor, allBindings); 

    $(element).inputmask({ 
     mask: '(999) 999-9999' 
     }); 
    }, 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
    var value = valueAccessor(); 
     } 
}; 
+0

Это кажется довольно интересным подходом. Я попробую и дам вам знать, как это сработало для меня. Благодарю. – smr5

+0

Мне нравится эта концепция, однако, одна проблема, с которой я сталкиваюсь с таким подходом, для которого я еще не нашел решение, заключается в том, что если вы не вводите точные номера телефонов формата (10 цифр), неправильные номера телефонов исчезают , И у меня нет записей об этом. Я все еще хочу иметь возможность захватить неправильные значения. – smr5

+0

Вы выяснили способ захвата неправильных номеров телефонов? Я немного поиграл с ним, но так и не получил хорошего решения –

0

легкий путь, чтобы добавить метки после того, есть достаточное количество символов, такие, что курсор всегда трогательные номера. Поскольку текстовое поле добавляет эти символы, у вас есть эта ошибка, когда вы добавляете нечисловые символы. Например, ошибка, о которой вы говорили в «-», также происходит, когда у вас есть только 3 номера и вы пытаетесь удалить один номер (он удаляет пробел, а затем добавляет пробел). например: если 3 числа, (123, и это добавляет), после того, как они набирают в четвертом.

Другой способ - сохранить input = input.replace(/[^0-9]/g, ''); в поле данных элемента и пропустить весь выходной каскад, если номер не изменился. например:

input = input.replace(/[^0-9]/g, ''); 
if(element.phone == input){ return; } 
element.phone = input; 
+0

Благодарим вас за ввод. Но как это будет знать положение курсора? Если в код области (123) я удаляю 1, 2 и 3 смены вниз, а другой номер из следующих трех цифр становится региональным кодом. – smr5

+0

Он не знает курсора. У браузеров нет такого контроля над позицией курсора. Это возможно, но будет намного сложнее, если вы хотите отслеживать позицию курсора при наборе и удалении символов. Редакторы wysiwyg реализуют его, но это не то, что я могу свести к ответу stackoverflow. – Hong

+0

Хм, спасибо. – smr5