POUZE NYNÍ: Získej až 80 % extra kreditů ZDARMA na náš interaktivní e-learning. Zjistit více.
NOVINKA: Staň se datovým analytikem od 0 Kč a získej jistotu práce, lepší plat a nové kariérní možnosti. 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. Tentokrát to byly Pagination, Alerts a Breadcrumb.

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

Ačkoli se pop-upy, tedy překryvný obsah, na web úplně nehodí, občas se jim 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. Těmto modálním dialogům se říká také lightboxy.

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.

V první ukázce 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-primary" data-bs-dismiss="modal">Uložit</button>
            </div>
        </div>
    </div>
</div>

V praxi budeme dialogy na rozdíl od naprosté většiny komponent spouštět 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 Bootstrapu
popupy.html

Pro dialog nejprve vkládáme poloprůhlednou šedou vrstvu přes stránku jako element <div> s 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 tuto 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> s třídou .modal-dialog. Ten rozdělíme na <div> elementy s 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 k reklamním sdělením, 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, aniž bychom 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 bychom tento atribut 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ě popoverů nebo gridu, viz dále v kurzu.

Předvyplnění obsahu

Obsah modálních dialogů lze předvyplnit a případně upravit v závislosti na události, při které 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"></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>
            </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 technologií AJAX a podobně. Klíčová je reakce na událost show.bs.modal.

Výsledek v prohlížeči:

Pop-upy v Bootstrapu
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

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

  • .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, kdy 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 konstruktoru 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í hodnotou 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'), {
  keyboard: false
})

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. Metodu voláme, pokud se výška dialogu 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ředtí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 - Popovery, se budeme věnovat komponentě popover.


 

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 - Popovery
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
955 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