Dialogs
Basic support for dialogs forms part of the Toolkit core. These dialogs provide a simple abstraction around the business of getting input from the user and dealing with it. They're not necessarily fully-featured enough for all applications - they were built for the demo pages in the Toolkit - but they do provide a reasonable amount of functionality for very little effort.
Initialization
You can initialize the dialogs in one of two ways:
With a dialogs map
import { Dialogs } from "@jsplumbtoolkit/browser-ui"
const dialogs = new Dialogs({
dialogs:{
editor:{
title:"Node Editor",
template:`<div><input jtk-att="name" jtk-focus placeholder="Node name"/></div>`,
cancelable:true
}
}
})
The arguments are:
- title Optional title for the dialog
- template Required. The HTML to use in the dialog. See discussion below.
- cancelable Optional. If true, a
Cancel
button is added to the dialog.
With a selector
Instead of supplying a map of dialogs, you can serve up the dialogs in your HTML and target them with a selector:
<script type="jtk-dialog" id="editor" title="Node Editor" cancelable="true">
<div>
<input jtk-att="name" jtk-focus placeholder="Node name"/>
</div>
</script>
import { Dialogs } from "@jsplumbtoolkit/browser-ui"
const dialogs = new Dialogs({
selector:"[type='jtk-dialog']"
})
The dialogs code uses document.querySelectorAll
to retrieve matching elements.
Templates
Binding Parameters
These templates use the same template engine as the Surface renderer and support data binding of this form:
<div>{{name}}</div>
To bind parameters to input fields you use the jtk-att
attribute:
<div>
<input jtk-att="name" placeholder="node name"/>
</div>
The list of supported input types is:
- text inputs
- radio button(s)
- checkbox
- select
- textarea
- hidden inputs
- color inputs
Setting focus
You can set the focus on a field when the dialog opens via the jtk-focus
attribute:
<div>
<input jtk-att="name" placeholder="node name" type="text" jtk-focus/>
<input jtk-att="foo" placeholder="node foo" type="text"/>
<input jtk-att="color" type="color"/>
</div>
Showing a dialog
This example is the dialog that is shown when you edit a View query in the Database Visualizer. We provide the id of
the template to use for the dialog, and we provide the View node's data as the backing data for the dialog. Then we
provide an onOK
callback.
We register a tap
listener on the pencil icon in the upper right corner and then inside the event handler we find the
Toolkit object related to the clicked icon, then open a dialog to edit it.
const node = toolkit.getNode("someNode")
dialogs.show({
id:"editor",
data:node.data,
onOK:(data) => {
// update data
toolkit.updateNode(info.obj, data);
},
onCancel:() => {
console.log("cancelled")
}
});
onOK callback
The data
argument to the onOK
callback consists of an object whose key value pairs are determined by the jtk-att
attributes found in the template. Recall that above we had an input with jtk-att="name"
. This means that the data
argument to onOK
looks like this:
{
name:"the name of the node"
}
onCancel callback
If a given dialog is marked cancelable
, a cancel button will be shown on the dialog. When pressed, the onCancel
callback will be invoked,
if you provide one.
Dialog Positions
Dialogs may be positioned in one of four locations: top, bottom, left or right. In each location the dialog is centered
in the other axis, eg. for top
, the dialog is positioned at the top of the viewport and centered in the X axis.
The default position is top
. You can provide a position
parameter to the show
method to specify a different location:
dialogs.show({
id:"editor",
data:node.data,
position:"bottom"
});
The vast majority of the positioning of these dialogs is controlled through the CSS in jsplumbtoolkit-defaults.css
.
The only exception is the code that keeps the dialog centered in the minor axis when the viewport is resized. CSS
is discussed below.
Custom Button Labels
The default button labels are "OK" and "Cancel". This can be overridden with the labels
parameter on a show
method call:
dialogs.show({
id:"editor",
data:node.data,
position:"bottom",
labels:{
ok:"Yes",
cancel:"No"
}
});
Custom Buttons
You can provide your own buttons for use in a dialog, eg:
dialogs.show({
id:"editor",
buttons:[ button1, button2 ]
});
where button1
and button2
are DOM elements that each have a specific attribute set on them to indicate their function:
const button1 = document.createElement("button");
button1.innerHTML = "YES";
button1.setAttribute("jtk-commit", "true");
button1.className = "yourButtonClass";
const button2 = document.createElement("button");
button2.innerHTML = "NO";
button2.setAttribute("jtk-cancel", "true");
button2.className = "yourButtonClass";
The key things here are the jtk-commit
and jtk-cancel
attributes. When present, and set to "true"
, they indicate
the purpose of the button. Of course you can put anything you like in the array of buttons
; they do not need to have
jtk-**
attributes set on them, and they do not even need to be button
DOM elements.
The contents of buttons
will have been added to the dialog prior to the onOpen
callback being called, so you can
attach functionality to them inside there.
Custom clear button
There's one other attribute supported on custom buttons - jtk-clear-all
:
const button3 = document.createElement("button");
button3.innerHTML = "CLEAR";
button3.setAttribute("jtk-clear-all", "true");
button3.className = "yourButtonClass clearButton";
dialogs.show({
id:"editor",
buttons:[ button3, button1, button2]
});
Lifecycle Callbacks
There are five lifecycle callbacks supported:
- onOpen Called when the dialog has been opened. The related DOM element for the dialog is passed to this method.
- onMaybeClose Called prior to
onOK
, with the same data that will be passed toonOK
. If you return false from this, the dialog stays open. - onOK Called when the user presses OK. The callback is provided a data object as discussed above.
- onCancel Called when the user presses cancel. No arguments are provided to the callback.
- onClose Called when dialog has been closed, regardless of how it was closed. No arguments are provided to the callback.
Global Lifecycle Callbacks
In addition to providing callbacks to each show
call, you can register a callback for each of these four events
that will be called for every dialog show:
- onOpen
- onOK
- onCancel
- onClose
You provide these in a globals
argument to the initialize
method:
dialogs.initialize({
selector:".myDialog",
globals:{
onOpen:() => {
console.log("a dialog was opened")
},
onClose:() => {
console.log("a dialog was closed.")
}
}
})
Closing via Enter key
Text Input Elements
You can set the jtk-commit
attribute on any text input
elements that you'd like to have close (and persist) the dialog when the user presses the enter key:
<script type="jtk" class="dlg" id="dlgViewQuery" title="Edit Query">
<input type="text" class="txtViewQuery" jtk-focus jtk-att="query" jtk-commit="true"></input>
</script>
Textarea Elements
For textarea
elements you can also use the jtk-commit
attribute, but in this case you need to press ctrl+enter (or cmd+enter on a Mac) to close the dialog.
<script type="jtk" class="dlg" id="dlgViewQuery" title="Edit Query">
<textarea class="txtViewQuery" jtk-focus jtk-att="query" jtk-commit="true"></textarea>
</script>
CSS Classes
This is the full list of classes used by the dialog code. There are defaults for these declared in jsplumbtoolkit-defaults.css.
Class | Explanation |
---|---|
jtk-dialog-underlay | The element that acts as the modal "mask" |
jtk-dialog-overlay | The element that acts as the parent for dialog content |
jtk-dialog-overlay-visible | Assigned to an overlay when the dialog is visible |
jtk-dialog-overlay-x | Assigned to dialogs appearing in the `top` or `bottom` positions. |
jtk-dialog-overlay-y | Assigned to dialogs appearing in the `left` or `right` positions. |
jtk-dialog-overlay-top | Assigned to dialogs appearing in the `top` position |
jtk-dialog-overlay-bottom | Assigned to dialogs appearing in the `bottom` position |
jtk-dialog-overlay-left | Assigned to dialogs appearing in the `left` position |
jtk-dialog-overlay-right | Assigned to dialogs appearing in the `right` position. |
jtk-dialog-buttons | Button container element |
jtk-dialog-button | An individual button in a dialog |
jtk-dialog-title | The titlebar of a dialog |
jtk-dialog-content | The content of a dialog (does not contain the titlebar) |
The default CSS stylesheet also contains several rules such as hover states etc. You may wish to keep that in mind when you write your app-specific overrides.