При работе с денежными значениями, бухгалтерскими системами, финансовыми панелями, аналитикой и пользовательскими формами возникает необходимость корректно обрабатывать отрицательные числа. Библиотека Cleave.js поддерживает подобные сценарии через механизм числового форматирования.
Отрицательные значения особенно важны в следующих случаях:
Главная особенность заключается в том, что отрицательное число
содержит символ -, который должен корректно
взаимодействовать с:
Для числового режима используется параметр numeral.
<input id="price">
new Cleave('#price', {
numeral: true
});
Поле начинает автоматически форматировать числа:
1000 → 1,000
5000000 → 5,000,000
По умолчанию отрицательные числа также поддерживаются:
-1000 → -1,000
-55000 → -55,000
Символ минуса сохраняется в начале строки и участвует в дальнейшем форматировании.
Для управления отрицательными значениями существует специальная настройка:
numeralPositiveOnly
Она определяет, разрешены ли отрицательные числа.
new Cleave('#price', {
numeral: true,
numeralPositiveOnly: false
});
Теперь допустимы:
-10
-2500
-999999
new Cleave('#price', {
numeral: true,
numeralPositiveOnly: true
});
В этом режиме:
-1000
автоматически преобразуется в:
1000
или минус игнорируется ещё на этапе ввода.
Корректный сценарий:
-12345
После форматирования:
-12,345
Некорректный ввод:
123-45
Библиотека автоматически нормализует значение и пытается сохранить только допустимый формат.
Ввод:
--100
обычно преобразуется к:
-100
Лишние символы удаляются.
Отрицательные числа часто используются вместе с дробной частью.
new Cleave('#price', {
numeral: true,
numeralDecimalScale: 2
});
Пример:
-1234.56
После форматирования:
-1,234.56
new Cleave('#price', {
numeral: true,
numeralDecimalMark: ',',
delimiter: ' '
});
Ввод:
-1234567,89
Результат:
-1 234 567,89
new Cleave('#price', {
numeral: true,
prefix: '$',
rawValueTrimPrefix: true
});
Результат:
-$5,000
или:
$-5,000
в зависимости от логики обработки строки.
В большинстве финансовых систем используются два основных варианта отображения.
-$1,500
$-1,500
Cleave.js не содержит отдельного параметра для позиционирования минуса относительно префикса. Обычно подобное поведение реализуется дополнительной обработкой значения.
Пример ручной корректировки:
const cleave = new Cleave('#price', {
numeral: true,
prefix: '$',
rawValueTrimPrefix: true
});
document.querySelector('#price').addEventListener('input', function () {
let value = cleave.getRawValue();
if (value.startsWith('-')) {
this.value = '-$' + value.substring(1);
}
});
Метод:
getRawValue()
возвращает исходное значение без форматирования.
Пример:
-1,234,567.89
Метод вернёт:
-1234567.89
Это особенно важно для:
Чаще всего после получения raw-значения выполняется преобразование:
const raw = cleave.getRawValue();
const number = Number(raw);
Для отрицательных значений:
"-5500.25"
результат:
-5500.25
const input = document.querySelector('#price');
input.addEventListener('input', function () {
const value = Number(cleave.getRawValue());
if (value < -1000) {
console.log('Минимальный предел превышен');
}
});
input.addEventListener('input', function () {
const value = Number(cleave.getRawValue());
if (value < -5000 || value > 5000) {
console.log('Число вне диапазона');
}
});
input.addEventListener('input', function () {
let value = Number(cleave.getRawValue());
if (value < -1000) {
value = -1000;
}
if (value > 1000) {
value = 1000;
}
this.value = value;
});
В некоторых системах отрицательные значения отображаются через круглые скобки.
(1,500.00)
Внутри Cleave.js подобное форматирование отсутствует, однако его можно реализовать вручную.
function formatAccounting(value) {
const number = Number(value);
if (number < 0) {
return '(' + Math.abs(number).toLocaleString() + ')';
}
return number.toLocaleString();
}
new Cleave('#percent', {
numeral: true,
suffix: '%'
});
Ввод:
-12.5
Результат:
-12.5%
Подобный формат часто применяется в:
new Cleave('#temp', {
numeral: true,
suffix: ' °C'
});
Результат:
-15 °C
const regex = /^-?\d+(\.\d+)?$/;
Поддерживаются:
100
-100
55.25
-55.25
const value = Number(cleave.getRawValue());
if (Number.isNaN(value)) {
console.log('Некорректное число');
}
Промежуточное состояние ввода:
-
является распространённой проблемой.
Пользователь может ввести минус, но ещё не указать цифры.
const raw = cleave.getRawValue();
if (raw === '-') {
return;
}
Без подобной проверки:
Number('-')
вернёт:
NaN
import Cleave from 'cleave.js/react';
function PriceInput() {
return (
<Cleave
options={{
numeral: true,
numeralDecimalScale: 2,
numeralPositiveOnly: false
}}
/>
);
}
<cleave
:options="options"
v-model="price"
/>
export default {
data() {
return {
price: '',
options: {
numeral: true,
numeralPositiveOnly: false
}
};
}
};
<input
cleave="{
numeral: true,
numeralPositiveOnly: false
}"
/>
Причины:
parseInt('-12.99')
вернёт:
-12
Дробная часть будет потеряна.
Для финансовых значений обычно используется:
parseFloat()
или:
Number()
Некоторые локали используют:
-1.234,56
а другие:
-1,234.56
Неправильная конфигурация:
numeralDecimalMark
delimiter
может привести к ошибкам парсинга.
new Cleave('#price', {
numeral: true,
delimiter: '_'
});
Результат:
-1_000_000
new Cleave('#price', {
numeral: true,
numeralIntegerScale: 6
});
Максимально допустимое значение:
999999
Для отрицательных чисел:
-999999
Минус не учитывается в ограничении длины целой части.
new Cleave('#price', {
numeral: true,
numeralThousandsGroupStyle: 'lakh'
});
Результат:
-12,34,567
new Cleave('#price', {
numeral: true,
numeralThousandsGroupStyle: 'wan'
});
Результат:
-1234,5678
Иногда необходимо отдельно обрабатывать знак числа.
const value = Number(cleave.getRawValue());
if (value < 0) {
console.log('Отрицательное число');
}
Math.abs(value)
-15,000
может обозначать задолженность.
-2.15%
обозначает снижение.
-$550
используется для отображения списаний.
Отрицательные значения часто выделяются визуально.
input.addEventListener('input', function () {
const value = Number(cleave.getRawValue());
if (value < 0) {
this.style.color = 'red';
} else {
this.style.color = 'black';
}
});
Перед отправкой данных рекомендуется:
const raw = cleave.getRawValue();
const value = Number(raw);
if (!Number.isNaN(value)) {
sendToServer(value);
}
Обычно используются:
numeral: true
numeralDecimalScale: 2
numeralPositiveOnly: false
Часто достаточно:
numeral: true
numeralPositiveOnly: false
Дополнительно применяются:
Наиболее удобным считается поведение, при котором: