Stack modulesBoostrap oferuje łatwy skrypt do wywołania okien modalnych w stronach internetowych.

Czasem jednak istnieje potrzebna wywołania kolejnego okna, gdy już jedno z nich zostało otwarte.

Pamiętam jak kiedyś uruchamiałem okna modalne przy użyciu kontrolek Telerick. W scenariuszu, w którym było potrzebne kolejne okno modalne, wtedy „łamałem sobie głowę”. Wywołanie okna modalnego, mając otwarte inne okno modalne, powodowało utworzenie okna modalnego w oknie modalnym. Całe szczęście, że nie programuję już z wykorzystaniem tych starych rozwiązań.

Mając jednak nawet boostrapa i rozwiązanie godne naszych czasów wciąż zadaję sobie pytanie, jak to można zrobić.

Potrzeba wywołania okna modalnego w trakcie,  gdy inne jest już otwarte, zazwyczaj symbolizuje problem po stronie wymyślania działania interfejsu użytkownika.

Gdy jednak istnieje taka potrzeba wystarczy napisać małą obsługę stosu warstw okienek modal.

Gdy w boostrapie wywołamy kolejne okno modalne, musimy jakoś powiedzieć stronie, że wszystkie  wcześniej otwarte okna modalne muszą zostać zakryte w warstwie poniżej.

Na szczęście nie musimy niczego zmieniać w samym boostrapie. Sam boostrap domyślnie nie ma takiej funkcjonalności. http://getbootstrap.com/javascript/#modals

Brak w wielu modali w boostrap

Znalazłem dwa rozwiązania tego problemu. Jedno z nich znajduje się na tej stronie

http://jschr.github.io/bootstrap-modal/

Postanowiłem je zignorować ponieważ wymuszają na użytkowniku używania styli nadpisujących style boostrap.

Lepsze rozwiązanie znalazłem na tej stronie http://miles-by-motorcycle.com/fv-b-8-670/stacking-bootstrap-dialogs-using-event-callbacks

Polega ono na dodaniu tego skryptu. Co ten skrypt robi?

Za każdym razem, gdy nowe okno się otworzy:

  • Dodaje atrybut “fv_open_modals” do tagu body, które przechowują informację ile obecnie modali zostało otwartych.
  • Zwiększa właściwość z-index  w oknie, które ma być otwarte w zależności od tego ile okien zostało wcześniej otwartych.
$(document).ready(function () {
    $('.modal').on('hidden.bs.modal', function (event) {
        $(this).removeClass('fv-modal-stack');
        $('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
    });

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

        // keep track of the number of open modals
        if (typeof ($('body').data('fv_open_modals')) == 'undefined') {
            $('body').data('fv_open_modals', 0);
        }

        // if the z-index of this modal has been set, ignore.
        if ($(this).hasClass('fv-modal-stack')) {
            return;
        }

        $(this).addClass('fv-modal-stack');

        $('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);

        $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals')));

        $('.modal-backdrop').not('fv-modal-stack')
                .addClass('fv-modal-stack');
    });
});

Oto jak działa te rozwiązanie w praktyce.

Untitled

Pamiętajcie, że rozwiązanie pochodzi z tej strony http://miles-by-motorcycle.com/fv-b-8-670/stacking-bootstrap-dialogs-using-event-callbacks. Ja tego rozwiązania nie wymyśliłem, ale moim zdaniem jest ono najbardziej elastyczne gdyż nie zmieniamy niczego w stylach i skryptach bootstrap.

Pobierz Kod