Интеграция с jQuery

Библиотека AutoNumeric может использоваться как в чистом JavaScript, так и в проектах, построенных на базе jQuery. Несмотря на то что современные версии AutoNumeric не зависят от jQuery, совместное использование остаётся распространённым сценарием в административных панелях, старых enterprise-приложениях, CRM-системах и формах с большим количеством динамических элементов.

Наиболее типичный вариант подключения:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>AutoNumeric + jQuery</title>

    <script src="jquery.min.js"></script>
    <script src="autoNumeric.min.js"></script>
</head>
<body>

<input type="text" class="price">

<script>
    $(document).ready(function () {
        new AutoNumeric('.price', {
            digitGroupSeparator: ' ',
            decimalCharacter: ',',
            decimalPlaces: 2
        });
    });
</script>

</body>
</html>

В данном примере jQuery используется исключительно как средство поиска DOM-элементов и управления жизненным циклом страницы.


Инициализация через jQuery-селекторы

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

Инициализация одного элемента

$(function () {
    const element = $('.amount')[0];

    new AutoNumeric(element, {
        currencySymbol: '₸ ',
        decimalPlaces: 0
    });
});

jQuery-объект не является DOM-элементом. AutoNumeric ожидает:

  • HTML-элемент;
  • CSS-селектор;
  • NodeList;
  • массив элементов.

Поэтому при использовании jQuery часто применяется:

$('.amount')[0]

или:

$('.amount').get(0)

Инициализация группы элементов

AutoNumeric умеет самостоятельно обрабатывать коллекции элементов.

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

Однако в jQuery-проектах часто используется .each().

Использование each()

$('.money').each(function () {
    new AutoNumeric(this, {
        currencySymbol: '$ ',
        decimalPlaces: 2
    });
});

Преимущества такого подхода:

  • возможность задавать индивидуальные настройки;
  • доступ к индексу элемента;
  • интеграция с существующим jQuery-кодом;
  • совместимость со старыми архитектурами.

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

В jQuery-приложениях элементы часто создаются после загрузки страницы:

$('#container').append(`
    <input type="text" class="dynamic-price">
`);

AutoNumeric не инициализирует такие элементы автоматически.

Ручная инициализация после append()

const input = $('#container .dynamic-price').last()[0];

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

Интеграция с jQuery AJAX

Одно из самых распространённых применений — загрузка HTML-фрагментов через AJAX.

Пример

$.ajax({
    url: '/form',
    success: function (html) {
        $('#content').html(html);

        new AutoNumeric('.ajax-price', {
            decimalPlaces: 2
        });
    }
});

Ключевая особенность заключается в том, что инициализация должна происходить только после вставки HTML в DOM.


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

jQuery активно использует систему событий. AutoNumeric полностью совместим с ней.

Отслеживание изменений

$('.price').on('change', function () {
    console.log($(this).val());
});

Однако важно понимать различие между:

  • форматированным значением;
  • сырой числовой величиной.

Получение чистого числа

const anElement = AutoNumeric.getAutoNumericElement('.price');

$('.price').on('change', function () {
    console.log(anElement.getNumericString());
});

Использование data-атрибутов

В jQuery-проектах часто применяется конфигурация через HTML.

Пример

<input
    class="money"
    data-currency="₽ "
    data-decimals="2">
$('.money').each(function () {
    new AutoNumeric(this, {
        currencySymbol: $(this).data('currency'),
        decimalPlaces: $(this).data('decimals')
    });
});

Такой подход особенно полезен:

  • в CMS;
  • генераторах форм;
  • шаблонизаторах;
  • больших административных интерфейсах.

Хранение экземпляров через jQuery.data()

Иногда требуется доступ к экземпляру AutoNumeric позже.

Сохранение экземпляра

$('.price').each(function () {
    const an = new AutoNumeric(this);

    $(this).data('autoNumeric', an);
});

Получение экземпляра

const an = $('.price').data('autoNumeric');

console.log(an.getNumber());

Этот подход широко применяется в старых jQuery-архитектурах.


Интеграция с jQuery UI

AutoNumeric хорошо работает с компонентами jQuery UI.

Dialog

$('#dialog').dialog({
    open: function () {
        new AutoNumeric('.dialog-price', {
            decimalPlaces: 2
        });
    }
});

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


Использование внутри jQuery plugins

AutoNumeric часто интегрируется в пользовательские jQuery-плагины.

Пример собственного плагина

(function ($) {

    $.fn.currencyField = function (options) {

        return this.each(function () {

            new AutoNumeric(this, {
                currencySymbol: '₸ ',
                decimalPlaces: 2,
                ...options
            });

        });

    };

}(jQuery));

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

$('.salary').currencyField({
    decimalPlaces: 0
});

Такой подход помогает стандартизировать поведение полей во всём приложении.


Интеграция с формами

Автоматическая инициализация всех денежных полей

$('form').find('.money').each(function () {

    new AutoNumeric(this, {
        digitGroupSeparator: ' ',
        decimalCharacter: ','
    });

});

Отправка формы через jQuery

