Bootstrap JavaScript
Open a modal with a button
Description: Add a button “Open”. The click must open a modal with a title, a text and a Close button.
Hint:
- Use
data-bs-toggle="modal",data-bs-targetanddata-bs-dismiss="modal".
Solution
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#ex1">Open</button>
<div class="modal fade" id="ex1" tabindex="-1" aria-labelledby="ex1Label" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="ex1Label">Hello</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">This is a modal.</div>
<div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button></div>
</div>
</div>
</div>
const m = document.getElementById('ex1');
document.querySelector('[data-bs-toggle="modal"]').click();
await new Promise(r => setTimeout(r, 700));
console.log('open: ' + m.classList.contains('show'));
m.querySelector('.modal-footer .btn').click();
await new Promise(r => setTimeout(r, 700));
console.log('open after Close: ' + m.classList.contains('show'));
open: true
open after Close: false
How it works
- The button opens the element with the id from
data-bs-target. modal-dialog-centeredputs the box in the vertical center.
Read Modal.
Create an accordion with three items
Description: Make an accordion with three items. The first is open at the start, and opening another one must close the first.
Hint:
- Use
accordion,accordion-item,accordion-buttonanddata-bs-parent.
Solution
<div class="accordion" id="acc">
<div class="accordion-item">
<h2 class="accordion-header"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#a1" aria-expanded="true" aria-controls="a1">Item 1</button></h2>
<div id="a1" class="accordion-collapse collapse show" data-bs-parent="#acc"><div class="accordion-body">Text of item 1</div></div>
</div>
<div class="accordion-item">
<h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#a2" aria-expanded="false" aria-controls="a2">Item 2</button></h2>
<div id="a2" class="accordion-collapse collapse" data-bs-parent="#acc"><div class="accordion-body">Text of item 2</div></div>
</div>
<div class="accordion-item">
<h2 class="accordion-header"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#a3" aria-expanded="false" aria-controls="a3">Item 3</button></h2>
<div id="a3" class="accordion-collapse collapse" data-bs-parent="#acc"><div class="accordion-body">Text of item 3</div></div>
</div>
</div>
document.querySelector('[data-bs-target="#a3"]').click();
await new Promise(r => setTimeout(r, 800));
['a1', 'a2', 'a3'].forEach(id => console.log(id + ' open = ' + document.getElementById(id).classList.contains('show')));
a1 open = false
a2 open = false
a3 open = true
How it works
data-bs-parent="#acc"connects the items, so Bootstrap closes the others.- After the click on item 3, only item 3 is open.
Read Collapse and Accordion.
Create tabs with three panels
Description: Create three tabs. Clicking a tab must show only its own panel.
Hint:
- Use
nav nav-tabs,data-bs-toggle="tab"andtab-contentwithtab-pane.
Solution
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation"><button class="nav-link active" id="t1" data-bs-toggle="tab" data-bs-target="#p1" type="button" role="tab" aria-controls="p1" aria-selected="true">Home</button></li>
<li class="nav-item" role="presentation"><button class="nav-link" id="t2" data-bs-toggle="tab" data-bs-target="#p2" type="button" role="tab" aria-controls="p2" aria-selected="false">Profile</button></li>
<li class="nav-item" role="presentation"><button class="nav-link" id="t3" data-bs-toggle="tab" data-bs-target="#p3" type="button" role="tab" aria-controls="p3" aria-selected="false">Contact</button></li>
</ul>
<div class="tab-content border border-top-0 p-3">
<div class="tab-pane fade show active" id="p1" role="tabpanel" tabindex="0">Home panel</div>
<div class="tab-pane fade" id="p2" role="tabpanel" tabindex="0">Profile panel</div>
<div class="tab-pane fade" id="p3" role="tabpanel" tabindex="0">Contact panel</div>
</div>
document.getElementById('t3').click();
await new Promise(r => setTimeout(r, 500));
console.log('active panel: ' + document.querySelector('.tab-pane.active').textContent);
console.log('active tab: ' + document.querySelector('.nav-link.active').textContent);
active panel: Contact panel
active tab: Contact
How it works
- Each tab button points to a panel with
data-bs-target. Bootstrap switches the classesactiveandshow.
Read Navs and Tabs.
Create a carousel with three slides
Description: Make a carousel with three slides, previous and next buttons and three indicators.
Hint:
- Use
carousel slide,carousel-inner,carousel-item activeand the control buttons withdata-bs-slide.
Solution
<div id="cx" class="carousel slide" style="max-width: 420px">
<div class="carousel-indicators">
<button type="button" data-bs-target="#cx" data-bs-slide-to="0" class="active" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#cx" data-bs-slide-to="1" aria-label="Slide 2"></button>
<button type="button" data-bs-target="#cx" data-bs-slide-to="2" aria-label="Slide 3"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active"><img src="images/photo.jpg" class="d-block w-100" alt="Slide 1"></div>
<div class="carousel-item"><img src="images/photo.jpg" class="d-block w-100" alt="Slide 2"></div>
<div class="carousel-item"><img src="images/photo.jpg" class="d-block w-100" alt="Slide 3"></div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#cx" data-bs-slide="prev"><span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="visually-hidden">Previous</span></button>
<button class="carousel-control-next" type="button" data-bs-target="#cx" data-bs-slide="next"><span class="carousel-control-next-icon" aria-hidden="true"></span><span class="visually-hidden">Next</span></button>
</div>
const cx = document.getElementById('cx');
const idx = () => [...cx.querySelectorAll('.carousel-item')].findIndex(i => i.classList.contains('active')) + 1;
cx.querySelector('.carousel-control-next').click();
await new Promise(r => setTimeout(r, 900));
console.log('after Next: slide ' + idx());
cx.querySelector('.carousel-control-next').click();
await new Promise(r => setTimeout(r, 900));
console.log('after Next again: slide ' + idx());
cx.querySelector('.carousel-control-next').click();
await new Promise(r => setTimeout(r, 900));
console.log('after Next at the end: slide ' + idx() + ' (it goes round)');
after Next: slide 2
after Next again: slide 3
after Next at the end: slide 1 (it goes round)
How it works
- Exactly one
carousel-itemmust have the classactiveat the start. - After the last slide, the carousel goes back to the first one.
Read Carousel.
Add a tooltip to a button
Description: Add a tooltip “Save the file” to a button, which opens when the user hovers on it.
Hint:
- Use
data-bs-toggle="tooltip",data-bs-titleand start it withnew bootstrap.Tooltip().
Solution
<button type="button" class="btn btn-success" id="savebtn" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Save the file">Save</button>
<script>
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(function (el) { new bootstrap.Tooltip(el); });
</script>
const b = document.getElementById('savebtn');
b.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
await new Promise(r => setTimeout(r, 400));
const t = document.querySelector('.tooltip');
console.log('tooltip shown: ' + (t !== null) + ', text: ' + (t ? t.textContent.trim() : ''));
tooltip shown: true, text: Save the file
How it works
- Tooltips are not started automatically. The small script finds all elements with
data-bs-toggle="tooltip"and starts them.
Read Tooltips and Popovers.
Create an offcanvas sidebar which opens from the left
Description: A “Menu” button must open a sidebar from the left side, with two links and a close button.
Hint:
- Use
offcanvas offcanvas-start,data-bs-toggle="offcanvas"anddata-bs-dismiss="offcanvas".
Solution
<button class="btn btn-dark" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebar" aria-controls="sidebar">Menu</button>
<div class="offcanvas offcanvas-start" tabindex="-1" id="sidebar" aria-labelledby="sidebarLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="sidebarLabel">Menu</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<a class="d-block mb-2" href="#">Home</a>
<a class="d-block" href="#">Contact</a>
</div>
</div>
const s = document.getElementById('sidebar');
document.querySelector('[data-bs-toggle="offcanvas"]').click();
await new Promise(r => setTimeout(r, 700));
console.log('open: ' + s.classList.contains('show'));
s.querySelector('.btn-close').click();
await new Promise(r => setTimeout(r, 700));
console.log('open after close: ' + s.classList.contains('show'));
open: true
open after close: false
How it works
offcanvas-startplaces the panel on the left side. The toggle button opens it, and the close button closes it.
Read Offcanvas.
Create a button which switches the page to dark mode
Description: A button must switch the page between light and dark mode.
Hint:
- Change the attribute
data-bs-themeof the html element.
Solution
<button type="button" class="btn btn-outline-secondary" id="themeSwitch">Switch theme</button>
<script>
document.getElementById('themeSwitch').addEventListener('click', function () {
var root = document.documentElement;
root.setAttribute('data-bs-theme', root.getAttribute('data-bs-theme') === 'dark' ? 'light' : 'dark');
});
</script>
const bg = () => getComputedStyle(document.body).backgroundColor;
console.log('start: ' + (document.documentElement.getAttribute('data-bs-theme') || 'light') + ' -> ' + bg());
document.getElementById('themeSwitch').click();
console.log('after the 1st click: ' + document.documentElement.getAttribute('data-bs-theme') + ' -> ' + bg());
document.getElementById('themeSwitch').click();
console.log('after the 2nd click: ' + document.documentElement.getAttribute('data-bs-theme') + ' -> ' + bg());
start: light -> rgb(255, 255, 255)
after the 1st click: dark -> rgb(33, 37, 41)
after the 2nd click: light -> rgb(255, 255, 255)
How it works
- Bootstrap colors come from CSS variables, which change when
data-bs-themechanges. - To remember the choice of the user, also save it in
localStorage.
Read Color Modes.