IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 23 - Bootstrap - Modální dialogy

V minulé lekci, Bootstrap - Paginace, Upozornění a Drobečková navigace, jsme pokračovali v přehlídce Bootstrap komponent Pagination, Alerts a Breadcrumb.

V následujícím tutoriálu CSS frameworku Bootstrap se budeme věnovat modálním dialogům.

Ačkoli pop-upy, překryvný obsah, se na web úplně nehodí, občas se mu nevyhneme. Jedná se například o situaci, kdy se chceme uživatele zeptat, zda si skutečně přeje zavřít záložku, protože má rozdělanou práci. K tomuto účelu bychom sice mohli použít nativní JavaScriptové dialogy (confirm(), prompt(), alert()), ale ty většinou nevypadají zrovna nejlépe a nelze je přizpůsobovat. Pop-upy se často používají také například k otevření zvětšeniny obrázku nebo videa, aby se zabránilo zbytečnému přesměrování na jinou stránku. Známé jsou také pod označením lightbox.

Modální dialogy v Bootstrapu

Modální dialogy tvoříme pomocí JavaScriptu. Budeme k nim tedy opět potřebovat načíst Bootstrap JavaScript plugin.

Jako první ukázku do stránky vložíme tlačítko, které po stisknutí vyvolá modální dialog:

<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#dialog">
    Otevřít dialog
</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">Titulek</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Zavřít">
                </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">Zavřít</button>
            </div>
        </div>
    </div>
</div>

Dialogy budeme na rozdíl od naprosté většiny komponent spouštět v praxi spíše JavaScriptem. V ukázce výše je dialog otevřený pomocí elementu <button> a data atributem data-bs-toggle="modal". Pomocí atributu data-bs-target uvedeme selektor na dialog, který má tlačítko otevřít. Výsledek v prohlížeči:

Pop-upy v Bootstrap
popupy.html

Pro dialog nejprve vkládáme poloprůhlednou šedou vrstvu přes stránku jako element <div> se třídou .modal. K dosažení efektu animace přidáváme ještě třídu .fade, pokud bychom animaci z nějakého důvodu nechtěli, tak třídu jednoduše nepřidáme. K vyloučení vybrání vrstvy klávesou Tab uvádíme atribut tabindex="-1". A konečně k dosažení podpory hlasových čteček přidáváme atributy aria-labelledby="dialog-label" a aria-hidden="true". Samotný dialog poté vkládáme jako další <div> se třídou .modal-dialog. Ten rozdělíme na divy se třídami .modal-header, .modal-body a .modal-footer. Za povšimnutí stojí ještě vložení křížku k uzavření dialogu v jeho hlavičce.

Do dialogu můžeme vložit libovolný HTML obsah včetně formulářů. Ovšem pozor, nepoužívejme dialogy na reklamní sdělení, která se otevřou hned po navštívení stránky, Google takové weby penalizuje.

Při zobrazení pop-upu se na element <body> automaticky aplikuje třída .modal-open, která mu odstraní scrollbary. Není třeba ji implementovat ručně. Můžeme tak scrollovat obsahem pop-upu, pokud se na stránku nevejde, místo abychom rolovali stránkou. Bootstrap modal se zavře kliknutím mimo něj. V jednu chvíli můžeme zobrazit pouze jeden takový dialog. Protože se modální dialogy zobrazují s fixní pozicí, měli bychom modální obsah umístit nad obsah stránky, aby nedošlo k překrytí modálního obsahu nějakou částí obsahu na stránce. V modálních dialozích nebude fungovat atribut autofocus. Pokud bychom do dialogu umístili formulář a chtěli atributu využít, musíme místo něj sáhnout po JavaScriptu:

var myModal = document.getElementById('myModal')
var myInput = document.getElementById('myInput')

myModal.addEventListener('shown.bs.modal', function () {
  myInput.focus()
})

Jak již bylo řečeno, do dialogů můžeme vložit prakticky cokoli včetně popovers nebo gridu, viz dále v kurzu.

Předvyplnění obsahu

Modální dialogy můžeme předvyplnit nebo i lehce pozměnit jejich obsah v závislosti na události, při jaké byly otevřené. Můžeme tedy používat jeden modální dialog pro více podobných účelů.

V ukázce níže vyplníme text do inputu v závislosti na stisknutém tlačítku:

<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#dialog" data-bs-whatever="funkce">Navrhnout novou funkci</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#dialog" data-bs-whatever="bug">Nahlásit 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">Vývoj systému</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Zavřít">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <form>
                    <div class="mb-3">
                        <label for="typ-pozadavku" class="col-form-label">Typ požadavku</label>
                        <input type="text" class="form-control" id="typ-pozadavku">
                    </div>
                    <div class="mb-3">
                        <label for="text-pozadavku" class="col-form-label">Text</label>
                        <textarea class="form-control" id="text-pozadavku"></textarea>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary">Odeslat</button>
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Zavřít</button>
            </div>
        </div>
    </div>
</div>

K předvyplnění dialogu využijeme JavaScript:

var MyModal = document.getElementById('dialog')
MyModal.addEventListener('show.bs.modal', function (event) {
  var button = event.relatedTarget   // Získáme tlačítko, kterým jsme dialog otevřeli
  var recipient = button.getAttribute('data-bs-whatever')   // Získáme info z data-bs-whatever atributu
  var modalBodyInput = MyModal.querySelector('.modal-body input') // Přiřadíme hodnotu do inputu
  modalBodyInput.value = recipient
})