Основная проблема при отправке формы — сервер может получить форматированную строку вместо числа.

Неправильный вариант

1 234 567,89 ₽

Ожидаемый сервером вариант

1234567.89

Очистка значений перед submit

Пример

$('form').on('submit', function () {

    $('.money').each(function () {

        const an = AutoNumeric.getAutoNumericElement(this);

        $(this).val(an.getNumericString());

    });

});

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


Восстановление форматирования после AJAX submit

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

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

$('form').on('ajax:success', function () {

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

});

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

jQuery поддерживает делегирование событий.

Пример

$(document).on('focus', '.money', function () {

    if (!AutoNumeric.isManagedByAutoNumeric(this)) {

        new AutoNumeric(this, {
            decimalPlaces: 2
        });

    }

});

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


Работа с таблицами

Интеграция особенно популярна в финансовых таблицах.

Пример

<table>
    <tr>
        <td><input class="price"></td>
        <td><input class="price"></td>
    </tr>
</table>
$('.price').each(function () {

    new AutoNumeric(this, {
        digitGroupSeparator: ' ',
        decimalPlaces: 2
    });

});

Пересчёт итогов через jQuery

Пример

$('.price').on('keyup', function () {

    let total = 0;

    $('.price').each(function () {

        const an = AutoNumeric.getAutoNumericElement(this);

        total += Number(an.getNumericString());

    });

    $('#total').text(total);

});

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

AutoNumeric часто применяется совместно с DataTables.

Повторная инициализация после redraw

$('#table').on('draw.dt', function () {

    new AutoNumeric('.datatable-money', {
        decimalPlaces: 2
    });

});

Поскольку DataTables пересоздаёт DOM-элементы, форматирование необходимо восстанавливать.


Интеграция с Bootstrap-модальными окнами

В проектах на Bootstrap и jQuery часто используются модальные окна.

Пример

$('#salaryModal').on('shown.bs.modal', function () {

    new AutoNumeric('.modal-money', {
        currencySymbol: '$ '
    });

});

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

При удалении DOM-элементов желательно уничтожать экземпляры AutoNumeric.

Пример

$('.money').each(function () {

    const an = AutoNumeric.getAutoNumericElement(this);

    an.remove();

});

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

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

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

В крупных jQuery-проектах нередко возникает повторная инициализация одного и того же поля.

Проверка

if (!AutoNumeric.isManagedByAutoNumeric(element)) {

    new AutoNumeric(element);

}

Массовая работа с экземплярами

Получение всех экземпляров

const autoNumericObjects = [];

$('.money').each(function () {

    autoNumericObjects.push(
        new AutoNumeric(this)
    );

});

Массовое обновление настроек

autoNumericObjects.forEach(an => {

    an.update({
        currencySymbol: '₽ '
    });

});

Интеграция со старыми jQuery-кодовыми базами

Во многих legacy-проектах применяется стиль:

var self = this;

или:

var that = this;

AutoNumeric не конфликтует с такими архитектурами.

Пример

$('.money').each(function () {

    var $input = $(this);

    var an = new AutoNumeric(this, {
        decimalPlaces: 2
    });

    $input.on('blur', function () {

        console.log(an.getFormatted());

    });

});

Использование debounce вместе с jQuery

При большом количестве вычислений может потребоваться ограничение частоты обработки.

Пример

let timer;

$('.money').on('keyup', function () {

    clearTimeout(timer);

    timer = setTimeout(function () {

        console.log('Обновление');

    }, 300);

});

Типичные ошибки интеграции

Передача jQuery-объекта вместо DOM-элемента

Неправильно:

new AutoNumeric($('.price'));

Правильно:

new AutoNumeric($('.price')[0]);

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

Неправильно:

new AutoNumeric('.price');
new AutoNumeric('.price');

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


Отправка форматированных данных на сервер

Неправильно:

$(this).val();

Правильно:

an.getNumericString();

Совместимость версий

Старые версии AutoNumeric имели более тесную интеграцию с jQuery и даже предоставляли jQuery-подобный API.

Современные версии:

  • не требуют jQuery;
  • работают независимо;
  • поддерживают интеграцию через DOM;
  • совместимы с legacy-кодом.

Архитектурные рекомендации

Централизованная инициализация

function initMoneyFields(context = document) {

    $(context).find('.money').each(function () {

        if (!AutoNumeric.isManagedByAutoNumeric(this)) {

            new AutoNumeric(this, {
                decimalPlaces: 2
            });

        }

    });

}

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

initMoneyFields('#modal');

Подобная архитектура особенно полезна:

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

Инкапсуляция конфигурации

Единый объект настроек

const moneyConfig = {
    digitGroupSeparator: ' ',
    decimalCharacter: ',',
    decimalPlaces: 2
};

Повторное использование

new AutoNumeric('.price', moneyConfig);
new AutoNumeric('.salary', moneyConfig);
new AutoNumeric('.total', moneyConfig);

Это упрощает поддержку крупных jQuery-проектов и снижает вероятность расхождения настроек между различными компонентами интерфейса.