Реализация модального окна подтверждения с помощью jQuery.Deferred
jQuery

Реализация модального окна подтверждения с помощью jQuery.Deferred

jQuery.Deferred — это мощный инструмент, появившийся в jQuery 1.5. Как правило, его используют для работы с асинхронным кодом, но есть и другие интересные применения. В данной статье мы рассмотрим использование deferred объекта для создания модального окна подтверждения.

Такие окна всем знакомы, они как правило используются в интерфейсах при удалении элемента. Если пользователь нажимает OK — элемент удаляется, если нажимает Отмена — элемент не удаляется.

Модальное окно

Для реализации модального окна воспользуемся примером из статьи Модальное окно на чистом CSS. Только в этом случае будем активировать модальное окно не по псевдо-классу «:target», а по классу «active».

HTML-разметка довольно простая:


<a href="" id="delete_link">Удалить элемент</a>

<aside class="modal" id="delete_confirm">
    <header>
        <h2>Удаление элемента</h2>
    </header>
    <section>Вы уверены, что хотите удалить этот элемент?</section>
    <footer class="footer">
        <a href="" class="confirm_cancel btn">Нет</a> 
        <a href="" class="confirm_ok btn">Да</a>
    </footer>
</aside>

При нажатии на ссылку «Удалить элемент» должно показываться окно подтверждения удаления.

Удаление элемента

Добавим обработчик ссылки Удалить элемент.


(function(globals, $) {
    $(function() {
        $('#delete_link').on('click', function(event) {
            event.preventDefault();
            // …
        });
    });
})(window, jQuery);

Вместо многоточия в обработчике должен быть запрос подтверждения и в случае, если пользователь подтвердил удаление, удаление элемента.

Окно подтверждения

Давайте теперь рассмотрим код самого окна подтверждения.


(function (name, definition){
    if (typeof define === 'function') {
        define(definition);
    } else if (typeof module !== 'undefined' && module.exports) {
        module.exports = definition();
    } else {
        var theModule = definition(), global = this, old = global[name];
        theModule.noConflict = function () {
            global[name] = old;
            return theModule;
        };
        global[name] = theModule;
    }
})('ConfirmationWindow', function() {
    var ConfirmationWindow = (function() {        
	var deferred, $modal;
    
        var show = function() {
            $modal.addClass('active');

            $modal.on('click', '.confirm_cancel', decline);
            $modal.on('click', '.confirm_ok', confirm);
        };

        var close = function() {
            $modal.removeClass('active');

            $modal.off('click', '.confirm_cancel', decline);
            $modal.off('click', '.confirm_ok', confirm);
        };

        var decline = function(event) {
            event.preventDefault();
            deferred.reject();
            close();
        };

        var confirm = function(event) {
            event.preventDefault();
            deferred.resolve();
            close();
        };        

        return {
            /**
             * Запрос подтверждения
             */
            requestConfirmation: function(modal) {
                // запоминаем ссылку на модальное окно
                $modal = modal;
                // создаем deferred объект
		deferred = new $.Deferred();
                // отображаем модальное окно
                show();
                // возвращаем deferred объект
                return deferred.promise();
            }
        };
    })();

    return ConfirmationWindow;
});

В начале мы создаем модуль с возможностью подключения его через Require.js, через Browserify или просто подключением js-файла на странице.

Далее создаем объект ConfirmationWindow с помощью немедленно вызываемой функции. Этот объект будет иметь только один метод: requestConfirmation.

Методе requestConfirmation принимает jQuery-объект модального окна, запоминает ссылку на этот объект, создает новый deferred объект, отображает модальное окно и возвращает проекцию deferred-объекта — deferred.promise().

Функции show и close очень простые. В функции show к модальному окну добавляется класс active, который отображает окно, и навешиваются обработчики клика по ссылкам «Да» и «Нет». В функции close удаляется класс active и удаляются обработчики кликов по ссылкам «Да» и «Нет».

И наконец, две функции-обработчики. Первая, функция confirm срабатывает по клику на ссылку «Да». В ней вызывается метод deferred объекта resolve() и закрывается модальное окно. Вторая, функция decline, вызывается по клику на ссылку «Нет», в ней вызывается метод deferred объекта reject и закрывается модальное окно.

Использование окна подтверждения

Использовать такое окно подтверждения очень просто. Зная, что метод requestConfirmation возвращает промис, мы можем использовать его вместе с функцией $.when:


$('#delete_link').on('click', function(event) {
    event.preventDefault();

    $.when(ConfirmationWindow.requestConfirmation($('#delete_confirm')))
    .then(function() {
        console.log('resolved');
    }, function() {
        console.log('rejected');
    });
});

Также можно использовать методы done и fail deferred объекта:


$('#delete_link').on('click', function(event) {
    event.preventDefault();

    ConfirmationWindow.requestConfirmation($('#delete_confirm'))
    .done(function() {
        console.log('resolved');
    })
   .fail(function() {
        console.log('rejected');
    });
});

Оба способа работают одинаково — здесь уж какой вариант вам больше по душе.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться