Групповые операции

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

Такой подход особенно важен в следующих сценариях:

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

Групповая обработка снижает количество повторяющегося кода и упрощает поддержку интерфейсов с большим количеством числовых компонентов.


Коллекции экземпляров AutoNumeric

После инициализации каждый элемент получает собственный экземпляр AutoNumeric.

const price = new AutoNumeric('#price');
const tax = new AutoNumeric('#tax');
const total = new AutoNumeric('#total');

При большом количестве полей экземпляры обычно объединяют в массив:

const fields = [
    new AutoNumeric('#price'),
    new AutoNumeric('#tax'),
    new AutoNumeric('#discount'),
    new AutoNumeric('#total')
];

Теперь все элементы можно обрабатывать централизованно.


Массовое обновление значений

Использование цикла

Наиболее распространённый вариант — перебор массива экземпляров.

fields.forEach(field => {
    field.set(0);
});

Все поля будут сброшены к нулю с автоматическим форматированием.


Применение одинакового значения

fields.forEach(field => {
    field.set('1000');
});

Результат зависит от настроек форматирования каждого экземпляра:

1 000,00 €
$1,000.00
1000.000

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


Групповое получение значений

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

const formattedValues = fields.map(field => {
    return field.getFormatted();
});

console.log(formattedValues);

Результат:

[
    '1 200,00',
    '500,00',
    '300,00',
    '1 400,00'
]

Получение числовых значений

const numericValues = fields.map(field => {
    return field.getNumber();
});

console.log(numericValues);

Результат:

[
    1200,
    500,
    300,
    1400
]

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

const rawValues = fields.map(field => {
    return field.getNumericString();
});

Результат:

[
    '1200',
    '500',
    '300',
    '1400'
]

Массовое изменение настроек

Одним из главных преимуществ групповых операций является централизованная смена конфигурации.

Изменение валюты

fields.forEach(field => {
    field.update({
        currencySymbol: '$',
        currencySymbolPlacement: 'p'
    });
});

Все элементы мгновенно обновят формат отображения.


Переключение локали

fields.forEach(field => {
    field.update({
        digitGroupSeparator: '.',
        decimalCharacter: ','
    });
});

До обновления:

1,234.56

После обновления:

1.234,56

Изменение количества десятичных знаков

fields.forEach(field => {
    field.update({
        decimalPlaces: 4
    });
});

Теперь все поля будут отображать:

100.0000

Использование общего CSS-селектора

Часто элементы инициализируются через единый селектор.

Инициализация группы

new AutoNumeric.multiple('.money', {
    currencySymbol: '€ ',
    decimalPlaces: 2
});

Все элементы с классом .money автоматически получают экземпляры AutoNumeric.


Метод AutoNumeric.multiple

Назначение

Метод AutoNumeric.multiple() предназначен для массовой инициализации набора элементов.


Базовый синтаксис

AutoNumeric.multiple(selector, options);

Пример

<input class="price">
<input class="price">
<input class="price">
AutoNumeric.multiple('.price', {
    decimalCharacter: ',',
    digitGroupSeparator: ' '
});

Возвращаемое значение multiple()

Метод возвращает массив экземпляров AutoNumeric.

const instances = AutoNumeric.multiple('.price', {
    currencySymbol: '$'
});

Теперь можно выполнять групповые операции:

instances.forEach(instance => {
    instance.set(500);
});

Работа с NodeList

Инициализация через querySelectorAll

const elements = document.querySelectorAll('.amount');

const instances = AutoNumeric.multiple(elements, {
    decimalPlaces: 2
});

Это особенно удобно при динамическом DOM.


Смешанные настройки

Индивидуальная конфигурация

Иногда требуется общая база настроек с локальными переопределениями.

const baseOptions = {
    digitGroupSeparator: ' ',
    decimalCharacter: ','
};

const salary = new AutoNumeric('#salary', {
    ...baseOptions,
    currencySymbol: '₸ '
});

const bonus = new AutoNumeric('#bonus', {
    ...baseOptions,
    currencySymbol: '$ '
});

Такой подход позволяет сохранить единообразие поведения.


Массовая очистка полей

Очистка через empty()

fields.forEach(field => {
    field.clear();
});

Все значения будут удалены.


Установка null

fields.forEach(field => {
    field.set(null);
});

Поведение зависит от параметров:

emptyInputBehavior

Массовое отключение полей

Блокировка ввода

fields.forEach(field => {
    field.node().disabled = true;
});

Повторное включение

fields.forEach(field => {
    field.node().disabled = false;
});

Групповое удаление AutoNumeric

Уничтожение экземпляров

fields.forEach(field => {
    field.remove();
});

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

  • удаляются обработчики событий;
  • прекращается автоформатирование;
  • элемент становится обычным input.

