I know, not another JavaScript library for Bootstrap modals, right?
However, I found that existing libraries seem to be no longer updated/supported, for older versions of Bootstrap, and/or still require jQuery. So, I decided to write my own for Bootstrap 5, using all native JavaScript and native Bootstrap markup and CSS - there is no custom styling.
I should mention that both the standard and module versions of the library are using newer JavaScript features (as of this writing) which are only supported in more recent versions of the major browsers; like class structures, including private fields and methods.
That said, I have also included a compatibility version of the library transpiled by Babel, if needed. It targets the versions of all major browsers which first included class support (for specifics, check out the Grunt configuration file). I did not go back as far as ES5, because Bootstrap 5 no longer supports it either.
Important Note
As of version1.7.0
, I have stopped generating the compatibility version of the library. All features are now supported by greater than 90% of browsers, so I feel it is no longer necessary. This allows me to drop the babel dependency, as well as decrease the distribution size. However, I have backed-up version 1.6.2 to an alternate branch in the unlikely event anyone still needs it.
Requirements
Just Bootstrap version 5.0.1 or greater.
Getting Started
The modbox library can be added to your project in several ways:
-
NPM:
npm i bootstrap-modbox
Although since it's client-side, if you're not using a bundler (eg. Webpack), you'll also have to copy the necessary
.js
file(s) fromnode_modules/bootstrap-modbox/dist
into your project folder structure and include it in your page(s) like the examples below. -
Unpkg CDN:
<!-- latest version --> <script src="https://unpkg.com/bootstrap-modbox"></script> <!-- specific version --> <script src="https://unpkg.com/bootstrap-modbox@1.7.0/dist/bootstrap-modbox.min.js"></script>
// latest version import modbox from 'https://unpkg.com/bootstrap-modbox/dist/bootstrap-modbox.esm.min.js'; // specific version import modbox from 'https://unpkg.com/bootstrap-modbox@1.7.0/dist/bootstrap-modbox.esm.min.js';
-
Download from GitHub:
<script src="dist/bootstrap-modbox.min.js"></script>
import modbox from './dist/bootstrap-modbox.esm.min.js';
Notes
-
Bootstrap ES module:
Modbox will automatically attempt to locate a reference to Bootstrap in the global namespace. If it does not exist, such as when loading Bootstrap as an ES module, you will also need to pass it as a reference to the
modbox.bootstrapModal
property before it can be used.import * as bootstrap from '/path/to/bootstrap.esm.min.js'; import modbox from '/path/to/bootstrap-modbox.esm.min.js'; modbox.bootstrapModal = bootstrap.Modal;
... or ...
import { Modal } from '/path/to/bootstrap.esm.min.js'; import modbox from '/path/to/bootstrap-modbox.esm.min.js'; modbox.bootstrapModal = Modal;
Unfortunately, it is not as simple as automatically importing Bootstrap into the module version of modbox. The ES standard module system requires a path to the file to be imported. Meaning if I were to include it, I would have to hardcode the path, and anyone using modbox would either have to use that same path to Bootstrap, or modify the code with their own path - which is obviously not desirable. Alternatively, if I imported Bootstrap using the specifier syntax (
import * as bootstrap from 'bootstrap'
), then a bundler like webpack would be required and no one could use the ES module version in a vanilla JavaScript environment (it would throw an error).A JavaScript import map could work, however, it is currently still an experimental feature and not supported by all browsers. For now, the above solution should be sufficient, and I have added a more descriptive error thrown if the
bootstrap
object is not found. -
Sanitization:
This library builds its markup as a string, then uses the
element.insertAdjacentHTML()
method to parse and inject the resulting nodes into the DOM. There has been some concern shown for other libraries using similar methods (element.insertHTML
, jQuery$(element).html()
, etc) that this could be a potential XSS attack vector (eg. user submitted data), considering that custom markup can be passed as a string with some configuration options (title, body, etc).I understand this argument in theory, however in practice, I feel it's a non-issue. It should be the responsibility of each developer to handle such situations. If you're using user submitted data to build the markup for a modbox, it is on you to make sure the data is clean and safe. Handling this task is outside the scope of this library.
So that said, I'm not going to take the time to write and maintain my own sanitizer, nor am I going to add an external dependency. However, as a compromise, I have added a
sanitizer
option that accepts a function, which can be from an external library like DOMPurify (for example), should you wish to include/use one on your own. In addition, the.prompt()
modal also has aninput.sanitizer
option that can clean the user input before being passed to the Promise resolve function. See the documentation for more details.Please note that if you use software which scans your code for vulnerabilities, the solution above will most likely not satisfy those scans, since markup is still permitted and the sanitizer is optional.