Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Форматирование вводимого номера + 7 123 456-78-90 (https://javascript.ru/forum/dom-window/26506-formatirovanie-vvodimogo-nomera-7-123-456-78-90-a.html)

danik.js 11.03.2012 04:24

Форматирование вводимого номера + 7 123 456-78-90
 
Хочу сделать чтобы при вписывании номера в input происходило вот такое незамысловатое форматирование.
Пока даже не знаю с чего начать. Я понимаю что тут нужно использовать регулярку и прослушивать события keypress, change.
Но как все совместить, не пойму. Может кто уже делал подобную штуку?

Впринципе важно чтобы все работало при вручном вводе номера, корректная работа backspace. На вставку из буфера можно забить - врядли кто-то будет этим пользоваться.

T-sh 11.03.2012 05:11

по кейпрессу вызываешь функцию, которая сразу ставит плюс и пробел, дальше проверяет позицию каретки (курсора). если 3 (плюс уже занимает первое место, пробел — второе) — к значению поля (value) добавляешь ещё один пробел, если 7 — тоже самое (добавляешь пробел), если 11 — добавляешь дефис, и если 14 — тоже дефис.

devote 11.03.2012 06:55

var numbers = [
    "+71234567890",
    "1234567890",
    "234567890",
    "34567890",
    "4567890",
    "567890",
    "67890",
    "7890",
    "890",
    "90",
    "0"
]

var re = /(?:([\d]{1,}?))??(?:([\d]{1,3}?))??(?:([\d]{1,3}?))??(?:([\d]{2}))??([\d]{2})$/;

for( var i = 0; i < numbers.length; i++ ) {
    var formatted = numbers[ i ].replace( re, function( all, a, b, c, d, e ){
        return ( a ? a + " " : "" ) + ( b ? b + " " : "" ) + ( c ? c + "-" : "" ) + ( d ? d + "-" : "" ) + e;
    });

    alert( formatted  );
}

devote 11.03.2012 07:21

Чушь конечно получилась, ну и фиг с ним :D
<input type="text" onkeyup="handler( this )" oninput="handler( this )" onblur="handler( this )" />
<script>
    var re = /(?:([\d]{1,}?))??(?:([\d]{1,3}?))??(?:([\d]{1,3}?))??(?:([\d]{2}))??([\d]{2})$/;
    function handler( elem ) {
        elem.value = elem.value.replace( /[^0-9]/g, '' ).replace( re, function( all, a, b, c, d, e ){
            return ( a ? "+ " + a + " " : "" ) + ( b ? b + " " : "" ) + ( c ? c + "-" : "" ) + ( d ? d + "-" : "" ) + e;
        });
    }
</script>

nerv_ 11.03.2012 11:05

еще вариант
<input type="text" onkeyup="formattingNumbers( this )">
<script>
	function formattingNumbers( elem ) {
		var num = elem.value.replace( /\D/g, '' ).split( /(?=.)/ ), i = num.length - 1;
		if ( 0 <= i ) num.unshift( '+ ' );
		if ( 1 <= i ) num.splice( 2, 0, ' ' );
		if ( 4 <= i ) num.splice( 6, 0, ' ' );
		if ( 7 <= i ) num.splice( 10, 0, '-' );
		if ( 9 <= i ) num.splice( 13, 0, '-' );
		elem.value = num.join( '' );
	}
</script>

рони 11.03.2012 15:18

Вариант ...
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
<input type="text" onkeyup="formattingNumbers( this )" value="+ 7 ">
<script>
function formattingNumbers(b) {
    var a = "+ 7 123 456-78-90",
        c = b.value.match(/\d/g);
        if(!c) return b.value = "+ 7 ";
        a = a.replace(/\d/g, function () {
            return c.shift() || "#"
        });
    b.value = a.replace(/#.*/, "")
};</script>
</body>
</html>

danik.js 11.03.2012 17:17

Благодарю всех.
У devote форматирование идет как то с конца, вводить номер неудобно. Зато можно ввести международный номер с кодом страны боьше чем из одной цифры :) . Но мне это не нужно.
У рони нельзя удалить ошибочноо введенные цифры (
Самый адекватный вариант у nerv'а , осталось только ограничение сделать.

danik.js 11.03.2012 18:02

А что вот это такое? 'string'.split( /(?=.)/ ) - это такой способ преобразования строки в массив?

Кстати чтобы заработал бэкспейс в вариант от рони, достаточно использовать такую регулярку
b.value = a.replace(/(\ |-)#.*/, "")

nerv_ 11.03.2012 21:07

danik.js, да не, рони нормальный вариант предложил, за что ему плюс в карму :) Хотя, может быть в моем меньше замен/манипуляций производится, но в оптимизации сложнее.
Еще такой вариант на его основе
<input type="text" onkeyup="formattingNumbers( this )" value="+ 7 123 456-78-90">
<script>
	function formattingNumbers( elem ) {
		var pattern = '+ 7 123 456-78-90', arr = elem.value.match( /\d/g ), i = 0;
		if ( arr === null ) return;
		elem.value = pattern.replace( /\d/g, function( a, b ) {
			if ( arr.length ) i = b + 1;
			return arr.shift();
		}).substring( 0, i );
	}
</script>

danik.js 11.03.2012 21:13

Как то понравился ваш вариант, nerv, хотя у рони задать паттерн можно. Вобщем вроде бы разобрался в обоих способах, особой разницы для меня нет что использовать.
Вопрос такой: сложно ли сделать чтоб контролировалась вставка из буфера?

Выложу окончательный вариант, вдруг кому понадобится (jQuery) :
$.fn.formatPnoneNumber = function(){
			return this.each(function(){
				$(this).bind('keyup', function(){
					var num = this.value.replace( '+ 7' , '' ).replace( /\D/g, '' ).split( /(?=.)/ ), i = num.length;
					if ( 0 <= i ) num.unshift( '+ 7' );
					if ( 1 <= i ) num.splice( 1, 0, ' ' );
					if ( 4 <= i ) num.splice( 5, 0, ' ' );
					if ( 7 <= i ) num.splice( 9, 0, '-' );
					if ( 9 <= i ) num.splice( 12, 0, '-' );
					if ( 11 <= i ) num.splice( 15, num.length - 15 );
					this.value = num.join( '' );
				});
			});
		};


Часовой пояс GMT +3, время: 09:19.