Динамически создаваемые элементы

Добавление новых полей

const input = document.createElement('input');

input.classList.add('money');

document.body.appendChild(input);

const anElement = new AutoNumeric(input, {
    currencySymbol: '€ '
});

Повторная массовая инициализация

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

AutoNumeric.multiple('.money', {
    currencySymbol: '€ '
});

Но важно избегать повторной инициализации уже существующих экземпляров.


Проверка существующего экземпляра

Использование getAutoNumericElement

const existing = AutoNumeric.getAutoNumericElement(input);

Если экземпляр уже существует:

if (!existing) {
    new AutoNumeric(input);
}

Групповая синхронизация значений

Копирование значения между полями

const source = new AutoNumeric('#source');

fields.forEach(field => {
    field.set(source.getNumericString());
});

Массовый расчёт итогов

Суммирование группы

const total = fields.reduce((sum, field) => {
    return sum + Number(field.getNumericString());
}, 0);

console.log(total);

Реакция на изменения группы

Подписка на события

fields.forEach(field => {
    field.node().addEventListener('autoNumeric:rawValueModified', () => {
        recalculate();
    });
});

Автоматический пересчёт

function recalculate() {
    const total = fields.reduce((sum, field) => {
        return sum + Number(field.getNumericString());
    }, 0);

    totalField.set(total);
}

Групповое изменение режима отображения

Скрытие валютных символов

fields.forEach(field => {
    field.update({
        currencySymbol: ''
    });
});

Возврат валюты

fields.forEach(field => {
    field.update({
        currencySymbol: '₸ '
    });
});

Централизованное управление точностью

Изменение decimalPlaces

fields.forEach(field => {
    field.update({
        decimalPlaces: 0
    });
});

Все значения станут целыми:

1 500
25
10000

Работа с большими формами

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

  • хранить экземпляры в Map;
  • разделять группы по назначению;
  • избегать повторных upd ate();
  • минимизировать количество DOM-операций;
  • обновлять только изменённые элементы.

Использование Map для группировки

const groups = new Map();

groups.se t('prices', [
    new AutoNumeric('#price1'),
    new AutoNumeric('#price2')
]);

groups.set('taxes', [
    new AutoNumeric('#tax1'),
    new AutoNumeric('#tax2')
]);

Обработка отдельных групп

groups.get('prices').forEach(field => {
    field.update({
        currencySymbol: '$ '
    });
});

Массовая валидация

Проверка диапазонов

const invalidFields = fields.filter(field => {
    return field.getNumber() < 0;
});

Подсветка ошибок

invalidFields.forEach(field => {
    field.node().classList.add('error');
});

Массовый экспорт данных

Формирование JSON

const payload = fields.map(field => {
    return {
        value: field.getNumericString()
    };
});

console.log(JSON.stringify(payload));

Групповая деинициализация перед удалением DOM

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

fields.forEach(field => {
    field.remove();
});

container.remove();

Это предотвращает:

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

Организация менеджера групп

В крупных приложениях часто создаётся централизованный менеджер.

class NumericGroupManager {
    constructor(instances = []) {
        this.instances = instances;
    }

    setAll(value) {
        this.instances.forEach(i => i.set(value));
    }

    clearAll() {
        this.instances.forEach(i => i.clear());
    }

    updateAll(options) {
        this.instances.forEach(i => i.update(options));
    }

    getTotal() {
        return this.instances.reduce((sum, i) => {
            return sum + Number(i.getNumericString());
        }, 0);
    }
}

Использование менеджера

const manager = new NumericGroupManager([
    new AutoNumeric('#a'),
    new AutoNumeric('#b'),
    new AutoNumeric('#c')
]);

manager.setAll(100);

console.log(manager.getTotal());

Производительность групповых операций

Наиболее затратными являются:

  • массовые upd ate();
  • постоянные перерасчёты;
  • частые se t() внутри событий;
  • множественные DOM-изменения.

Для оптимизации применяются:

  • debounce;
  • batching;
  • requestAnimationFrame;
  • локальное кеширование значений;
  • минимизация количества reflow/repaint.

Типичные ошибки

Повторная инициализация

AutoNumeric.multiple('.money');
AutoNumeric.multiple('.money');

Это может привести к конфликтам экземпляров.


Смешивание raw и formatted значений

Ошибка:

field.set(field.getFormatted());

Правильнее:

field.set(field.getNumericString());

Потеря ссылок на экземпляры

Ошибка:

AutoNumeric.multiple('.money');

Без сохранения результата дальнейшее управление становится затруднительным.

Правильно:

const moneyFields = AutoNumeric.multiple('.money');