Enhancement

SelectLoader

Load an HTML fragment into a target when a select's choice changes

Import
@parallelogram-js/core/components/SelectLoader
Selector
[data-selectloader]

Playground

Menu picker

Choose another menu, then Reset puts back and loads the breakfast menu.

<form class="form" action="#menu">
  <div class="form__group">
    <label class="form__label" for="menu-choice">Menu</label>
    <div class="form__control">
      <select id="menu-choice" data-selectloader data-selectloader-target="#menu-panel">
        <option value="">Choose a menu</option>
        <option value="fragments/breakfast.html" selected>Breakfast</option>
        <option value="fragments/lunch.html">Lunch</option>
        <option value="fragments/missing.html">A menu that fails to load</option>
      </select>
    </div>
  </div>
  <div class="form__actions">
    <button type="reset">Reset</button>
  </div>
</form>
<div id="menu-panel" class="panel"></div>

About

Each option's value is the URL of a fragment, fetched through RouterManager, so the page needs the framework's router. A choice made before the router has loaded, including one selected in the page's HTML, waits for it to start. A newer choice cancels a load that is still running, the target is marked aria-busy while loading, and the loaded content is announced.

Fragments are inserted as HTML, through the parallelogram policy on pages that enforce Trusted Types, so they must come from a trusted, same-origin source; sanitise anything else first, for example with DOMPurify.

Usage

Register the component and the framework loads it the first time a page contains [data-selectloader].

import { Parallelogram } from '@parallelogram-js/core';

const app = Parallelogram.create();
app.components.add('[data-selectloader]', () => import('@parallelogram-js/core/components/SelectLoader'));
app.run();

Attributes

NameTypeDefaultDescription
data-selectloaderflagnoneMarks the select On a <select>.
data-selectloader-targetselectornoneThe element that receives the content
data-selectloader-target-viewstringnoneThe target's data-view name, instead of a selector
data-selectloader-transitionfade | slide | nonefadeHow new content appears; skipped under reduced motion For every instance, SelectLoader.defaults.transition.
data-selectloader-transition-durationnumber300Length of the transition in milliseconds For every instance, SelectLoader.defaults.transitionDuration.
data-selectloader-retain-scrollbooleanfalseKeep the target's scroll position For every instance, SelectLoader.defaults.retainScroll.
data-selectloader-empty-messagestringPlease select an optionText shown when nothing is chosen For every instance, SelectLoader.defaults.emptyMessage.
data-selectloader-error-messagestringFailed to load contentShown when a fragment fails to load and the error carries no message of its own For every instance, SelectLoader.defaults.errorMessage.
data-selectloader-retry-labelstringRetryThe button beside that message, which loads the same choice again For every instance, SelectLoader.defaults.retryLabel.
data-selectloader-loading-classstringloadingClass on the target while loading For every instance, SelectLoader.defaults.loadingClass.
data-selectloader-error-classstringerrorClass on the target after a failed load For every instance, SelectLoader.defaults.errorClass.

Methods

NameSignatureDescription
load(element: HTMLSelectElement, url: string) => voidChoose a URL and load its fragment
reload(element: HTMLSelectElement) => voidLoad the current choice again
clear(element: HTMLSelectElement) => voidChoose nothing, cancel a running load and show the empty message
getLoadState(element: HTMLSelectElement) => { isLoading: boolean; currentUrl: string | null; hasContent: boolean; hasError: boolean } | nullWhether a load is running, the current URL, and whether the target has content or an error

Events

NameDetailDescription
selectloader:before-change{ value: string; previousUrl: string | null; targetElement: HTMLElement }The choice is about to load; cancelling puts the previous choice back DOM event and event bus Cancelable.
selectloader:cleared{ targetElement: HTMLElement }The empty choice was selected DOM event and event bus
selectloader:loading{ url: string; targetElement: HTMLElement }A fragment started loading DOM event and event bus
selectloader:loaded{ url: string; targetElement: HTMLElement; html: string }A fragment was inserted DOM event and event bus
selectloader:error{ url: string; error: Error; targetElement: HTMLElement }A fragment failed to load DOM event and event bus
selectloader:complete{ url: string; success: boolean }A load finished, successfully or not DOM event and event bus
selectloader:content-loaded{ element: HTMLSelectElement; url: string; targetElement: HTMLElement }A fragment was inserted Event bus
app:notification{ type: 'error'; message: string; duration: number }A message for the page to show when a load fails Event bus