В этой статье рассмотрим как можно динамически (т.е. с помощью JavaScript) создать и управлять модальным окном Bootstrap 3 и 4.

Материалы, содержащие базовые моменты по компоненту Bootstrap Modal, доступны по этому адресу.

Модальное окно (HTML-код) не всегда удобно непосредственно размещать на страницах сайта. Т.к. это не только увеличивает размер страницы, но и предусматривает (в большинстве случаев) написания сценария JavaScript по управлению этим окном.

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

Скрипт JavaScript для управления компонентом Modal

Нижеприведённый сценарий JavaScript не представляет собой ничего сложного – это обычная функция-конструктор. Её назначение создание и управление модальными окнами Bootstrap.

var ModalApp = {};
ModalApp.ModalProcess = function (parameters) {  
  this.id = parameters['id'] || 'modal';
  this.selector = parameters['selector'] || '';
  this.title = parameters['title'] || 'Заголовок модального окна';
  this.body = parameters['body'] || 'Содержимое модального окна';
  this.footer = parameters['footer'] || '<button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>';   
  this.content = '<div id="'+this.id+'" class="modal fade" tabindex="-1" role="dialog">'+
    '<div class="modal-dialog" role="document">'+
      '<div class="modal-content">'+
        '<div class="modal-header">'+
          '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>'+
          '<h4 class="modal-title">'+this.title+'</h4>'+
        '</div>'+
        '<div class="modal-body">'+this.body+'</div>'+
        '<div class="modal-footer">'+this.footer+'</div>'+
      '</div>'+
    '</div>'+
  '</div>';
  this.init = function() {
    if ($('#'+this.id).length==0) {
      $('body').prepend(this.content);
    }
    if (this.selector) {
      $(document).on('click',this.selector, $.proxy(this.showModal,this));
    }
  }
}
ModalApp.ModalProcess.prototype.changeTitle = function(content) {
  $('#' + this.id + ' .modal-title').html(content);
};
ModalApp.ModalProcess.prototype.changeBody = function(content) {
  $('#' + this.id + ' .modal-body').html(content);
};
ModalApp.ModalProcess.prototype.changeFooter = function(content) {
  $('#' + this.id + ' .modal-footer').html(content);
};
ModalApp.ModalProcess.prototype.showModal = function() {
  $('#' + this.id).modal('show');
};
ModalApp.ModalProcess.prototype.hideModal = function() {
  $('#' + this.id).modal('hide');
};  
ModalApp.ModalProcess.prototype.updateModal = function() {
  $('#' + this.id).modal('handleUpdate');
};

Чтобы не "засорять" глобальное пространство, создание объектов производится в рамках объекта ModalApp.

Для более удобного подключения данного функционала можете воспользоваться следующими файлами:

Принцип работы с control-modal.js

1. Вставить или подключить этот скрипт к странице. Это необходимо сделать после подключения библиотеки jQuery и js-плагина Bootstrap.

<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<!-- Подключения скрипта control-modal.min.js к странице -->
<script src="js/control-modal.min.js"></script>

2. Создать объект "Модальное окно" (ModalProcess).

var myModal = new ModalApp.ModalProcess({ id: 'myModal' });

При создании объекта вы можете передать ему не только параметр id, но и другие параметры:

  • title – заголовок модального окна;
  • body – содержимое модального окна;
  • footer – футер модального окна;
  • selector – добавить элементы (селектор), с помощью которых это модальное окно будет открываться.

Пример, как можно создать объект ModalProcess с id, заголовком, телом и селектором:

var myModal = new ModalApp.ModalProcess({
  id: 'myModal',
  title: 'Мой заголовок',
  body: '<div class="embed-responsive embed-responsive-16by9"><iframe class="embed-responsive-item" src="https://www.youtube.com/embed/bju_FdCo42w?list=PLtK75qxsQaMLZSo7KL-PmiRarU7hrpnwK" allowfullscreen></iframe></div>'
  selector: '.modal-show'
});

Если не указывать параметры, то он создаст модальное окно с параметрами по умолчанию (в качестве id, будет равно modal).

3. После создания объекта, его необходимо "инициализировать". Это действие, в данном случае, просто добавляет модальное окно на страницу (после открывающего тега body).

