Библиотека Cleave.js позволяет создавать динамические маски ввода на
основе набора правил. В основе механизма лежит разделение значения на
блоки (blocks) и применение разделителей
(delimiters) либо специальных обработчиков.
Собственная маска строится вокруг следующих параметров:
new Cleave('.input-element', {
blocks: [4, 4, 4, 4],
delimiter: '-'
});
Результат:
1234-5678-9012-3456
Массив blocks определяет длину каждой части строки, а
delimiter — символ-разделитель между ними.
Минимальная конфигурация включает:
new Cleave(selector, {
blocks: [],
delimiter: ''
});
| Свойство | Назначение |
|---|---|
blocks |
размеры сегментов |
delimiter |
единый разделитель |
delimiters |
массив разных разделителей |
uppercase |
автоматический upper-case |
lowercase |
автоматический lower-case |
numericOnly |
разрешение только цифр |
prefix |
фиксированный префикс |
noImmediatePrefix |
отложенный вывод префикса |
rawValueTrimPrefix |
удаление префикса из rawValue |
Пример пользовательского идентификатора:
new Cleave('.code-input', {
blocks: [3, 3, 3],
delimiter: ':',
uppercase: true
});
Формат:
ABC:DEF:GHI
Если требуется несколько различных разделителей:
new Cleave('.serial-input', {
blocks: [2, 4, 2, 6],
delimiters: ['-', '/', '#']
});
Результат:
12-3456/78#123456
Количество элементов в delimiters должно быть на единицу
меньше количества блоков.
Фактически:
blocks.length - 1 === delimiters.length
new Cleave('.passport', {
blocks: [2, 2, 6],
delimiters: [' ', '-'],
uppercase: true
});
Результат:
AB 12-123456
Свойство numericOnly запрещает ввод любых нечисловых
символов.
new Cleave('.numeric-code', {
blocks: [5, 5],
delimiter: '-',
numericOnly: true
});
Попытка ввода:
12AB345
Превратится в:
12345
new Cleave('.license', {
prefix: 'LIC',
blocks: [3, 4, 4],
delimiters: ['-', '-'],
uppercase: true
});
Результат:
LIC-ABCD-1234
new Cleave('.invoice', {
prefix: 'INV',
blocks: [3, 6],
delimiter: '-'
});
Поле сразу содержит:
INV-
new Cleave('.invoice', {
prefix: 'INV',
noImmediatePrefix: true,
blocks: [3, 6],
delimiter: '-'
});
Теперь префикс появится только после начала ввода.
Cleave.js хранит два значения:
| Тип | Описание |
|---|---|
| formatted value | отображаемое значение |
| rawValue | значение без форматирования |
Пример:
new Cleave('.bank-code', {
blocks: [4, 4, 4],
delimiter: '-'
});
Ввод:
1234-5678-9999
rawValue:
123456789999
Получение значения:
const cleave = new Cleave('.bank-code', {
blocks: [4, 4, 4],
delimiter: '-'
});
console.log(cleave.getRawValue());
Эти параметры взаимно исключают друг друга.
new Cleave('.upper', {
blocks: [4, 4],
delimiter: '-',
uppercase: true
});
new Cleave('.lower', {
blocks: [4, 4],
delimiter: '-',
lowercase: true
});
new Cleave('.partial', {
blocks: [2, 2, 2, 2],
delimiter: '-'
});
Во время ввода:
12-
12-34-
12-34-56-
Маска формируется постепенно.
new Cleave('.compact', {
blocks: [4, 4, 4]
});
Разделители отсутствуют, но ограничение длины блоков сохраняется.
Суммарная длина вычисляется автоматически:
blocks: [3, 3, 3]
Максимум:
9 символов
Если используется delimiter:
delimiter: '-'
Отображаемая длина:
11 символов
Но rawValue остаётся длиной 9.
Маска может изменяться динамически.
const cleave = new Cleave('.dynamic', {
blocks: [4, 4],
delimiter: '-'
});
document.querySelector('.dynamic')
.addEventListener('input', function(e) {
if (e.target.rawValue.length > 8) {
cleave.destroy();
new Cleave('.dynamic', {
blocks: [4, 4, 4],
delimiter: '-'
});
}
});
new Cleave('.employee-id', {
blocks: [2, 3, 5],
delimiters: ['/', '-'],
uppercase: true
});
Результат:
HR/452-98125
const inputs = document.querySelectorAll('.masked');
inputs.forEach(input => {
new Cleave(input, {
blocks: [3, 3, 3],
delimiter: '.'
});
});
Метод destroy() удаляет обработчики и
форматирование.
const cleave = new Cleave('.field', {
blocks: [4, 4],
delimiter: '-'
});
cleave.destroy();
Cleave.js автоматически корректирует позицию курсора при:
Это особенно важно для сложных пользовательских шаблонов.
new Cleave('.unicode-mask', {
blocks: [2, 2, 2],
delimiters: ['•', '→']
});
Результат:
12•34→56
new Cleave('.hex-input', {
blocks: [2, 2, 2],
delimiter: ':',
uppercase: true
});
Результат:
AF:45:1C
new Cleave('.mac-address', {
blocks: [2, 2, 2, 2, 2, 2],
delimiter: ':',
uppercase: true
});
Результат:
AA:BB:CC:DD:EE:FF
При вставке строки Cleave.js:
Пример:
Буфер:
123456789012
Маска:
blocks: [4, 4, 4],
delimiter: '-'
Результат:
1234-5678-9012
Обработчик позволяет реагировать на изменение значения.
new Cleave('.tracking', {
blocks: [4, 4, 4],
delimiter: '-',
onValueChanged: function(event) {
console.log(event.target.value);
console.log(event.target.rawValue);
}
});
function createMask(selector, config) {
return new Cleave(selector, {
blocks: config.blocks,
delimiters: config.delimiters,
delimiter: config.delimiter,
uppercase: config.uppercase,
numericOnly: config.numericOnly
});
}
Использование:
createMask('.product-code', {
blocks: [3, 5, 2],
delimiters: ['-', '/'],
uppercase: true
});
Ошибка:
blocks: [2, 2, 2],
delimiters: ['-']
Правильно:
blocks: [2, 2, 2],
delimiters: ['-', '-']
Ошибка:
uppercase: true,
lowercase: true
Использоваться должен только один режим.
Без этого параметра пользователь сможет вводить текст.
Наиболее затратные операции:
Хорошая практика:
const config = {
blocks: [4, 4, 4],
delimiter: '-'
};
document.querySelectorAll('.mask')
.forEach(el => new Cleave(el, config));
const cleave = new Cleave('.payment-id', {
blocks: [4, 4, 4],
delimiter: '-'
});
form.addEventListener('submit', function() {
hiddenInput.value = cleave.getRawValue();
});
В интерфейсе отображается форматированное значение, а на сервер отправляется очищенная строка.
function buildMask(type) {
switch(type) {
case 'passport':
return {
blocks: [2, 2, 6],
delimiters: [' ', '-']
};
case 'tax':
return {
blocks: [3, 3, 3],
delimiter: '.'
};
}
}
<input
type="text"
class="serial"
/>
new Cleave('.serial', {
blocks: [5, 5],
delimiter: '-'
});
const input = document.querySelector('.device-id');
new Cleave(input, {
blocks: [4, 4, 4],
delimiter: ':'
});
new Cleave('.advanced-mask', {
prefix: 'SYS',
noImmediatePrefix: true,
blocks: [3, 4, 4, 2],
delimiters: ['-', '/', '#'],
uppercase: true,
onValueChanged: function(event) {
console.log(event.target.value);
}
});
Результат:
SYS-ABCD/1234#99