Получение исходных и отформатированных значений

В Cleave.js ключевая модель работы строится вокруг разделения данных на два представления: исходное значение (raw value) и отформатированное значение (formatted value). Эта концепция определяет поведение всей библиотеки и влияет на то, как данные извлекаются, сохраняются и передаются дальше по приложению.

Разделение raw и formatted значений

Raw value представляет собой «чистые» данные без визуального форматирования. Обычно это:

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

Formatted value — это строка, отображаемая в input-поле, с применёнными правилами маскирования:

  • добавленные пробелы, дефисы, скобки;
  • разделители тысяч;
  • префиксы и суффиксы валют;
  • любые визуальные преобразования, заданные конфигурацией Cleave.js.

Эта двойственность лежит в основе всех механизмов библиотеки: пользователь работает с formatted value, а бизнес-логика — с raw value.


Поведение input-элемента

После инициализации Cleave.js перехватывает управление значением поля ввода. В результате:

  • input.value всегда содержит форматированную строку;
  • внутреннее состояние экземпляра хранит как formatted, так и raw представление;
  • любое изменение пользователем автоматически синхронизируется с обоими состояниями.

Пример типичного поведения:

  • ввод: 1234567890
  • отображение: +1 (234) 567-890
  • raw value: 1234567890

Доступ к значениям через экземпляр Cleave

После создания экземпляра:

const cleave = new Cleave(input, {
  phone: true,
  phoneRegionCode: 'US'
});

становится доступным объект управления состоянием.

Получение отформатированного значения

Отформатированное значение совпадает с тем, что находится в DOM-элементе:

const formatted = input.value;

или через экземпляр:

const formatted = cleave.properties.result;

В разных версиях Cleave.js внутреннее хранение может отличаться, но логика остаётся одинаковой: отображаемое значение всегда доступно как результат форматирования.


Получение исходного значения

Основной способ извлечения raw value:

const raw = cleave.getRawValue();

Метод возвращает строку без маски, полностью очищенную от форматирования.

Пример поведения:

Ввод Форматированное Raw
1234 5678 9012 3456 1234 5678 9012 3456 1234567890123456

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

  • удаление ведущих нулей;
  • приведение к числовому виду (в зависимости от опций numeral);
  • нормализация десятичного разделителя.

Обратная установка значений

Для управления состоянием извне используется обратная синхронизация.

Установка raw значения

cleave.setRawValue('1234567890');

После вызова:

  • Cleave.js автоматически пересчитывает formatted value;
  • обновляет DOM-элемент;
  • синхронизирует внутреннее состояние.

Это особенно важно при:

  • загрузке данных с сервера;
  • восстановлении формы;
  • динамическом обновлении значений.

Установка formatted значения

В большинстве случаев прямой установки formatted value не требуется, так как библиотека всегда нормализует ввод. Однако можно присвоить значение через input:

input.value = '+1 (234) 567-890';
cleave.setRawValue(cleave.getRawValue());

Такой подход используется для принудительной нормализации состояния.


Событие onValueChanged

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

const cleave = new Cleave(input, {
  phone: true,
  onValueChanged: function(e) {
    console.log(e.target.value);   // formatted value
    console.log(e.target.rawValue); // raw value
  }
});

Структура объекта события обычно включает:

  • target — DOM-элемент input
  • value — текущее отформатированное значение
  • rawValue — исходное значение без маски

Этот механизм позволяет полностью отказаться от ручного парсинга input.value.


Разница между value и rawValue в событиях

В рамках onValueChanged важно различать два поля:

  • e.value — визуальное представление, синхронизированное с UI
  • e.rawValue — чистые данные для бизнес-логики

Типичный пример использования:

onValueChanged: function(e) {
  sendToServer({
    phone: e.rawValue
  });
}

Таким образом, UI остаётся форматированным, а передача данных — стандартизированной.


Особенности numeral-масок

При использовании числового режима (numeral: true) поведение raw value может отличаться:

const cleave = new Cleave(input, {
  numeral: true,
  numeralThousandsGroupStyle: 'thousand'
});

В этом режиме:

  • formatted value содержит разделители тысяч;
  • raw value представляет собой «чистое число в строке»;
  • возможна нормализация десятичной части.

Пример:

Ввод Форматированное Raw
10000 10,000 10000
10000.50 10,000.50 10000.50

Влияние mask-типов на извлечение значений

Разные режимы Cleave.js по-разному формируют raw value:

Credit card mode

  • raw value: только цифры
  • formatted: группы по 4 символа

Phone mode

  • raw value: только цифры международного формата
  • formatted: с региональными разделителями

Date mode

  • raw value: числовая последовательность даты
  • formatted: с разделителями (/, -, .)

Это важно учитывать при унификации обработки данных на сервере.


Синхронизация состояния

Cleave.js поддерживает двустороннюю синхронизацию:

  1. пользователь вводит данные → обновляется formatted value
  2. formatted value пересчитывается → обновляется raw value
  3. вызывается callback onValueChanged

Любое внешнее изменение через setRawValue инициирует тот же цикл в обратном направлении.


Частые ошибки при получении значений

Использование input.value как raw

input.value всегда возвращает formatted строку. Использование её как raw приводит к:

  • ошибкам валидации;
  • некорректной отправке данных;
  • дублированию форматирования на сервере.

Попытка вручную очищать строку

Удаление символов через replace или regex часто конфликтует с внутренней логикой Cleave.js. Это приводит к:

  • рассинхронизации состояния;
  • скачкам курсора;
  • некорректной перерисовке input.

Потеря raw value при интеграции с фреймворками

В React, Vue или Angular при контролируемых компонентах часто сохраняется только formatted value, если не обрабатывать onValueChanged корректно. Это приводит к потере исходных данных при сабмите формы.


Практика хранения значений

На уровне архитектуры обычно разделяют:

  • UI слой → работает только с formatted value;
  • сервисный слой → принимает raw value;
  • API слой → хранит raw value как источник истины.

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


Итоговая модель работы с данными

Cleave.js всегда оперирует парой значений:

  • отображаемое значение (value)
  • логическое значение (rawValue)

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