myModal.init();

Функции для работы с модальным окном

Для работы с модальным окном Bootstrap данный скрипт предоставляет следующие методы:

  • changeTitle – изменить заголовок;
  • changeBody – изменить содержимое тела;
  • changeFooter – изменить футер;
  • showModal – вызвать (отобразить) модальное окно;
  • hideModal – скрыть модальное окно;
  • updateModal – откорректировать положение компонента Modal.

Примеры использования control-modal.js

Рассмотрим различные примеры, в которых разберём как с помощью control-modal.js можно очень просто создавать и управлять модальными окнами Bootstrap.

Использование модальных окон Bootstrap для отображения AJAX контента

1. Создадим 2 простых php-файла ajax.php и other-ajax.php. Эти файлы будут просто возвращать некоторый контент.

Содержимое файла ajax.php:

<?php
// Если  запрос не AJAX (XMLHttpRequest), то завершить работу
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
  exit();
}
$output['title']='Новый заголовок';
$output['body']='Новое содержимое...';
echo json_encode($output);

Содержимое файла other-ajax.php:

<?php
// Если  запрос не AJAX (XMLHttpRequest), то завершить работу
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
  exit();
}
$output = 'То же какое-то содержимое...';
echo $output;

2. HTML документ, содержащий 2 кнопки и JavaScript код:

<a href="#" class="modal-show">Открыть модальное окно</a>
<br>
<a href="#" class="modal-show-other">Открыть модальное окно</a>

...

