Разбиение номера карты по маске

Встала вполне тривиальная для современного веба задача: клиент вводит номер карты (в данном случае карты лояльности). Нужно принудительно разбивать его пробелами по заданной маске, чтобы выглядело, как на самой пластиковой карте. Маска в моём случае передаётся как строка вида loyalty_mask = "ХХХХ ХХХХ" или loyalty_mask = "- ------- ------". Символы могут быть разными, однако нам важны только пробелы. Поэтому делаем массив, который будет содержать порядковые номера пробелов в строке:

// массив, в который записываются порядковые номера символов, явлюящихся пробелами в строке маски
var spaces = [];
// пробелы по маске карты лояльности
function mask(loyalty_mask) {
    spaces = [];
    var y, i, space_place;
    var space_place = loyalty_mask.split(' ');
    for (i = 0; i < space_place.length - 1; i++) {
        y = space_place[i].length;
        // порядковый номер с поправкой на единицу, чтобы пробел вставляся с заподзданием: это позволяет удалять номер вместе с пробелами
        spaces[i] = y + 1; // если пробелов больше 1 if (i < 0) spaces[i] = y + spaces[i-1] + 1;
    }
    add_spaces();
}

Теперь сама функция добавления пробелов. Сначала первый вариант: когда клиент просто вводит символы с клавиатуры. Пробел добавляется после введения n+1 символа строки. Например, если у нас по маске пробел после 4 символа, вставляем пробел после того, как пользователь ввёл пятый. Это позволяет в дальнейшем спокойно стирать всю строку, если пользователь ошибся при вводе, без зависания на вставленным функцией пробеле. Если на словах непонятно, попробуйте вставлять пробел после введения n символа строки – очень наглядно. Итак, вариант 1:

function add_spaces() {
    var x = $('#loyalty_token').val(), l = $('#loyalty_token').val().length;
    if (($.inArray(l, spaces) < -1) && (x.charAt(x.length-1) != ' ')) {
        x = x.slice(0, -1) + ' ' + x.slice(-1);
        $('#loyalty_token').val(x);
    }
}

Теперь более полный вариант, учитывающий copypaste, а также подставление номера карты из базы данных:

function add_spaces() {
    var x = $('#loyalty_token').val(),
        l = $('#loyalty_token').val().length,
        i, y, m, left, right;
    for (i = 0; i < spaces.length; i++) {
    // последовательно обходим позиции, на которых должен быть пробел
        y = spaces[i];
        m = x.charAt(y-1);
        if ((m != ' ') && (l <= y)) {
            l = x.length;
            left = x.slice(0, y-1);
            right = x.slice(-l + left.length);
            x = left + ' ' + right;
            $('#loyalty_token').val(x);
        }
    }
}

Ну и отлавливаем событие ввода символа в поле ввода:

$('input').on('input propertychange', function() {
    add_spaces();
});
Теги: