Lekce 24 - Bootstrap - Popovers
V minulé lekci, Bootstrap - Modální dialogy, jsme se naučili používat modální dialogy.
V následujícím tutoriálu CSS frameworku Bootstrapu se budeme věnovat takzvaným Popovers. Informační bubliny Popovers jsou podobné tooltipům, které se ovšem nezobrazují a nemizí po přejetí myší, ale reagují na kliknutí.
Popovers v Bootstrapu
Bootstrap adoptoval Popovers z platformy iOS. Komponenta je založená rovněž na JavaScriptu, jako tomu bylo u Dropdowns, které jsme si představili v lekci Bootstrap - Dropdowns. Všechny potřebné závislosti jsou již součástí javascriptového balíčku Bootstrapu (bundle). Pro inicializaci Popovers stačí použít přímo funkce Bootstrapu 5 v nativním JavaScriptu.
Inicializace popoverů
Z důvodu optimalizace nejsou popovers inicializovány na základě data atributů jako dosavadní komponenty, ale musíme je inicializovat ručně a to například přes data atributy JavaScriptem:
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')) var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { return new bootstrap.Popover(popoverTriggerEl) })
Tento přístup umožňuje definovat chování HTML elementů přímo v HTML
kódu a poté je dynamicky inicializovat pomocí JavaScriptu. Kód, který jsme
si ukázali, vyhledá všechny elementy, které mají data atribut
data-bs-toggle="popover"
, a pro každý z nich vytvoří nový
popover objekt Bootstrapu.
Dalším způsobem inicializace je využít wrapper. Tedy obalit element, ze kterého chceme popover vytvořit, dalším elementem a vytvořit popover právě z tohoto obalujícího elementu. Někdy se může stát, že styly popoveru kolidují s našimi styly a právě řešení s wrapperem tento problém vyřeší, protože popover se vytvoří až z wrapperu, který je bez stylů:
var popover = new bootstrap.Popover(document.querySelector('.example-popover'), { container: 'body' })
Další vlastnosti popoverů
Popovers mají kromě jiného následující důležité vlastnosti:
- Pokud bude titulek nebo obsah prázdný string, popover se nezobrazí. K zobrazení nedojde ani v případě, když se pokusíme zobrazit popover na skrytém elementu.
- Při použití spolu s komplexnějšími komponentami, jako jsou například
input groups z lekce Bootstrap - Další
možnosti formulářů, button group z lekce Bootstrap - Tlačítka a
podobně, je vhodné uvést
container: body
pro vyhnutí se problémům s renderováním. - Pro zobrazení popoveru z elementu s atributem
disabled
nebo třídou.disabled
je třeba tento element obalit a popover zobrazit pomocí tohoto wrapperu. - V případě použití popovers na odkazy, které sahají přes více
řádek, bude popover vycentrován vzhledem k celkové šířce těchto odkazů.
Pro změnu tohoto chování přidáme elementu
<a>
stylwhite-space: nowrap;
. - Pokud bychom odstranit chtěli elementy, ze kterých jsme vytvořili popovery, musíme tyto popovery nejprve skrýt.
Použití popoverů v praxi
Ukažme si čtyři tlačítka, která po kliknutí zobrazí popovery v různých směrech okolo nich:
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Text nahoře"> Popover nahoře </button> <button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Text vpravo"> Popover vpravo </button> <button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Text dole"> Popover dole </button> <button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Text vlevo"> Popover vlevo </button> <script> var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')) var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { return new bootstrap.Popover(popoverTriggerEl) }) </script>
Všimněme si nutnosti explicitní inicializace JavaScriptem. Výsledek:
V ukázce výše se kvůli výšce prohlížeče zobrazí dolní popover rovněž nahoře.
Skrytí při kliknutí mimo popover
Určitě jsme si v ukázce výše vyzkoušeli, že se popover zavře jen
opětovným kliknutím na tlačítko. Toto chování můžeme upravit tak, aby
se popover zavřel při kliknutí na cokoli mimo toto tlačítko. Takový
popover vytvoříme pomocí data atributu
data-bs-trigger="focus"
:
<a tabindex="0" class="btn btn-lg btn-primary" role="button" data-bs-toggle="popover" data-bs-trigger="focus" title="Skrytí popoveru" data-bs-content="Tento obsah zmizí po kliknutí kamkoli mimo něj.">Test popoveru</a>
Inicializace, kterou v elementu <script>
vložíme na
konec <body>
pak vypadá takto:
var popover = new bootstrap.Popover(document.querySelector('.popover-btn'), { trigger: 'focus' })
JavaScript inicializuje popover na odkazu s třídou
.btn
, který je v HTML kódu. Pokud máme ve stránce více odkazů
s touto třídou a chceme inicializovat popover pouze na konkrétním odkazu,
můžeme přidat unikátní ID nebo specifickou třídu k tomuto odkazu a
použít ji jako selektor v JavaScriptu.
Výsledek v prohlížeči:
Stejného chování jsme mohli docílit i nastavením vlastnosti
trigger: focus
v JavaScriptu. K tlačítkům tohoto typu musíme
využívat jen elementů <a>
s rolí "button" a
tabindex="0"
. Chování na elementu <button>
nemusí být v některých prohlížečích podporováno.
JavaScript
Jako vždy si ještě ukažme, jak se komponenta ovládá přímo z JavaScriptu:
var exampleEl = document.getElementById('example') var popover = new bootstrap.Popover(exampleEl, options)
Vlastnosti popoverů
Veškeré níže uvedené vlastnosti můžeme nastavit pomocí data
atributů. K získání názvu atributu stačí k vlastnosti přidat prefix
data-bs-
. Pokud bychom chtěli vlastnosti inicializovat v
JavaScriptu, uděláme předáním objektu s těmito vlastnostmi metodě
popover()
:
document.querySelectorAll('[data-bs-toggle="popover"]').forEach(popoverTriggerEl => { new bootstrap.Popover(popoverTriggerEl, { animation: false, title: "Informace" }); });
Podívejme se na jednotlivé vlastnosti blíže:
animation
- Zda se má aplikovat animace (výchozítrue
).container
- Připojí popover k danému elementu. Pomocícontainer: body
způsobíme přichycení popoveru na element<body>
a tak zůstane na správném místě i při změně velikosti okna. Výchozí hodnota jefalse
.content
- Obsah popoveru, který se použije jako výchozí, když není uvedený v data atributudata-bs-content
příslušného elementu. Pokud předáme funkci, bude zavolána v kontextu elementu, ke kterému je popover připojený. Výchozí hodnota je""
(prázdný string).delay
- Prodleva v milisekundách před zobrazením/skrytím popoveru. Můžeme předat buď jedno číslo nebo specifikovat obě hodnoty předáním objektu s následující strukturou:delay: { "show": 250, "hide": 50 }
. Výchozí hodnota je0
.html
- Zda je v obsahu (content
) podporován HTML obsah. Výchozí hodnota jefalse
a tudíž se všechen obsah vloží jako pouhý text (pomocí jQuery metodytext()
).placement
- Určuje pozici popoveru, můžeme zadat hodnoty"auto"
,"top"
,"bottom"
,"left"
a"right"
, výchozí je"right"
. Předat můžeme i funkci, které se předá jako první parametr DOM element s popoverem a jako druhý parametr element tlačítka. Kontextthis
je nastaven na instanci popoveru.selector
- Pokud uvedeme příslušný selektor do této vlastnosti, budou popovery fungovat i na dynamicky vloženém obsahu. V opačném případě se popovery zaktivní pouze na elementech přítomných při prvním načtení stránky. Výchozí hodnota jefalse
.template
- HTML šablona, pomocí které se popover vytvoří. Titulek se vloží do elementu s třídou.popover-header
. Obsah se vloží do.popover-body
. Jako šipka se použije element se třídou.popover-arrow
. Element obalující celý popover by měl mít přiřazenou třídu.popover
. Výchozí hodnota je:
'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'
title
- Výchozí titulek, pokud není zadán data atributemdata-bs-title
na příslušném elementu. Můžeme předat i funkci, která je následně spuštěna v kontextu, kdethis
odkazuje na element, na který je popover připojený. Výchozí hodnota je""
(prázdný string).trigger
- Určuje způsob, jakým se popover zobrazí/skryje. Můžeme zadat hodnoty"click"
,"hover"
,"focus"
,"manual"
. Můžeme zadat i více hodnot oddělených mezerou kromě hodnoty"manual"
, kterou nelze kombinovat. Výchozí hodnota je"click"
.offset
- Umožní popover posunout relativně k tlačítku. Posouváme buď o stejnou vzdálenost v obou směrech zadáním jedné hodnoty nebo zadáním dvou hodnot oddělených čárkou. Více hodnot zadáváme jako textový řetězec (např."10%, 10px"
). Můžeme zadat i matematické výpočty. Výchozí hodnota je0
.fallbackPlacement
- Určuje kterou pozici popover zaujme v případě, že se nevejde na tu určenou. Můžeme uvést hodnoty"top"
,"right"
,"bottom"
a"left"
.
Metody
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 popoveru, který právě přehrává transition, bude toto volání metody ignorováno.
Na jednotlivé metody se podíváme blíže:
show()
- Zobrazí popover elementu. Vrací řízení před tím, než se dokončí animace a element se opravdu zobrazí/skryje.hide()
- Skryje popover elementu. Vrací řízení před tím, než se dokončí animace a element se opravdu zobrazí/skryje.toggle()
- Zobrazí/skryje popover elementu. Vrací řízení před tím, než se dokončí animace a element se opravdu zobrazí/skryje.dispose()
- Skryje a zničí popover elementu. Popovery, které mají specifikovanýselector
, nemusí být možné vždy zničit.enable()
- Umožní popoveru daného elementu, aby mohl být zobrazený. Ve výchozím stavu je zobrazení popoverům umožněno.disable()
- Znemožní popoveru daného elementu, aby mohl být zobrazený.toggleEnabled()
- Umožní/znemožní popoveru daného elementu, aby mohl být zobrazený.update()
- Aktualizuje pozici popoveru.
Události
Za určitých okolností můžeme potřebovat reagovat na jednotlivé události popoverů. Těch je celkem pět:
show.bs.popover
- Zavolá se ihned po zavoláníshow
. Element typicky není ještě zobrazený, protože se přehrává animace.shown.bs.popover
- Zavolá se ve chvíli zobrazení popoveru (po dokončení animace).hide.bs.popover
- Zavolá se ihned po zavoláníhide
. Element typicky není ještě skrytý, protože se přehrává animace.hidden.bs.popover
- Zavolá se ve chvíli skrytí popoveru (po dokončení animace).inserted.bs.popover
- Zavolá se po událostishow.bs.popover
, ve chvíli přidání šablony do DOM stránky.
Reakce na události vypadá například takto:
var myPopoverTrigger = document.getElementById('myPopover') myPopoverTrigger.addEventListener('hidden.bs.popover', function () { // nějaká reakce... });
V příští lekci, Bootstrap - Scrollspy, si představíme komponentu Scrollspy.