Передача данных в callback-функции

Передача данных в callback-функции в Cleave.js строится вокруг концепции реактивного обновления поля ввода: каждая модификация значения преобразуется библиотекой и сопровождается событием, содержащим полный контекст текущего состояния инпута. Это позволяет синхронизировать внешний код с внутренней логикой форматирования без необходимости вручную парсить строку.

Основной callback, используемый для отслеживания изменений значения, — onValueChanged. Он вызывается при каждом обновлении поля ввода после применения маскирования и форматирования.

Передаваемый аргумент представляет собой объект события, который содержит несколько уровней данных:

  • target — DOM-элемент input
  • value — отформатированное значение
  • rawValue — «сырое» значение без форматирования
  • properties — объект внутренних параметров Cleave.js
  • дополнительные служебные поля состояния

Ключевая особенность заключается в том, что Cleave.js не ограничивается передачей только DOM-события. Вместо этого библиотека расширяет контекст, добавляя вычисленные значения, что позволяет работать как с отображаемым, так и с исходным вводом одновременно.

Пример структуры:

onValueChanged: function (event) {
    console.log(event.target);
    console.log(event.target.value);
    console.log(event.target.rawValue);
    console.log(event.target.properties);
}

Raw и formatted values

Одним из центральных аспектов передачи данных является разделение значений на два слоя:

formatted value — значение, которое отображается пользователю в input после применения правил форматирования;

raw value — исходная строка, очищенная от разделителей, пробелов, масок и прочих визуальных преобразований.

Форматированное значение

event.target.value отражает итоговое значение после всех преобразований. Например, для телефонного номера:

+7 (777) 123-45-67

Это значение уже пригодно для отображения, но не для вычислений или хранения в базе данных без дополнительной очистки.

Сырое значение

event.target.rawValue содержит только значимые символы:

77771234567

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

Разделение этих двух сущностей — один из ключевых механизмов Cleave.js, позволяющий отделить UI-слой от бизнес-логики без дополнительных парсеров.

Объект properties и внутреннее состояние

Поле properties предоставляет доступ к внутреннему состоянию экземпляра Cleave.js. Это наиболее технически насыщенная часть callback-данных.

Обычно внутри properties содержатся:

  • текущая конфигурация форматирования
  • тип инпута (phone, credit card, numeral, date и т.д.)
  • разделители и маски
  • массив блоков (например, для кредитных карт или дат)
  • текущая позиция курсора (в некоторых режимах)
  • вспомогательные вычисленные параметры

Пример:

onValueChanged: function (event) {
    const props = event.target.properties;

    console.log(props.result); 
    console.log(props.delimiter);
    console.log(props.blocks);
    console.log(props.prefix);
}

Блоки форматирования

Для сложных форматов, таких как кредитные карты или даты, Cleave.js использует систему блоков (blocks). Например, номер карты может быть разбит на:

[4, 4, 4, 4]

Это означает, что ввод разбивается на группы по 4 символа, и каждый блок обрабатывается отдельно при форматировании.

Передача контекста и модель обновления

Callback-функции Cleave.js работают в синхронной модели: каждое изменение input вызывает пересчёт значения и немедленный вызов обработчика.

Важная особенность заключается в том, что передаваемые данные всегда отражают уже обработанное состояние, а не промежуточный ввод пользователя.

Это означает:

  • событие вызывается после применения маски
  • значение уже стабилизировано
  • курсор уже скорректирован библиотекой

Такой подход исключает необходимость debounce в большинстве сценариев обработки форм.

onCreditCardTypeChanged и специализированные данные

Отдельный callback onCreditCardTypeChanged используется при работе с режимом кредитных карт. Он вызывается при изменении типа карты на основе введённых цифр.

Передаваемое значение обычно представляет собой строку с типом карты:

  • visa
  • mastercard
  • amex
  • discover

Пример:

new Cleave(input, {
    creditCard: true,
    onCreditCardTypeChanged: function (type) {
        console.log(type);
    }
});

Механизм определения типа

Определение типа карты происходит по BIN (Bank Identification Number), то есть по первым цифрам номера. Cleave.js анализирует префикс и сопоставляет его с известными диапазонами.

Передаваемые данные в callback минималистичны: только строковый идентификатор типа карты без дополнительного контекста. Это делает обработку быстрой и предсказуемой.

Синхронизация пользовательского состояния

Callback-и Cleave.js часто используются для синхронизации внешнего состояния приложения с введёнными данными. В этом случае важно учитывать различие между источниками данных:

  • DOM value — отображаемое значение
  • rawValue — логическое значение
  • callback event — агрегированный объект состояния

Пример интеграции с состоянием:

onValueChanged: function (event) {
    state.formatted = event.target.value;
    state.raw = event.target.rawValue;
}

Такой подход позволяет строить архитектуру, в которой UI-слой полностью отделён от слоя данных.

Особенности передачи данных при программном изменении

Если значение устанавливается программно через методы Cleave.js (например, setRawValue), callback также срабатывает, но структура данных может отличаться по времени вызова.

В этом случае:

  • событие инициируется после применения форматирования
  • rawValue отражает установленное значение
  • value пересчитывается синхронно

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

Контекст курсора и косвенные данные

Хотя Cleave.js не всегда явно передаёт позицию курсора в публичных API, внутренние properties могут содержать информацию, используемую для корректировки caret position.

Это особенно важно в сценариях:

  • вставка больших чисел
  • форматирование дат
  • ввод кредитных карт с разделителями

Корректировка курсора происходит автоматически, но через callback можно наблюдать косвенные признаки изменений через итоговое значение и структуру блоков.

Нюансы интерпретации данных callback

При работе с callback-данными важно учитывать несколько технических особенностей:

  1. value всегда зависит от текущей конфигурации форматирования
  2. rawValue не содержит визуальных символов, но может сохранять логическую структуру
  3. properties может изменяться между вызовами даже при одинаковом вводе
  4. быстрый ввод пользователя может приводить к частым последовательным вызовам callback

Из-за этого обработка данных должна быть идемпотентной и не зависеть от порядка промежуточных состояний.

Пример комплексной обработки данных

new Cleave(input, {
    phone: true,
    onValueChanged: function (event) {
        const value = event.target.value;
        const raw = event.target.rawValue;
        const props = event.target.properties;

        if (raw.length > 10) {
            form.valid = true;
        }

        form.display = value;
        form.cleaned = raw;
        form.formatMeta = {
            delimiter: props.delimiter,
            blocks: props.blocks
        };
    },
    onCreditCardTypeChanged: function (type) {
        form.cardType = type;
    }
});

В этом примере видно, что callback-и формируют поток данных, в котором каждое изменение input становится источником обновления нескольких уровней состояния: визуального, логического и мета-описательного.

Передача данных как часть архитектуры ввода

Механизм callback-функций в Cleave.js фактически реализует событийную модель управления данными, где каждое изменение инпута превращается в структурированное событие с предсказуемыми полями.

Такой подход позволяет использовать библиотеку не только как инструмент форматирования, но и как слой нормализации пользовательского ввода, в котором данные уже разделены на уровни готовности к обработке.