modal#
Browser dialogs that load server-rendered HTML, with layouts for modals and nested prompts.
Install#
Install in a NodeDK application and copy the layouts and assets:
npm i @nodedk/modal
mkdir -p app/assets/js app/assets/css app/assets/img app/layouts
cp node_modules/@nodedk/modal/build/assets/js/*.js app/assets/js/
cp node_modules/@nodedk/modal/build/assets/css/*.css app/assets/css/
cp node_modules/@nodedk/modal/build/assets/img/* app/assets/img/
cp node_modules/@nodedk/modal/build/layouts/*.js app/layouts/
Add these entries to the application’s existing bundle configuration:
// app/config/bundle.js
module.exports = {
css: ['/css/modal.css', '/css/prompt.css'],
js: ['/js/modal.js']
}
Load bundles with state.style(['/bundle.css']) and
state.script(['/bundle.js']) in the main layout. Add empty containers near
the end of its body:
<div class="modal" style="display: none"></div>
<div class="prompt" style="display: none"></div>
Usage#
Register routes that return modal and prompt content:
// app/config/routes.js
var { html } = require('@nodedk/page')
var Modal = require('../layouts/modal.js')
var Prompt = require('../layouts/prompt.js')
module.exports = [
{
name: 'modal',
methods: 'GET',
paths: '/modal',
handler: async function (state) {
return Modal(state, { title: 'Account' }, [
html`<p>Account settings.</p>
<button
onclick="window.openModal(this)"
data-modal=".prompt"
data-href="/prompt"
>
Confirm changes
</button>`
])
}
},
{
name: 'prompt',
methods: 'GET',
paths: '/prompt',
handler: async function (state) {
return Prompt(state, { title: 'Confirm' }, [
html`<p>Save your changes?</p>`
])
}
}
]
Open a dialog from a link or button:
<a
href="/modal"
data-modal=".modal"
onclick="
openModal(this)
return false
"
>
Account settings
</a>
<button
onclick="openModal(this)"
data-modal=".modal"
data-href="/modal"
data-title="Edit account"
>
Edit account
</button>
openModal(trigger, callback)#
Returns a Promise with no value. trigger is an element or a selector for
one. callback() is optional and runs after content loads; its return value
is not awaited.
Trigger attributes:
data-modal: target selector; defaults to.modal.data-hreforhref: URL whose HTML replaces the dialog contents. Without a URL, opens the existing contents.data-title: HTML that replaces.modal-titleafter loading.
The helper marks the dialog with .modal-current, adds .modal-open to the
body, and runs inline scripts in the loaded content. Use trusted HTML.
closeModal(target, options = {})#
Hides and empties the dialog. target is its selector or a trigger element
with data-modal; the element form defaults to .modal. The helper returns
no value.
options.scroll: false keeps the body’s modal state and scroll position,
which is useful when closing a prompt over an open modal.
closeModal('.prompt', { scroll: false })
closeModal('.modal')
Layouts#
Modal(state, props = {}, slot = []) and
Prompt(state, props = {}, slot = []) return HTML strings.
state: application state, accepted for the NodeDK layout convention.props.title: title text, default''; escaped by the layout.props.type: additional frame classes, default''.slot: array of rendered HTML strings, joined with newlines.
Development#
npm run build
Copies assets and layouts into build. Packaging runs this build automatically.
Created by Vidar Eldøy