Веб

ngx-mask 20.0.3: автоматическая запятая в separator

Как настроить ngx-mask 20.0.3 для автоматической вставки десятичного разделителя (запятой) как в версии 7. Используйте mask="separator", [decimalMarker] и [thousandSeparator]. Примеры кода, отладка и альтернативы для ngx mask angular.

Как автоматически вставлять десятичный разделитель в ngx-mask 20.0.3?

Я использую ngx-mask 20.0.3 и столкнулся с проблемой с маской separator.2, которая работала иначе в версии 7.0.0.

В ngx-mask 7.0.0 я использовал этот код:

html
<input type="text" mask="separator.2" thousandSeparator="." decimalMarker="," prefix="" formnovalidate matInput formControlName="amount" required />

При вводе чисел, таких как 123, значение автоматически форматировалось как 1.23.

Однако в ngx-mask 20.0.3 запятая в качестве десятичного разделителя не вставляется автоматически. Я пробовал добавлять [leadZero]="true", но запятая все равно должна вводиться пользователем вручную.

Как настроить ngx-mask 20.0.3 для автоматической вставки запятой в качестве десятичного разделителя при вводе чисел пользователем, аналогично поведению в версии 7.0.0?

В консоли нет никаких ошибок, но значение 123 не форматируется как 1.23, что вызывает проблемы в моем приложении.

В ngx mask (ngx mask angular) 20.0.3 поведение маски с десятичными изменилось: вместо устаревшей separator.2 нужно использовать mask="separator" и передавать параметры как Angular inputs ([decimalMarker], [thousandSeparator]) — либо реализовать лёгкий форматтер, который вставляет запятую перед двумя последними цифрами. Ниже — конкретные варианты: быстрый HTML‑пример, рабочий компонент (reactive form), глобальная конфигурация и чеклист отладки.


Содержание


Почему в ngx-mask изменилась маска separator? (ngx mask)

Коротко: поведение separator.2, которое автоматически «вставляло» разделитель перед двумя последними цифрами в старых версиях (v7 и т.д.), было переработано/убрано в более новых релизах. Разработчики унифицировали API: теперь используется mask="separator", а параметры вроде thousandSeparator, decimalMarker, prefix/suffix — вводятся как Inputs Angular (через квадратные скобки) и/или задаются глобально. Подробные обсуждения и баг‑репорты есть в репозитории проекта (пример запроса по поведению и желаемой автоматике — см. обсуждение на GitHub) и в связанных issue, где отмечают регрессии поведения между версиями: issue #733 и issue #1259. Документация старых версий (пример) показывает прежнее поведение, но в новых релизах синтаксис и семантика изменились — это причина, почему код из v7 не работает «из коробки» в 20.0.3.


Быстрое решение: настройка mask=“separator” (ngx mask angular)

Самый простой шаг — заменить mask="separator.2" на mask="separator" и передавать разделители как inputs:

html
<input
 type="text"
 mask="separator"
 [thousandSeparator]="'.'"
 [decimalMarker]="','"
 [prefix]="''"
 formnovalidate
 matInput
 formControlName="amount"
 required
/>

Важно: использовать привязку через [] для thousandSeparator и decimalMarker (в новых версиях эти опции — inputs, а не простые атрибуты). Это описано в репозитории и README библиотеки — см. основной репозиторий: JsDaddy/ngx-mask и пример использования в README‑mirror unpkg README.

Но! это не всегда автоматически вставит запятую перед двумя последними цифрами при последовательном наборе “123” → “1,23”. Если поведение не сравнивается со старой v7, есть два надёжных варианта:

  • Вариант A (быстрый): использовать небольшую обработку ввода, которая превращает строку цифр в формат с запятой перед двумя последними цифрами (см. пример ниже).
  • Вариант B: попробовать альтернативную маску/шаблон (например, mask="0*.00") — это обходной путь, который иногда даёт нужный результат (см. обсуждение на StackOverflow с примером 0*.00) StackOverflow.

Пример кода: module + component + template

Ниже — рабочий пример для reactive form: показано, как склеить автоматическую вставку запятой (перед двумя последними цифрами) через небольшую функцию форматирования. Этот подход надёжен и не зависит от того, убрали ли separator.2 в API.

app.module.ts — глобальная конфигурация (варианты):

