Bootstrap - Динамическое создание модальных окон

Александр Мальцев
19K
28
3
Bootstrap - Динамическое создание модальных окон
Содержание:
  1. Скрипт JavaScript для управления компонентом Modal
  2. Принцип работы с control-modal.js
  3. Примеры использования control-modal.js
  4. Комментарии

В этой статье рассмотрим как можно динамически (т.е. с помощью 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

Комментарии:

  1. Андрей
    17 декабря 2020, 00:20
    Добрый день! Очень помогла Ваша статья. Подключил скрипт control-modal, все отлично работает (при клике на кнопку появляется модальное окно для отображения видео). Мне нужно, чтобы вместо кнопки была картинка. Никак не могу разобраться, как правильно это сделать (Bootstrap 4). Пожалуйста, помогите.
    1. Александр Мальцев
      17 декабря 2020, 12:32
      Привет! Спасибо за отзыв!
      Для этого нужно выполнить аналогичные действия, т.е. просто добавить класс «modal-show» к картинке (открыть пример):
      <img src="/assets/images/picture.jpg" width="200" class="modal-show" data-title="Картинка 3" data-content="<img class='img-fluid center-block' src='/assets/images/picture.jpg'>">
      
    2. Tracktor
      31 мая 2020, 08:17
      Александр, привет!
      Использую модальные окна bootstrap 3 для увеличения изображений по клику. Но очень неудобно, когда на странице несколько изображений, сначала закрывать одно модальное окно, затем открывать следующее… Можно ли в bootstrap 3 сделать переключение модальных окон клавишами стрелок на клавиатуре, или свайпами на мобильном устройстве?
      1. Александр Мальцев
        02 июня 2020, 16:43
        Привет! Можно просто менять изображения при нажатии на кнопку влево или вправо. Пример, как это выполнить можно посмотреть здесь.
        1. Tracktor
          02 июня 2020, 20:10
          Спасибо за наводку! Подправил скрипт под себя, но столкнулся с парой проблем:
          1. У меня каждые две картинки разделяются заголовками, то есть примерно так:
          <h1>1</h1>
                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
                  <a href="#" class="thumbnail">
                    <img src="/examples/images/image03-800x600-min.jpg" alt="...">
                  </a>
                </div>
                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
                  <a href="#" class="thumbnail">
                    <img src="/examples/images/image04-800x600-min.jpg" alt="...">
                  </a>
                </div>
          <h1>2</h1>
                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
                  <a href="#" class="thumbnail">
                    <img src="/examples/images/image03-800x600-min.jpg" alt="...">
                  </a>
                </div>
                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
                  <a href="#" class="thumbnail">
                    <img src="/examples/images/image04-800x600-min.jpg" alt="...">
                  </a>
                </div>
          <h1>3</h1>
          etc...
          
          Из-за чего переключение срабатывает только для двух картинок до следующего заголовка и перед следующим. Примерно понимаю в чём проблема (функция parent()) — но своих мозгов пока не хватает чтобы решить…
          2. Картинки на странице у меня обновляются динамически с помощью вот такого скрипта:
          setInterval(function() {
          	for (var imgs = document.querySelectorAll(".camera, .img-responsive"), j = 0, J = imgs.length; j < J; j++) {
          		var s = imgs[j].src;
          		if (s.indexOf('&') != -1) s = s.split('&')[0];
          		imgs[j].src = s + '&rnd=' + Math.random();
          	}
          }, 5 * 1000);
          
          Соответственно, когда картинка обновляется и к ней приписывается новый гет-параметр (то есть через 5 секунд), переключение тоже перестаёт работать…
          Как всё это можно победить?
          1. Tracktor
            02 июня 2020, 21:25
            P.S. С первым пунктом кустарно, но справился. Если есть способ лучше, напишите пожалуйста)
                $(document).on('keydown', function (e) {
                  if ($('body').hasClass('modal-open')) {
                    if (e.key === 'ArrowRight') {
                      var currentImg = $('body').find('.thumbnail img[src="' + $('#image-modal img').attr('src') + '"]');
                      var nextImgSrc = currentImg.parent().parent().nextAll().find('img').attr('src'); // Здесь используем nextAll() вместо next()
                      $('#image-modal .modal-body img').attr('src', nextImgSrc);
                    } else if (e.key === 'ArrowLeft') {
                      var currentImg = $('body').find('.thumbnail img[src="' + $('#image-modal img').attr('src') + '"]');
                      var nodeName = currentImg.parent().parent().prev()[0]['nodeName']; //Получаем имя тега дива-родителя картинки
                        if (nodeName == 'H1') {
                        	var nextImgSrc = currentImg.parent().parent().prev().prev().find('img').attr('src');
                        } // Если тег h1 то сдвигаемся ещё на элемент назад
            	    else {
                        	var nextImgSrc = currentImg.parent().parent().prev().find('img').attr('src');
                        } // иначе - как было в скрипте изначально
                      $('#image-modal .modal-body img').attr('src', nextImgSrc);          
                    }
                  }
                });
            
            Со вторым пунктом пока не могу придумать…
            1. Александр Мальцев
              03 июня 2020, 13:25
              Конечно, можно написать более универсально.
              Например, так:
              $(document).on('keydown', function (e) {
                if ($('body').hasClass('modal-open')) {
                  var images = $('.container img');
                  var currentSrc = $('#image-modal .modal-body img').attr('src');
                  var index = -1;
                  for (var i = 0, length = images.length; i < length; i++) {
                    if (currentSrc == images.eq(i).attr('src')) {
                      index = i;
                    }
                  }
                  if (e.key === 'ArrowRight') {
                    if (index < images.length) {
                      $('#image-modal .modal-body img').attr('src', images.eq(index + 1).attr('src'));
                    }
                  } else if (e.key === 'ArrowLeft') {
                    if (index > 0) {
                      $('#image-modal .modal-body img').attr('src', images.eq(index - 1).attr('src'));
                    }
                  }
                }
              });
              
              Демо доступно на этой странице.
              1. Tracktor
                03 июня 2020, 20:42
                Спасибо большое! Над вторым пунктом буду думать, как это сделать на jQuery без добавления рандомного гет-параметра…
                1. Александр Мальцев
                  08 июня 2020, 15:25
                  Пожалуйста! В этом случае можно к изображениям добавить атрибут data-image-index и организовать переход по ним уже используя его. Данный атрибут можно добавить динамически с помощью JavaScript.
                  <img src="..." alt="..." data-image-index="0">
                  <img src="..." alt="..." data-image-index="1">
                  
      2. Максим
        04 мая 2020, 19:55
        Александр, доброго времени суток! Помогите с вопросом разобраться
        Разрабатываю учебный сайт на mvc5 и решил использовать модальные окна для предоставления детальной информации о блоке. Но при клике на любую карточку модальное окно показывает информацию только о первой карточке, хотя в инспекторе под каждую карточку создалось модальное окно с информацией. Подскажите, пожалуйста

        @model Checkitlink.Models.ViewModels.ProfileVM
        
        @foreach (var item in Model.LinkListUserProfile)
        {
        //Карточка
            <div class="col-xs-12 col-sm-4 col-md-4 link-item linkCard">
                <div class="thumbnail">
                    <img class="imgCardLink" data-toggle="modal" data-target="#showLink" title="Подробнее..." src="http://checkitlink.com/img/screen/3596.jpeg">
                    <div class="caption">
                        <h5 data-toggle="modal" data-target="#showLink">
                            @if (@item.LinkName.Length > 55)
                            {
                                <span title="@item.LinkName">
                                    @item.LinkName.Substring(0, 55).Insert(55, "...")
                                </span>
                            }
                            else
                            {
                                <span title="@item.LinkName">
                                    @item.LinkName
                                </span>
                            }
                        </h5>
                        <div class="btn-toolbar">
                            <div class="btn-group link-actions" role="group">
                                <button type="button" class="btn btn-default btn-link-favourite">  <span class="fa fa-star" aria-hidden="true"></span></button>
                                <button type="button" class="btn btn-default btn-link-private"><span class="fa fa-eye" aria-hidden="true"></span></button>
                                <button type="button" class="btn btn-default btn-link-share"><span class="fa fa-share" aria-hidden="true"></span></button>
                                <button type="button" class="btn btn-default btn-link-edit"><i class="fa fa-pencil"></i></button>
                                <button type="button" class="btn btn-default btn-link-remove"><span class="fa fa-times" aria-hidden="true"></span></button>
                            </div>
                            <div class="btn-group social-buttons" role="group">
                                <button type="button" class="btn btn-default"><span class="fa fa-heart" aria-hidden="true"><span class="badge">42</span></span></button>
                                <button type="button" class="btn btn-default"><span class="fa fa-comment" aria-hidden="true"></span></button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        
        //Модальное окно
            <div class="modal" id="showLink" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                <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">×</span></button>
                            <h4 class="modal-title" id="myModalLabel">
                                <a href="@item.LinkAddress" style="text-decoration:none" target="_blank">
                                    @item.LinkName
                                </a>
                            </h4>
                        </div>
                        <div class="modal-body linkBodyModal col-lg-12 col-md-12 col-sm-12">
                            <div class="col-lg-7 col-md-7 col-sm-7">
                                <img class="linkImg" src="http://checkitlink.com/img/screen/3596.jpeg">
                            </div>
                            <div class="col-lg-5 col-md-5 col-sm-5">
                                <p>Автор: @item.UserAuthor</p>
                                <p>Категория: @item.LinkCategory</p>
                                <p>Дата: @item.CreatedAt</p>
                            </div>
                        </div>
                        <div class="modal-body linkBodyModal col-lg-12 col-md-12 col-sm-12">
                            @if (item.LinkDescription == null)
                            {
                                <p></p>
                            }
                            else
                            {
                                <p>
                                    @item.LinkDescription
                                </p>
                            }
                        </div>
                        <div class="modal-footer">
                            <a href="@item.LinkAddress" target="_blank" type="button" class="btn btn-success">Перейти по ссылке</a>
                            <button type="button" class="btn btn-danger" data-dismiss="modal">Закрыть</button>
                        </div>
                    </div>
                </div>
            </div>
        }
        
        1. Александр Мальцев
          05 мая 2020, 15:22
          Когда вы создаёте модальные окна все они имеют один и тот же id (в примере id="showLink"). Элементы, через которые вы их открываете тоже указывают на одну и ту же цель (data-target="#showLink"). Как в этом случае разные элементы должны открывать разные модальные окна? Чтобы это сделать, вам, например 1-ому элементу следует задать data-target="#showLink-1", а первому модальному окну id="showLink-1", 2-ому элементу data-target="#showLink-2", а второму модальному окну id="showLink-2" и т.д.
        2. Роман
          13 апреля 2020, 01:46
          Доброго времени суток.
          Помогите решить задачу.
          Есть карта с метками созданная по API яндекс карты.
          Нужно к каждой метки задать по клику модальное окно с разным содержанием.
          Как реализовать это в JS, что бы не плодить это в HTML.
          Заранее спасибо!
          1. Александр Мальцев
            15 апреля 2020, 15:11
            Здравствуйте! Можно, например, создать объект с данными для вывода их в модальном окне:
            var data = [
               {id: 0, title: 'Заголовок...', body: 'Содержимое...'},
               {id: 1, title: 'Заголовок...', body: 'Содержимое...'},
            ];
            
            Далее получаем id метки, по которой был сделан клик (песочница), находим соответствующие данные и выводим их в модальном окне:
            objectManager.objects.events.add(['click'], function(e){
              var objectId = e.get('objectId');
              for (var i = 0, length = data.length; i < length; i++) {
                if (data[i].id === objectId) {
                  result = data[i];
                  myModal.changeTitle(data[i].title);      
                  myModal.changeBody(data[i].body);
                  myModal.showModal();
                  break;
                }
              }
            });
            
          2. Алексей
            27 июля 2019, 11:56
            Александр, здравствуйте.
            Подскажите, как очищать модальное окно, то есть на примере, у меня есть календарь с событиями, при нажатие на событие на календаре я в модальном окне вывожу информацию о сегодняшнем дне, после закрытия я выбираю другой день и другое событие, как мне очищать значению модального окна, либо удалять его из дом дерева и при нажатии на новое событие выводить с новыми параметрами.

            При клике происходит событие и на него вешаем создания и вывод модального окна, как очистить для следующего вывода после нажатия? или удалить созданное окно из дом дерева
            var myModal2 = new ModalApp.ModalProcess({
                    id: 'myModal2',
                    title: e.schedule.title,
                    body: '<p></p>'
                });
                myModal2.init();
                myModal2.showModal();
            


            Заранее, спасибо!
            1. Александр Мальцев
              27 июля 2019, 15:36
              Здравствуйте.
              Лучше же, конечно, очистить некоторую часть модального окна, чем создавать его заново. Т.к. это менее затратная операция как по быстродействию, так и по времени.
              Если необходимо очистить body модального окна, то так:
              myModal2.changeBody('');
              
              Если какую-то часть модального окна, то так:
              $('#' + myModal2.id).find('.message').text('Новое сообщение...');
              
              В этом примере мы сначала выбираем модальное окно, затем находим в нём элемент с классом message, а затем изменяем ему содержимое на «Новое сообщение...».
              1. Алексей
                01 августа 2019, 17:47
                Александр, добрый вечер.
                Такая вот проблема, есть модальное окно, в котором происходит отправка данных через аякс методом post. К примеру, если мы один раз открыли модальное окно, то при нажатии данных на сохранение = запрос аякс уходит один раз, а если мы несколько раз открываем модальное окно, к примеру 4 раза, то при нажатии на кнопку сохранить данные у нас происходит 4 запроса аякс.
                Здесь мы видим при закрытии окна, количество (картинка 1).
                $('#modal_open').on('hidden.bs.modal', function () {
                  console.log('hidden.bs.modal');
                })
                
                Здесь отправка данных аяксом (картинка 2)
                Помогите, что может быть?
                1. Александр Мальцев
                  11 августа 2019, 04:49
                  Вам не нужно каждый раз создавать окно, сделайте это один раз, а дальше просто изменяйте его содержимое.
                  1. Алексей
                    01 августа 2019, 17:51
                    Код отправил на почту
                    1. Александр Мальцев
                      05 августа 2019, 13:12
                      Я так не смогу тебе помочь. Если нужна помощь, то мне нужно хотя бы то, что я мог бы запустить.
                      1. Алексей
                        05 августа 2019, 13:45
                        Хорошо, сейчас подготовлю архив и скину на почту, спасибо
              2. Denis
                29 мая 2018, 17:45
                Добрый день, Александр.
                Подскажите пожалуйста, как на bootstape создать чтобы модальное окно, с ссылкой на другой документ на сервере, например test.html (этот код и будет отображаться в мод окне).
                Если можно, то поподробнее, так как новичок в этом.
                Заранее благодарен.
                1. Александр Мальцев
                  30 мая 2018, 17:13
                  Добрый день!
                  Например, можно завести атрибут data-href. В этом атрибуте задавать URL ресурса, контент которого необходимо поместить в модальное окно.
                  Пример:
                  <button class="btn btn-primary modal-show" data-href="test.html">Показать контент</button>
                  ...
                  <script>
                  $(function () {
                    var myModal = new ModalApp.ModalProcess({ id: 'myModal', title: 'Информация о контенте' });
                    myModal.init();
                    $('.modal-show').click(function () {
                      var content = getContent($(this).attr('data-href'));
                      content.done(function (html) {
                        myModal.changeBody(html);
                        myModal.showModal();
                      })
                    });
                    var getContent = function (href) {
                      return $.ajax({
                        url: href,
                        cache: false
                      })
                    };
                  });
                  </script>
                  
                2. Constantin
                  10 мая 2017, 09:05
                  Александр, спасибо за статью! Еще бы пример, как создавать окна с полями ввода и их обрабатывать :)
                  1. Александр Мальцев
                    11 мая 2017, 12:24
                    Отлично, что разобрался!

                    Приведу пример, как можно сделать загрузку нужной формы из внешнего файла и отображения её в модальном окне.
                    Например, на странице имеются 3 кнопки (для того чтобы указать какую форму необходимо грузить в модальную форму будем использовать атрибут data-form):
                    <button class="btn btn-default modal-form" data-form="form1">Открыть модальное окно (с формой 1)</button>
                    <button class="btn btn-default modal-form" data-form="form2">Открыть модальное окно (с формой 2)</button> 
                    <button class="btn btn-default modal-form" data-form="form3">Открыть модальное окно (с формой 3)</button>     
                    
                    Теперь только останется добавить на страницу следующий сценарий:
                    <script>
                    $(function() {
                      var myModal = new ModalApp.ModalProcess({ id: 'myModal'});
                      myModal.init();
                      $('.modal-form').click(function(){
                        $.get('forms.php', {content:$(this).attr('data-form')},function(data){
                          if (data) {
                            myModal.changeBody(data);
                            myModal.showModal();      
                          }
                        });
                      });
                    });
                    </script>
                    
                    С помощью такого небольшого кода мы получили необходимый функционал. Теперь напишем php скрипт (например, forms.php), который будет отдавать необходую HTML форму по запросу:
                    <?php
                    if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {return;}
                    // завершим работу php скрипта, если в суперглобальном массиве $_GET не существует ключа content, 
                    if (!isset($_GET['content'])) {
                      exit();
                    }
                    // получаем значение GET параметра и фильтруем его от не желательного содержимого с помощью очищающего фильтра FILTER_SANITIZE_STRING
                    $content = filter_var($_GET['content'], FILTER_SANITIZE_STRING);
                    // массив, элементы которого содержат различный контент
                    $contents = array();
                    $contents['form1'] = '<form id="form1">...</form>';
                    $contents['form2'] = '<form id="form2">...</form>';
                    $contents['form3'] = '<form id="form3">...</form>';
                    
                    // если значение GET параметра (ключ) присутствует в массиве, то вывести соответствующее ему значение
                    if (array_key_exists($content, $contents)) {
                      echo $contents[$content];
                    }
                    
                    1. Виталий
                      27 февраля 2018, 11:30
                      Александр, добрый день!
                      Подскажите, как в этом примере с формами передать title.
                      Спасибо.
                      1. Александр Мальцев
                        27 февраля 2018, 16:48
                        Например, можно добавить к каждой кнопке атрибут data-title с необходимым значением.
                        <button class="btn btn-default modal-form" data-form="form1" data-title="title1">Открыть модальное окно (с формой 1)</button>
                        ...
                        
                        А в обработчике кнопке:
                        var self = this;  	
                        $.get('forms.php', {content:$(this).attr('data-form')},function(data){
                            if (data) {
                              	myModal.changeTitle($(self).attr('data-title'));
                                myModal.changeBody(data);
                                myModal.showModal();      
                            }
                        });
                        
                      2. Василий
                        16 декабря 2017, 22:09
                        Александр, доброго времени суток!
                        Хотел с помощью демо разобраться до конца, как реализовать динамический вывод в одно модальное окно или может несколько разных, для показа в окне формы и отдельно изображения, но к сожалению, демо у вас выдает ошибку…
                      3. Constantin
                        11 мая 2017, 08:11
                        всё, разобрался :)
                      Войдите, пожалуйста, в аккаунт, чтобы оставить комментарий.