V JavaScriptu bychom samozřejmě mohli upravit jakoukoli část dialogu, načíst do něj něco AJAXem a podobně. Klíčová je reakce na událost show.bs.modal.

Výsledek v prohlížeči:

Pop-upy v Bootstrap
popupy_predvy­plneni.html

Výška dialogu

Dialog se vycentruje v závislosti na jeho výšce, která se vypočítá při jeho zobrazení. Pro dynamickou změnu obsahu a následnou aktualizaci pozice modálního okna použijeme metodu myModal.handleUpdate() na instanci modálního dialogu vytvořeného pomocí JavaScriptu:

var myModal = new bootstrap.Modal(document.getElementById('dialog'));
myModal.handleUpdate();

Velikosti

I dialogy můžeme vyvolat v několika velikostech a to přidáním třídy elementu <div> se třídou .modal-dialog, tedy druhému vnořenému divu:

  • .modal-sm - malý dialog,
  • bez třídy pro výchozí velikost,
  • .modal-lg - větší dialog,
  • .modal-xl - velký dialog.

JavaScript

Jak již bylo řečeno, JavaScript bude u modálních dialogů naším přítelem. Kromě vyvolání tlačítky s data atributem můžeme dialog vyvolat pomocí JavaScriptu jako:

var myModal = new bootstrap.Modal(document.getElementById('myModal'), options)

Tento přístup je alternativou k použití data atributů v HTML pro spouštění modálního okna. To je užitečné v situacích, kde potřebujeme více kontroly nad chováním modálního okna, než jakou poskytují standardní data atributy.

Vlastnosti dialogu

Pomocí data atributů s prefixem data-bs- nebo pomocí následujících javascriptových vlastností na dialogu lze měnit jeho chování. Objekt s těmito vlastnostmi můžeme předat metodě modal() výše jako parametr:

  • backdrop - Hodnota true způsobí překrytí stránky poloprůhledným šedým pozadím. Hodnota static navíc neumožní dialog zavřít kliknutím na toto pozadí. S hodnotou false se tato překryvná vrstva nezobrazí.
  • keyboard - Na základě hodnot true nebo false dojde, resp. nedojde, k uzavření dialogu po stisknutí klávesy Esc.
  • focus - Přesune focus na dialog po jeho otevření, výchozí hodnota je true.

Metody dialogu

Všechny metody jsou volané asynchronně a předávají řízení ještě předtím, než dojde k dokončení animace (transition). Pokud zavoláme metodu na dialogu, který právě přehrává transition, bude toto volání metody ignorováno.

Objekt s nastavenými vlastnostmi tak, jak jsme si je popsali výše, voláme například jako var myModal = new bootstrap.Modal(document.getElementById('myModal'), options).

Metody pro ovládání dialogu jsou pak tyto:

  • toggle() - Otevře/skryje dialog a předá řízení dříve, než dojde k jeho skutečnému zobrazení/skrytí.
  • show() - Otevře dialog a předá řízení dříve, než dojde k jeho skutečnému zobrazení.
  • hide() - Zavře dialog a předá řízení dříve, než dojde k jeho skutečnému zmizení.
  • handleUpdate() - Přepozicuje dialog na základě jeho výšky. Voláme, pokud se jeho výška změnila.
  • dispose() - Zničí dialog.
  • getInstance() - Statická metoda, která umožní získat modální instanci spojenou s prvkem DOM.
  • getOrCreateInstance() - Statická metoda, která umožní získat modální instanci přidruženou k prvku DOM nebo vytvořit novou v případě, že nebyla inicializována.

Události

Všechny modální události jsou spouštěny na samotný modal (tj. na <div class="modal">):

  • show.bs.modal - Vyvolá se po otevření dialogu, ale ještě před jeho zobrazením, protože stále může probíhat animace. Pokud byl dialog otevřen pomocí tlačítka, nalezneme tento element ve vlastnosti relatedTarget této události.
  • shown.bs.modal - Vyvolá se jakmile je dialog zobrazený, tedy po dokončení jeho animace. Pokud byl dialog otevřen pomocí tlačítka, nalezneme tento element ve vlastnosti relatedTarget této události.
  • hide.bs.modal - Vyvolá se po uzavření dialogu, ale ještě před tím, než dialog opravdu zmizí.
  • hidden.bs.modal - Vyvolá se až poté, co uzavřený dialog přestane být viditelný.
  • hidePrevented.bs.modal - Událost se spustí, když je zobrazen dialog a jeho pozadí je statické při kliknutí mimo dialog nebo při stisknutí klávesy Esc nebo nastavením data-bs-keyboard na false.

Reakce na událost vypadá například takto:

const myModalEl = document.getElementById('myModal')
myModalEl.addEventListener('hidden.bs.modal', event => {
    // Nějaká reakce na událost...
})

V příští lekci, Bootstrap - Popovers, se budeme věnovat komponentám Popovers.


 

Předchozí článek
Bootstrap - Paginace, Upozornění a Drobečková navigace
Všechny články v sekci
Kompletní kurz CSS frameworku Bootstrap
Přeskočit článek
(nedoporučujeme)
Bootstrap - Popovers
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
516 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity