Dialogs
Basic support for dialogs forms part of the JsPlumb 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 JsPlumb's demo pages - 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
Cancelbutton 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 JsPlumb's internal template engine 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>