Lightbox Lib

Download Download from Github

Lightbox Lib

Download Download from Github

Lightbox Library is a suite of lightbox-related tools. Its focus is on providing a sophisticated API for HTML-based modal dialogs, but can also be used to:

  • Show in-DOM elements i.e. interfaces intended for display in a lightbox
  • Show loading progress indicators e.g. for AJAX uploads
  • Auto generate lightbox-hosted carousels, e.g. for cycling through product photos
  • Fetch and show, via lightbox, images or pages not currently in the DOM

All styling is done in the accompanying CSS file.

Examples 🔗

Example 1 - modal dailog: Simulating a native alert()-style messag. Read more: Modal dialogs.

lblib.modal({ title: 'Hello', content: 'Hello, world!' });

Example 2 - lightbox interface: pop up an HTML element inside the lightbox.

let element = document.querySelector('#interface'); lblib.lightbox(element); //<-- could also pass options as 2nd param

Example 3 - loading indicator: show an inifinite, barbershop-style loading indicator. Read more: Loading progress indicators.

lblib.loading(true); //<-- infinite, i.e. unknown time left

Example 4 - carousel usage: invoke the lightbox on an element containing slides for a carousel. Read more: Carousel usage.

let el = document.querySelector('#slides'); //<-- a UL, containing slides lblib.lightbox(el, {carousel: true});

Example 5 - absent file: Fetch and load an image not currently in the DOM. Read more: Absent files.

lblib.fetch('/some/image.jpg'); lblib.fetch('/some/page.html'); //<-- or even a web page!

API 🔗

Lightbox Lib declares a single global namespace, lblib, on which its API lives.

  • lblib.lightbox(element[, params]) - show an HTML element, element (an HTML element reference or selector string) as a lightbox pop-up. params is an object of config params, all of which are optional:
    • noClose (bool) - denotes that the lightbox should not be closable.
    • autoDisappear (bool) - whether the lightbox should automatically close after a number of seconds (defined in the global config).
    • carousel (bool) - if true, the child nodes within element will be shown one at a time, with next/previous navigation also provided. See Carousel usage.
    • openCallback (func) - a callback to fire once the lightbox has opened. It is automatically passed a reference to the central element as its first and only param.
  • lblib.modal(params) - create and show a lightbox-hosted modal dialog, as defined by params (object). See Modal dialogs.
  • lblib.loading(percent[, message, done]) - show an indicator relating to a loading operation. See Loading progress indicators.
    • percent (int/bool) - if true, an infinte, barberpole-style indicator shows, otherwise an integer representing the percent loaded.
    • message (str) - an optional accompanying message for the indicator.
    • done (bool) - shows an auto-disappearing 'loading complete' notification.
    • failed (bool) - as with done, but for when the loading failed.
  • lblib.hide() - hide the lightbox, regardless of the mode it's currently in (showcasing an HTML element, as a modal dialog, etc). See: Lightbox closure.
  • lblib.fetch(url[, params]) - fetch and show a remote image or web page located at url. Additional params may be passed, identical to lblib.lightbox(). See: Absent files.
  • lblib.onClose(func) - register a callback function, func, to fire whenever the lightbox closes. It is passed the reason for closure. See Lightbox closure.
  • lblib.setConfig(item, value) - set a global config item, item, to a new value.

Central element 🔗

The central element is the element the lightbox is showing at any given time. This will either be:

  • An element already in the DOM (when lblib.lightbox() is called)
  • An element created by Lightbox Lib (when any other method is called)

When asked to show an element already in the DOM (via lblib.lightbox()), Lightbox Lib will show a clone of that element, not the source element itself. This is important to note when thinking about events etc; the clone of the element will not have any events that the original had.

You can always access the current central element via lblib.element. This can be useful, say, if you want to treat the element somehow after it's been opened in the lightbox.

lblib.lightbox(document.querySelector('#my-el')); lblib.element.classList.add('some-class');

The central element is destroyed when the lightbox is later closed.

Global config 🔗

Lightbox Lib features some global config settings. These can be overridden as required via lblib.setConfig() (see API).

  • anim (bool) - whether elements should animate in when being shown in the lightbox (default: true)
  • escape (bool) - whether the lightbox can be closed (where closure is not suppressed) via the user pressing the escape key (default: true)
  • enter (bool) - whether the promise of a modal containing an input field is resolvable by the user pressing the enter key inside the field (default: true). The promise will be fulfilled with the field value. Additionally, the value can be retrievable later via lblib.lastEnterVal.
  • clickLB (bool) - whether the lightbox can be closed via the user clicking the lightbox (i.e. outside the central element) (default: true)
  • topCloseBtn (bool) - whether a top close button showing an 'X' should be generated and added to the lightbox (where appropriate) (default: true)
  • autoDisappearInterval (int) - the default number of seconds any item configured with the autoDisappear param should display before disappearing.
  • startEnterVal (string) - for use in conjunction with enter; a default value for lblib.lastEnterVal. See below.

Note that with enter, lblib.lastEnterVal will be updated only if a keypress occurs on a field in the modal. To set a start value for this, that will persist even if no keypress occurs, pass that value to the startEnterVal param.

For example, to set a longer autoDisappear delay:

lblib.setConfig('autoDisappearInterval', 3); //<-- 3 seconds

Modal dialogs 🔗

Probably Lightbox Lib's chief use is as a simulator for native modal dialogs.

As discussed in API, modal dialogs are created and launched via the lblib.modal() function. It expects a single argument, an object of config params. These can include any of the params also accepted by the params argument of lblib.lightbox() (see API), but also, additionally:

  • title (string) - a heading for the dialog (displayed as an H4 element)
  • content (string) - the content for the dialog. It will be automatically wrapped in P tags.
  • OKButton (object/bool) - a defiition for the "OK", or "positive" button, positioned to the bottom right of the dialog. If omitted, or passed as boolean true, a simple button showing "OK" will show which, when clicked, closes the dialog. If false, no button will sow. As an object, it accepts the following params:
    • text (string) - the button text - if omitted, "OK" will show.
    • noClose (bool) - suppress the button from closing the lightbox when clicked.
    • callback (func) - a callback function to fire when the button is clicked. The callback is forwarded two params - an reference to the button element, and the event object. Note if a callback is specified, it will not automatically close the lightbox when clicked (see Lightbox closure).
  • cancelButton (object/bool) - the same as with OKButton, but for the cancel, or "negative" button, positioned to the bottom left of the dialog. However, unlike with the "OK" button, if omitted, no button will show.

Buttons will never be generated for modals that are configured with either autoDisappear or noClose set to true.

lblib.modal() returns a promise, which is always resolved (regardless of how the lightbox is closed). The value passed to the resolve callback will be one of:

  • String - the value entered into the field, for prompt()-style modals
  • Boolean true - if the OK button was clicked
  • Boolean false - if the cancel button was clicked or the lightbox was closed in any other way

Promises means we can use some interesting patterns with lblib.modal(). See Modals and promises.

Chaining modals 🔗

One of the most useful ways to use Lightbox Lib's modal dialogs is to chain multiple steps of a user interaction flow together.

Let's say we wanted a confirm()-type dialog when a user clicks a delete button. We'll warn them, then in the button callback we'll run the deletion, and then we'll chain another dialog to confirm the action completed (except we'll make this one auto-disappear). We could do it like this (warning: ugly code ahead):

lblib.modal({ title: 'Sure?', content: 'Really delete this item?', cancelButton: true, OKButton: { text: 'I said delete!', noClose: 1, callback: (btn, evt) => { fetch('delete.php?item=something') .then(response => lblib.modal({ title: 'Deleted', content: 'Deleted!', autoDisappear: true })); } } });

This can get messy, though, the more nesting we do. Fortunately we can reduce this code via shortcut methods and exploiting lblib.modal()'s use of JavaScript promises.

Lightbox Lib provides a few shortcut methods for the three native modal functions - alert(), confirm() and prompt(). These are merely simplified aliases for  lblib.modal().

lblib.alert('Hi!'); //same as lblib.modal({content: 'Hi!'});

All three methods accept the same arguments as their native equivalents. However, each accepts an additional argument, which forces the OK button to have noClose behaveiour (see API). This can be handy keep the modal open while, say, an AJAX request completes.

Modals and promises 🔗

Because lblib.modal() returns a promise, there are other patterns we can use rather than just chaining callbacks. These can be useful for chaining modals because nested callbacks like we saw above can quickly become messy and unreadable.

For one thing, we can use so-called promise chaining, like so:

lblib.confirm('Press a button!') .then(result => lblib.alert(result ? 'OK' : 'Canceled')) .then(() => lblib.alert("OK, that's enough."));

For another, we can use the async/await combo, which allows our code to be (sort of) blocking. This means we can use modals the way native ones work, without the need for explicit callbacks:

//must be inside an 'async' callback to use 'await' (async () => { let name = await lblib.prompt("What's your name?") if (name) lblib.alert('Hi, '+name+'!'); })();

We can thus refactor the AJAX example above in the following way (note: for brevity, we're assuming deletion is successful):

(async () => { if (await lblib.confirm('Really delete this item?', 1)) { await fetch('delete.php?item=something'); lblib.alert('Deleted!'); } })();

Loading progress indicators 🔗

Lightbox Lib can be used to show loading progress indicators - either infinite loading (i.e. the amount of time remaining is indeterminate, in which case an animated, barbershop-style pole shows) or finite (a known percentage remains).

See example 3 for an indeterminate time loading indicator. For a finite indicator, we simply pass an integer to the first parameter. This can be useful, for example, for progress events used with AJAX:

//prep our upload - @file is a selection from a input[type=file] let req = new XMLHttpRequest(), fd = new FormData(); fd.append('file', file); req.open('POST', 'uploader.php'); //on AJAX progress updates, set our loading indicator req.upload.addEventListener('progress', evt => { let pct = e.loaded / e.total * 100; lblib.loading(pct, 'Uploading - sit tight...'); }, false); //begin upload req.send(fd);

Then once it's done we can show a "loading complete" indicator (via the third param - see API)- a green tick, which auto-disappears:

req.onload = () => lblib.loading(0, 0, true);

Carousel usage 🔗

Lightbox Lib can be used as a basic carousel, for example to cycle through photos of a product on an e-commerce website.

To invoke this, simply invoke the lightbox on a parent element which contains the slides for the carousel (e.g. the photos) and additionally pass carousel: true to the params object. This will cause each child element within the container to be shown one at a time, starting with the first child being visible.

See Example 4 for a demonstration of this.

Next/previous navigation buttons are automatically provided when in carousel mode to cycle through the elements.

Lightbox closure 🔗

There are three causes of lightbox closure:

  • Triggered - via a user action (see below)
  • Auto - where the lightbox is configured with autoDisappear to auto disappear after a period of time
  • Manual - programmatically via lblib.hide()

Closure can always be suppressed by passing the noClose parameter which can be passed as part of the params argument to any of lightbox(), modal() and fetch().

Triggered closure comes when one of the following happens:

  • The user clicks a HTML button inside the lightbox, or any element with the class close
  • The user clicks the lightbox itself (if the global config allows this)
  • The user presses the escape key (if the global config allows this)
  • The user clicks the auto-generated close button that sits at the top of the lightbox (not present if the lightbox was configured with autoDisappear or noClose).

You can prevent buttons from closing the lightbox by giving them the class noClose or, for modals, passing noClose: true in the button's config. See Modals.

With loading progress indicators, it's best to close the lightbox with an indication as to whether the operation succeeded or failed. Lightbox Lib can automatically generate such indications - see Loading progress indicators.

It's possible to listen for lightbox closure by registering a callback function at lblib.onClose. When called, it will be passed three arguments:

  • evt (obj) - the DOM event that caused closure, if any
  • usage (str) - a string denoting the method that was called to invoke the lightbox before closure, i.e. "lightbox", "modal", "fetch" or "loading" or, if carousel mode, "carousel".
  • el (obj) - a reference to the HTML element that was being shown

Absent files 🔗

As shown in example 5, Lightbox Lib can fetch and showcase resources not present in the local DOM. These are termed absent files, and come in two forms:

  • Images
  • Pages (displayed via iframe)

Both cases are initiated via the lblib.absentFile() function (see API).

For images, the image will be preloaded. Until this completes, an infinite, barberpole-style loading progress indicator will show.

Download Download from Github

Did I help you? Feel free to be amazing and buy me a coffee on Ko-fi!