23. diel - Bootstrap - Modálne dialógy
V minulej lekcii, Bootstrap - Paginácia, Upozornenie a Drobčeková navigácia, sme pokračovali v prehliadke Bootstrap komponentov Pagination, Alerts a Breadcrumb.
V nasledujúcom tutoriále CSS frameworku Bootstrap sa budeme venovať modálnym dialógom.
Hoci pop-upy, prekryvný obsah, sa na web úplne nehodia, občas sa mu
nevyhneme. Ide napríklad o situáciu, kedy sa chceme používateľa opýtať,
či si skutočne praje zavrieť záložku, pretože má rozrobenú prácu. Na
tento účel by sme síce mohli použiť natívne JavaScriptové dialógy
(confirm()
, prompt()
, alert()
), ale tie
väčšinou nevyzerajú práve najlepšie a nemožno ich prispôsobovať.
Pop-upy sa často používajú aj napríklad na otvorenie zväčšeniny obrázka
alebo videa, aby sa zabránilo zbytočnému presmerovaniu na inú stránku.
Známe sú tiež pod označením lightbox.
Modálne dialógy v Bootstrape
Modálne dialógy tvoríme pomocou JavaScriptu. Budeme k nim teda opäť potrebovať načítať Bootstrap JavaScript plugin.
Ako prvú ukážku do stránky vložíme tlačidlo, ktoré po stlačení vyvolá modálny dialóg:
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#dialog"> Open modal </button> <div class="modal fade" id="dialog" tabindex="-1" aria-labelledby="dialog-label" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="dialog-label">Title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"> </button> </div> <div class="modal-body"> <p>Text</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div>
Dialógy budeme na rozdiel od prevažnej väčšiny komponentov spúšťať v
praxi skôr JavaScriptom. V ukážke vyššie je dialóg otvorený pomocou
elementu <button>
a data atribútom
data-bs-toggle="modal"
. Pomocou atribútu
data-bs-target
uvedieme selektor na dialóg, ktorý má tlačidlo
otvoriť. Výsledok v prehliadači:
Pre dialóg najskôr vkladáme polopriehľadnú šedú vrstvu cez stránku
ako element <div>
s triedou .modal
. Na
dosiahnutie efektu animácie pridávame ešte triedu .fade
, ak by
sme animáciu z nejakého dôvodu nechceli, tak triedu jednoducho nepridáme. Na
vylúčenie vybrania vrstvy klávesom Tab uvádzame atribút
tabindex="-1"
. A konečne na dosiahnutie podpory hlasových
čítačiek pridávame atribúty aria-labelledby="dialog-label"
a
aria-hidden="true"
. Samotný dialóg potom vkladáme ako ďalší
<div>
s triedou .modal-dialog
. Ten rozdelíme na
divy s triedami .modal-header
, .modal-body
a
.modal-footer
. Za povšimnutie stojí ešte vloženie krížika na
uzavretie dialógu v jeho hlavičke.
Do dialógu môžeme vložiť ľubovoľný HTML obsah vrátane formulárov. Avšak pozor, nepoužívajme dialógy na reklamné oznámenia, ktoré sa otvoria hneď po navštívení stránky, Google takéto weby penalizuje.
Pri zobrazení pop-upu sa na element <body>
automaticky
aplikuje trieda .modal-open
, ktorá mu odstráni scrollbary. Nie je
potrebné ju implementovať ručne. Môžeme tak zcrollovať obsahom pop-upu,
pokiaľ sa na stránku nezmestí, namiesto aby sme rolovali stránkou. Bootstrap
modal sa zavrie kliknutím mimo neho. V jednej chvíli môžeme zobraziť iba
jeden takýto dialóg. Pretože sa modálne dialógy zobrazujú s fixnou
pozíciou, mali by sme modálny obsah umiestniť nad obsah stránky, aby
nedošlo k prekrytiu modálneho obsahu nejakou časťou obsahu na stránke. V
modálnych dialógoch nebude fungovať atribút autofocus
. Ak by
sme do dialógu umiestnili formulár a chceli atribút využiť, musíme
namiesto neho siahnuť po JavaScripte:
var myModal = document.getElementById('myModal') var myInput = document.getElementById('myInput') myModal.addEventListener('shown.bs.modal', function () { myInput.focus() })
Ako už bolo povedané, do dialógov môžeme vložiť prakticky čokoľvek vrátane popovers alebo gridu, viď ďalej v kurze.
Predvyplnenie obsahu
Modálne dialógy môžeme predvyplniť alebo aj ľahko pozmeniť ich obsah v závislosti od udalosti, pri akej boli otvorené. Môžeme teda používať jeden modálny dialóg na viac podobných účelov.
V ukážke nižšie vyplníme text do inputu v závislosti na stlačenom tlačidle:
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#dialog" data-bs-whatever="funkce">Request a new feature</button> <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#dialog" data-bs-whatever="bug">Report a bug</button> <div class="modal fade" id="dialog" tabindex="-1" aria-labelledby="dialog-label" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="dialog-label">System Development</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <form> <div class="mb-3"> <label for="request-type" class="col-form-label">Request type</label> <input type="text" class="form-control" id="request-type"> </div> <div class="mb-3"> <label for="request-text" class="col-form-label">Text</label> <textarea class="form-control" id="request-text"></textarea> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary">Submit</button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div>
Na predvyplnenie dialógu využijeme JavaScript:
var MyModal = document.getElementById('dialog') MyModal.addEventListener('show.bs.modal', function (event) { var button = event.relatedTarget // Get the button which opened the modal var recipient = button.getAttribute('data-bs-whatever') // Load information from its data attribute var modalBodyInput = MyModal.querySelector('.modal-body input') // Assign the value to the input modalBodyInput.value = recipient })
V JavaScripte by sme samozrejme mohli upraviť akúkoľvek časť dialógu,
načítať doň niečo AJAXom a podobne. Kľúčová je reakcia na udalosť
show.bs.modal
.
Výsledok v prehliadači:
Výška dialógu
Dialóg sa vycentruje v závislosti na jeho výške, ktorá sa vypočíta pri
jeho zobrazení. Pre dynamickú zmenu obsahu a následnú aktualizáciu pozície
modálneho okna použijeme metódu myModal.handleUpdate()
na
inštancii modálneho dialógu vytvoreného pomocou JavaScriptu:
var myModal = new bootstrap.Modal(document.getElementById('dialog')); myModal.handleUpdate();
Veľkosti
Aj dialógy môžeme vyvolať v niekoľkých veľkostiach a to pridaním
triedy elementu <div>
s triedou .modal-dialog
,
teda druhému vnorenému divu:
.modal-sm
- malý dialóg,- bez triedy pre predvolenú veľkosť,
.modal-lg
- väčší dialóg,.modal-xl
- veľký dialóg.
JavaScript
Ako už bolo povedané, JavaScript bude pri modálnych dialógoch naším priateľom. Okrem vyvolania tlačidlami s dáta atribútom môžeme dialóg vyvolať pomocou JavaScriptu ako:
var myModal = new bootstrap.Modal(document.getElementById('myModal'), options)
Tento prístup je alternatívou k použitiu dáta atribútov v HTML pre spúšťanie modálneho okna. To je užitočné v situáciách, kde potrebujeme viac kontroly nad správaním modálneho okna, než akú poskytujú štandardné dáta atribúty.
Vlastnosti dialógu
Pomocou dáta atribútov s prefixom data-bs-
alebo pomocou
nasledujúcich javascriptových vlastností na dialógu je možné meniť jeho
správanie. Objekt s týmito vlastnosťami môžeme odovzdať konstruktoru
vyššie ako parameter:
backdrop
- Hodnotatrue
spôsobí prekrytie stránky polopriehľadným šedým pozadím. Navyše, hodnotastatic
neumožní zatvoriť dialóg kliknutím na toto pozadie. S hodnotoufalse
sa táto prekryvná vrstva nezobrazí.keyboard
- Na základe hodnôttrue
alebofalse
dôjde, resp. nedôjde, k uzavretiu dialógu po stlačení klávesy Esc.focus
- Presunie focus na dialóg po jeho otvorení, predvolená hodnota jetrue
.
Metódy dialógu
Všetky metódy sú volané asynchrónne a odovzdávajú konania ešte predtým, než dôjde k dokončeniu animácie (transition). Ak zavoláme metódu na dialógu, ktorý práve prehráva transition, bude toto volanie metódy ignorované.
Objekt s nastavenými vlastnosťami tak, ako sme si ich popísali vyššie, voláme napríklad ako:
var myModal = new bootstrap.Modal(document.getElementById('myModal'), { keyboard: false })
Metódy na ovládanie dialógu sú tieto:
toggle()
- Otvorí/skryje dialóg a odovzdá riadenie skôr, než dôjde k jeho skutočnému zobrazeniu/skrytiu.show()
- Otvorí dialóg a odovzdá konanie skôr, než dôjde k jeho skutočnému zobrazeniu.hide()
- Zavrie dialóg a odovzdá konanie skôr, než dôjde k jeho skutočnému zmiznutiu.handleUpdate()
- Prepozicuje dialóg na základe jeho výšky. Voláme, pokiaľ sa jeho výška zmenila.dispose()
- Zničí dialóg.getInstance()
- Statická metóda, ktorá umožní získať modálnu inštanciu spojenú s prvkom DOM.getOrCreateInstance()
- Statická metóda, ktorá umožní získať modálnu inštanciu pridruženú k prvku DOM alebo vytvoriť novú v prípade, že nebola inicializovaná.
Udalosti
Všetky modálne udalosti sú spúšťané na samotný modal (tj. na
<div class="modal">
):
show.bs.modal
- Vyvolá sa po otvorení dialógu, ale ešte pred jeho zobrazením, pretože stále môže prebiehať animácia. Pokiaľ bol dialóg otvorený pomocou tlačidla, nájdeme tento element vo vlastnostirelatedTarget
tejto udalosti.shown.bs.modal
- Vyvolá sa akonáhle je dialóg zobrazený, teda po dokončení jeho animácie. Pokiaľ bol dialóg otvorený pomocou tlačidla, nájdeme tento element vo vlastnostirelatedTarget
tejto udalosti.hide.bs.modal
- Vyvolá sa po uzavretí dialógu, ale ešte pred tým, než dialóg naozaj zmizne.hidden.bs.modal
- Vyvolá sa až potom, čo uzavretý dialóg prestane byť viditeľný.hidePrevented.bs.modal
- Udalosť sa spustí, keď je zobrazený dialóg a jeho pozadie je statické pri kliknutí mimo dialóg alebo pri stlačení klávesu Esc alebo nastavenímdata-bs-keyboard
nafalse
.
Reakcia na udalosť vyzerá napríklad takto:
const myModalEl = document.getElementById('myModal') myModalEl.addEventListener('hidden.bs.modal', event => { // Some reaction to the event... })
V budúcej lekcii, Bootstrap - Popovers, sa budeme venovať komponentom Popovers.