A lightweight utility for creating and controlling Bootstrap modals dynamically using JavaScript.
This library simplifies the process of building Bootstrap modal structures, handling modal lifecycle events, and providing convenient helpers for common dialog patterns such as alert, confirm, and prompt.
- Demo Files: ./demo
- Fiddle (ESM build): https://jsfiddle.net/c1uLypkg/
- Fiddle (UMD build): https://jsfiddle.net/u5ah2dxq/
- Bootstrap 5.x (JavaScript bundle required)
- Bootstrap 5.x
This library assumes Bootstrap is already loaded and available globally.
Example:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/js/bootstrap.bundle.min.js"></script>- UMD: https://cdn.jsdelivr.net/gh/dday9/bootstrap-modal-extension@1.0.0/dist/bootstrap-modal-extension.umd.min.js
- ESM: https://cdn.jsdelivr.net/gh/dday9/bootstrap-modal-extension@1.0.0/dist/bootstrap-modal-extension.esm.min.js
This library can be used either as an ES module or as a UMD script.
The built files are located in the dist directory.
./dist/bootstrap-modal-extension.esm.js./dist/bootstrap-modal-extension.umd.js
import { alert, confirm, prompt, Utilities } from './bootstrap-modal-extension.esm.js';<script src="bootstrap-modal-extension.umd.js"></script>
<script>
BootstrapModalExtension.alert("Hello world");
</script>Bootstrap Modal Extension works by constructing the modal DOM structure automatically using a configuration object.
The library:
- Generates standard Bootstrap modal markup
- Automatically attaches the modal to
document.body - Cleans up the DOM after the modal closes
- Provides optional form handling for prompts
- Includes built-in dialog helpers
import { alert } from './bootstrap-modal-extension.esm.js';
alert("Something happened!");Options can be passed to customize the title.
alert("Saved successfully", {
title: "My Application"
});Returns a Promise that resolves with true or false.
import { confirm } from './bootstrap-modal-extension.esm.js';
const confirmed = await confirm("Are you sure?");
if (confirmed) {
console.log("User confirmed");
}Returns a Promise that resolves with the user input.
import { prompt } from './bootstrap-modal-extension.esm.js';
try {
const name = await prompt("What is your name?");
console.log("Hello", name);
} catch {
console.log("User cancelled");
}Prompt supports input type customization.
prompt("Enter a number", {
type: "number"
});The modal structure can also be created manually using configuration objects.
Utilities.createModal({
dialog: {
content: {
header: { title: "Example Modal" },
body: { text: "Hello from the modal body" },
footer: {
ok: "Save",
cancel: "Cancel"
}
}
}
});interface ModalOptions {
id?: string
fade?: boolean
static?: boolean
tabIndex?: number
dialog?: ModalDialogOptions
}Static modals disable backdrop closing and keyboard escape.
{
static: true
}interface ModalDialogOptions {
scrollable?: boolean
verticallyCentered?: boolean
size?: "sm" | "lg" | "xl"
fullscreen?: boolean
content?: ModalContentOptions
}Examples:
{
dialog: {
size: "lg",
scrollable: true
}
}interface ModalContentOptions {
header?: ModalHeaderOptions
body?: ModalBodyOptions
footer?: ModalFooterOptions
}interface ModalHeaderOptions {
title?: string
close?: boolean | string
}Examples:
{
header: {
title: "User Settings",
close: true
}
}Custom close button label:
{
header: {
close: "Dismiss"
}
}interface ModalBodyOptions {
text?: string
prompt?: ModalPromptOptions
}Example:
{
body: {
text: "Please confirm this action."
}
}Prompts allow the modal to contain a form and input element.
interface ModalPromptOptions {
id?: string
submit?: (event) => void
input?: ModalInputOptions
}Example:
{
body: {
text: "Enter your name",
prompt: {
input: {
type: "text",
placeholder: "Your name"
}
}
}
}interface ModalInputOptions {
type?: string
class?: string
name?: string
placeholder?: string
validation?: ValidationOptions
}Supported input types:
- color
- date
- datetime-local
- file
- month
- number
- password
- range
- search
- tel
- text
- time
- url
- week
interface ValidationOptions {
required?: boolean
minlength?: number
maxlength?: number
min?: number
max?: number
step?: number
pattern?: string
}Example:
{
validation: {
required: true,
minlength: 3
}
}interface ModalFooterOptions {
ok?: ButtonOptions | string
cancel?: ButtonOptions | string
form?: string
}Example:
{
footer: {
ok: "Submit",
cancel: "Cancel"
}
}interface ButtonOptions {
text?: string
class?: string
type?: "button" | "submit" | "reset"
dismissOnClick?: boolean
}Example:
{
ok: {
text: "Save",
type: "submit"
}
}The library includes helper utilities for building modals and managing lifecycle.
Creates a normalized modal configuration.
Utilities.buildModal({
header: { title: "Title" },
body: { text: "Body text" },
footer: { ok: "Ok" }
});Creates and displays the modal immediately.
Utilities.createModal(modalOptions);This automatically:
- Adds the modal to
document.body - Instantiates
bootstrap.Modal - Removes the modal from the DOM after it is hidden
The library listens to Bootstrap modal lifecycle events.
- shown.bs.modal
- hidden.bs.modal
These events are used internally to manage focus, cleanup, and Promise resolution.
Bootstrap Modal Extension aims to provide a minimal abstraction over Bootstrap modals while keeping the generated markup fully compatible with Bootstrap.
Principles:
- Generate valid Bootstrap modal markup
- Avoid unnecessary abstractions
- Favor simple configuration objects
- Keep DOM generation predictable
- Automatically clean up modals after closing
Utilities.createModal({
dialog: {
size: "lg",
content: {
header: {
title: "Example"
},
body: {
text: "This modal was created dynamically."
},
footer: {
ok: "Save",
cancel: "Cancel"
}
}
}
});Show your support! Your (non-tax deductible) donation of Monero cryptocurrency is a sign of solidarity among web developers.
Being self taught, I have come a long way over the years. I certainly do not intend on making a living from this free feature, but my hope is to earn a few dollars to validate all of my hard work.
Monero Address: 447SPi8XcexZnF7kYGDboKB6mghWQzRfyScCgDP2r4f2JJTfLGeVcFpKEBT9jazYuW2YG4qn51oLwXpQJ3oEXkeXUsd6TCF
