Создания директивы простого диалогового окна в Angular.js

Модальные окна это просто

За период своей работы я работал с десятком плагинов по созданию модальных окон, почти все из которых были построены на основе jQuery. Но совсем недавно я осознал, что такие окна самому создать, зачастую, проще. Давайте так и сделаем в стиле Angular.

Требования

Хотелось бы создавать окна при помощи следующего HTML кода:

<modal-dialog show='modalShown' width='750px' height='90%'>
 <p>Modal Content Goes here<p>
</modal-dialog>

И иметь следующий набор функций:

  • Открывать и закрывать окно при помощи $scope переменной установив её в true или false (переменная в примере - modalShown)
  • Указывать размер окна в пикселях или процентах
  • Затемнять оставшуюся часть экрана
  • Закрывать кликнув на X в углу окна или за пределами окна

Код директивы

Сама директива довольно проста, с функцией в несколько строк в параметре link. Параметр “show: ‘=’” в отдельной области видимости создает двойную связку между переменной заданной в атрибуте show и переменной show в области видимости. Установка этого параметра в false и true открывает или закрывает окно. Также при открытии мы проверяем параметры height и width и, если они заданы, то выставляем нужные значения. Наконец, метод hideModal() просто устанавливает значение переменной show в false.

app.directive('modalDialog', function() {
    return {
        restrict: 'E',
        scope: {
            show: '='
        },
        replace: true, // Замените на шаблон
        transclude: true, // мы хотим вставлять пользовательский контент внутри директивы
        link: function(scope, element, attrs) {
            scope.dialogStyle = {};

            if (attrs.width) {
                scope.dialogStyle.width = attrs.width;
            }

            if (attrs.height) {
                scope.dialogStyle.height = attrs.height;
            }

            scope.hideModal = function() {
                scope.show = false;
            };
        },
        template: '...' // Смотрите ниже
    };
});

Шаблон

Сам шаблон также довольно прост. Обратите внимание на атрибут ng-transclude, он указывает на контейнер для содержимого вашего окна. А атрибут ng-style переводит объект javascript в инлайновый стиль (style) для элемента html.

<div class='ng-modal' ng-show='show'>
    <div class='ng-modal-overlay' ng-click='hideModal()'></div>
        <div class='ng-modal-dialog' ng-style='dialogStyle'>
        <div class='ng-modal-close' ng-click='hideModal()'>X</div>
        <div class='ng-modal-dialog-content' ng-transclude></div>
    </div>
</div>

CSS

Не буду досконально углубляться в CSS. Скажу только одно - работать будет только в современных браузерах. Если вы планируете применять эти стили в браузерах ниже IE9, то потребуется изменить способ центрирования окна.

.ng-modal-overlay {
    /* полупорозрачный DIV, который охватывает весь экран */
    position:absolute;
    z-index:9999;
    top:0;
    left:0;
    width:100%;
    height:100%;
    background-color:#000000;
    opacity: 0.8;
}
.ng-modal-dialog {
    /* Отцентрированный даилог с тенью */
    z-index:10000;
    position: absolute;
    width: 50%;

    /* Центрирование */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    -moz-transform: translate(-50%, -50%);

    background-color: #fff;
    box-shadow: 4px 4px 80px #000;
}
.ng-modal-dialog-content {
    padding:10px;
    text-align: left;
}
.ng-modal-close {
    position: absolute;
    top: 3px;
    right: 5px;
    padding: 5px;
    cursor: pointer;
    font-size: 120%;
    display: inline-block;
    font-weight: bold;
    font-family: 'arial', 'sans-serif';
}

Открытие и закрытие окна

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

<button ng-click='toggleModal()'>Открыть модальный диалог</button>
<modal-dialog show='modalShown' width='750px' height='60%'>
   <p>Содержимое модального окна<p>
</modal-dialog>
app.controller('MyCtrl', function($scope) {
        $scope.modalShown = false;
        $scope.toggleModal = function() {
        $scope.modalShown = !$scope.modalShown;
   };
});

Всё вместе

Вот и всё. Автор выложил рабочую версию на JSBin. Усовершенствованный вариант, разместил на GitHub.

Комментарии

0