<script>
$(function() {
  var myModal = new ModalApp.ModalProcess({ id: 'myModal', title: 'Мой заголовок' });
  myModal.init();
      
  $('.modal-show').click(function(e){
    e.preventDefault();
    $.get('ajax.php', function(data) {
      var data = JSON.parse(data);
      myModal.changeTitle(data['title']);
      myModal.changeBody(data['body']);
      myModal.showModal();
    });
  });        
  
  $('.modal-show-other').click(function(e){
    e.preventDefault();
    $.get('other-ajax.php', function(data) {
      myModal.changeBody(data);
      myModal.showModal();          
    });        
  });
</script>		 

При этом одно и то же модальное окно используется для отображения разного AJAX контента.

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

Пример на Bootstrap 4, в котором модальное окно используется для отображения data-атрибута ссылки.

<button class="btn btn-primary modal-show" data-content="Контент...">Показать контент</button>
<button class="btn btn-danger modal-show" data-content="Ещё контент...">Показать какой ещё есть контент</button>
<button class="btn btn-warning modal-show" data-content="Другой контент...">Показать другой контент</button>
...
<script>
$(function() {
  var myModal = new ModalApp.ModalProcess({ id: 'myModal', title: 'Информация о контенте' });
  myModal.init();
  $('.modal-show').click(function() {
    myModal.changeBody($(this).attr('data-content'));
    myModal.showModal();
  });
});
</script>

Демо этого же примера, но на Bootstrap 3:

Демо на Bootstrap 3

Как из одного окна открыть другое модальное окно

Пример на Bootstrap 4, в котором рассмотрим, как можно очень просто (с помощью control-modal.js) организовать открытие одного модального окна из другого:

<!-- Кнопка, открывающая модальное окно 1 -->
<button class="btn btn-info modal-show-1" data-content="Содержимое...">
    Открыть модальное окно 1
</button>

...
<script>
$(function () {

    /* Программно создаём модальные окна */
    var showModal1 = false,
        showModal2 = false,
        showModal3 = false;
    // создаём объект "Модальное окно 1"
    var myModal1 = new ModalApp.ModalProcess({
        id: 'myModal1',
        title: 'Заголовок модального окна 1',
        body: '<p>Некоторый текстовый контент 1 модального окна...</p>' +
          '<button class="btn btn-info modal-show-2">Открыть модальное окно 2</button>'
    });
    myModal1.init();
    // создаём ещё один объект "Модальное окно 2"
    var myModal2 = new ModalApp.ModalProcess({
        id: 'myModal2',
        title: 'Заголовок модального окна 2',
        body: '<p>Некоторый текстовый контент 2 модального окна...</p>' +
        '<button class="btn btn-info modal-show-3">Открыть модальное окно 3</button>'
    });
    myModal2.init();
    // создаём ещё один объект "Модальное окно 3"
    var myModal3 = new ModalApp.ModalProcess({
        id: 'myModal3',
        title: 'Заголовок модального окна 3',
        body: '<p>Некоторый текстовый контент 3 модального окна...</p>'
    });
    myModal3.init();


    /* Определяем поведение окон */
    // при нажатии на кнопку с классом modal-show-1 открываем myModal1
    $('.modal-show-1').click(function () {
        myModal1.showModal();
    });
    // при нажатии на кнопку с классом modal-show-2 открываем myModal2
    $('.modal-show-2').click(function () {
        showModal2 = true;
        myModal1.hideModal();
    });
    // при нажатии на кнопку с классом modal-show-2 открываем myModal2
    $('.modal-show-3').click(function () {
        showModal3 = true;
        myModal2.hideModal();
    });
    $('#myModal1').on('hidden.bs.modal', function (e) {
        if (showModal2) {
            showModal2 = false;
            window.setTimeout(function () {
                myModal2.showModal();
            }, 400);
        }
    });
    $('#myModal2').on('hidden.bs.modal', function (e) {
        if (showModal3) {
            showModal3 = false;
            window.setTimeout(function () {
                myModal3.showModal();
            }, 400);
        } else {
            window.setTimeout(function () {
                myModal1.showModal();
            }, 400)
        }
    });
    $('#myModal3').on('hidden.bs.modal', function (e) {
        window.setTimeout(function () {
            myModal2.showModal();
        }, 400)
    });
});
</script>

Этот же пример, но с 2 модальными окнами и на Bootstrap 3:

Демо на Bootstrap 3

Как использовать одно модальное окно для отображения видео и изображений

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

<h2>Видео</h2>
<button class="btn btn-default modal-show" data-title="Linux Sysadmin Basics - Course Introduction"
        data-content="<div class='embed-responsive embed-responsive-16by9'><iframe class='embed-responsive-item' src='https://www.youtube.com/embed/bju_FdCo42w?list=PLtK75qxsQaMLZSo7KL-PmiRarU7hrpnwK' allowfullscreen></iframe></div>">
    Course Introduction
</button>
<button class="btn btn-default modal-show" data-title="Basic Linux Access Control"
        data-content="<div class='embed-responsive embed-responsive-16by9'><iframe class='embed-responsive-item' src='https://www.youtube.com/embed/WhCIuGjhH-0?list=PLtK75qxsQaMLZSo7KL-PmiRarU7hrpnwK' allowfullscreen></iframe></div>">
    Basic Linux Access Control
</button>

<h2> Изображения </h2>
<button class="btn btn-default modal-show" data-title="Изображение черепахи"
        data-content="<img class='img-fluid center-block' src='/examples/images/carousel_1.jpg'>">
    Изображение
</button>
<button class="btn btn-default modal-show" data-title="Изображение черепахи"
        data-content="<img class='img-fluid center-block' src='/examples/images/carousel_2.jpg'>">
    Ещё одно изображение
</button>
...

<script>
$(function() {
  // создаём объект "Модальное окно"
  var myModal = new ModalApp.ModalProcess({ id: 'myModal' });
  myModal.init();
  // при нажатии на элемент с классом modal-show изменяем его заголовок и тело, а затем отображаем его 
  $('.modal-show').click(function(){
    myModal.changeTitle($(this).attr('data-title'));      
    myModal.changeBody($(this).attr('data-content'));
    myModal.showModal();
  });
  // при скрытии модального окна очищаем его содержимое
  $('#'+myModal.id).on('hidden.bs.modal', function (e) {
    myModal.changeBody('');
  });
});
</script>

Скриншоты примера:

Отображение в модальном окне Bootstrap видео с Youtube
Отображение в модальном окне Bootstrap видео с Youtube
Отображение в модальном окне Bootstrap изображения
Отображение в модальном окне Bootstrap изображения

На Bootstrap 3 этот пример (с использованием control-modal.js) доступен посредством следующей ссылки:

Пример на Bootstrap 3