ts
// Option A: старый стиль (forRoot)
import { NgModule } from '@angular/core';
import { NgxMaskModule } from 'ngx-mask';

@NgModule({
 imports: [
 NgxMaskModule.forRoot({
 thousandSeparator: '.',
 decimalMarker: ',',
 dropSpecialCharacters: false // если хотите сохранять разделители в модели
 })
 ]
})
export class AppModule {}
ts
// Option B: новый стиль (provide)
import { NgModule } from '@angular/core';
import { provideNgxMask } from 'ngx-mask';

@NgModule({
 providers: [
 provideNgxMask({ thousandSeparator: '.', decimalMarker: ',', dropSpecialCharacters: false })
 ]
})
export class AppModule {}

component.ts — reactive form + форматтер:

ts
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { debounceTime } from 'rxjs/operators';

@Component({
 selector: 'app-amount',
 templateUrl: './amount.component.html'
})
export class AmountComponent implements OnInit {
 form = new FormGroup({
 amount: new FormControl('')
 });

 ngOnInit() {
 const ctrl = this.form.get('amount')!;
 ctrl.valueChanges
 .pipe(debounceTime(50))
 .subscribe(val => {
 // raw digits only
 const digits = String(val || '').replace(/\D/g, '');
 if (!digits) {
 ctrl.setValue('', { emitEvent: false });
 return;
 }
 // integer part is everything except last 2 digits
 const intPart = digits.slice(0, -2) || '0';
 const decPart = digits.slice(-2).padStart(2, '0');
 // add thousand separators to integer part
 const intWithSep = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
 const formatted = `${intWithSep},${decPart}`;
 if (formatted !== val) {
 ctrl.setValue(formatted, { emitEvent: false });
 }
 });
 }
}

component.html:

html
<input
 type="text"
 mask="separator"
 [thousandSeparator]="'.'"
 [decimalMarker]="','"
 [prefix]="''"
 formControlName="amount"
 matInput
/>

Пояснение: логика берёт только цифры, формирует десятичную часть из двух последних цифр и обновляет контрол с уже отформатированной строкой. Это даёт ровно поведение старой separator.2 — ввод “123” превращается в “1,23”.


Отладка: чеклист и типичные ошибки

  • Проверьте версию пакета: npm ls ngx-mask или package.json (страница пакета: npm ngx-mask).
  • Убедитесь, что вы используете mask="separator", а не separator.2 (в v20 separator.2 может быть удалён/изменён).
  • Передавайте thousandSeparator и decimalMarker как inputs: [thousandSeparator]="'.'" и [decimalMarker]="','" — не просто атрибуты.
  • Используйте type="text", а не type="number" — HTML number мешает форматированию.
  • Если хотите, чтобы в модели (FormControl.value) сохранялся форматированный текст с запятой/точками, поставьте [dropSpecialCharacters]="false" или настройте глобально.
  • Проверяйте влияние Angular Material / сторонних директив (matInput) — иногда они взаимодействуют с событиями ввода.
  • Если поведение кажется багом — посмотрите похожие issue/регрессии в репозитории: issue #733 и issue #1259.

Альтернативы и патчи (leadZero, mask-паттерны, кастомный форматтер)

  • leadZero: опция [leadZero]="true" помогает вводить значение, начинающееся с разделителя (например, .110,11), но не делает автоматическую вставку десятичного символа при наборе «123».
  • Альтернативная маска: некоторые решают задав mask="0*.00" (пример решения — StackOverflow), это может автоматически показывать точку/запятую, но поведение отличается в разных версиях.
  • Кастомный форматтер (предложенный выше) — самый надёжный способ получить поведение из v7: вы полностью контролируете, как именно ввод превращается в формат с двумя десятичными знаками. Подход прост, транспарентен и легко тестируется.

Источники


Заключение

Если кратко: в ngx mask 20.0.3 замените separator.2 на mask="separator" и используйте [decimalMarker]="','" и [thousandSeparator]="'.'" как inputs; для поведения «вставлять запятую автоматически перед двумя последними цифрами» надёжно применять лёгкий форматтер на valueChanges (пример выше) или попробовать маску 0*.00. Этот подход восстанавливает поведение, похожее на ngx-mask v7, и решает проблему форматирования 123 → 1,23.

Авторы
Проверено модерацией
Модерация
ngx-mask 20.0.3: автоматическая запятая в separator