Stack modulesBootstrap 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 Telerik. 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 bootstrapa 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 Bootstrap domyślnie nie ma takiej funkcjonalności. http://getbootstrap.com/javascript/#modals
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 Bootstrap.
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 to rozwiązanie w praktyce.
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.