Introduction
When developing a planimeter application on my VeeTools website, there was the need for a modal user input box setting the scale for a certain map image. Modal windows in an HTML application are familiar (for example, see How TO - CSS/JS Modal, but I missed the .NET MsgBox()
functionality with the ability to Ok
, Apply
or Cancel
and to get an input value from the user. I decided to make a small module which can be inserted in any existing JavaScript namespace.
The Basics...
In the source code, you will find three files: dialogbox.html, dialogbox.js and dialogbox.css. I will not discuss the dialogbox.css here (you can alter the style of the dialogs to your own liking) apart from pointing out that it makes use of flex panels I describe in an earlier tip/trick: Pure HTML/CSS/JS Panel and Splitcontainer in .NET style.
Example 1
The dialogbox.html file contains a simple interface to test out the dialog box and some of the options. The HTML part is a straightforward collections of input
and select
elements. The button
at the bottom calls the function cbGetDialog()
in the <script>
part of the HTML
code snippet below. This function collects all the user inputs and calls dialog.msgBoxGet()
from the module to build and return the dialog. Subsequently, the returned dialog is run with module function dialog.msgBoxShow()
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="UTF-8">
<title>VeeTools DialogBox</title>
<!--
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<!--
<script src="./dialogbox.js"></script>
<link rel="stylesheet" href="./dialogbox.css" type="text/css">
</head>
<body>
<div class="" style="">
<div><label>DialogBox title:</label><input id="title"
value="Hello" placeholder="dialog title..."
style="position:absolute;left:150px;width:200px;">
</input></div><br>
<div><label>DialogBox message:</label><input id="msg" value="World<br>
The dialog.msgBox in its simplest form..." placeholder="dialog message..."
style="position:absolute;left:150px;width:200px;"></input></div><br>
<!--
<div><button onclick="cbGetDialog()">Show dialog</button></div>
</div>
</body>
<script>
function cbGetDialog(){
var ttl = document.getElementById("title").value
var msg = document.getElementById("msg").value
var dlg = mymod.dialog.msgBoxGet(ttl,msg)
mymod.dialog.msgBoxShow(dlg)
}
</script>
</html>
Example 2
So far, nothing too difficult. Let's turn the simple message dialog into a user input dialog by changing the following options: dlgStyle
, dlgButtons
, dlgOkLabel
, dlgInputBox
and dlgInputBoxCallback
, shown in the figure below:
In the second example, the <script>
part of the file dialogbox.html will look like this:
<script>
function cbGetDialog(){
var ttl = document.getElementById("title").value
var msg = document.getElementById("msg").value
var stl = document.getElementById("optstyle").value
var bts = document.getElementById("optbuts").value
var labok = document.getElementById("labbutok").value
var inpfield = document.getElementById("chkinputfield").checked
var inpcb = document.getElementById("cbinputfield").value
if (!inpcb || inpcb=="") inpcb = null
var dlg = mymod.dialog.msgBoxGet(ttl,msg,{
dlgStyle:stl,
dlgButtons:bts,
dlgOkLabel:labok,
dlgInputBox: inpfield,
dlgInputBoxCallback: window[inpcb],
})
mymod.dialog.msgBoxShow(dlg)
}
function cbInputValue(val){
var dlg = mymod.dialog.msgBoxGet("Input result","Input value returned="+val)
mymod.dialog.msgBoxShow(dlg)
}
</script>
Note that the callback processing the user input is specified in cbinputfield
element and named cbInputValue
which should correspond to an existing function. In this case, the function is defined in the HTML
file <script>
part and therefore the callback is passed as a property of the window by dlgInputBoxCallback: window[document.getElementById("cbinputfield").value]
. This is not the most elegant way by using the global stack, but used here for practical purposes. A more proper way inside a namespace
would be dlgInputBoxCallback: mymod.myfunction
. The callback function cbInputValue
in turn creates a new (simple) dialog box returning the value the user has entered.
Example 3
The third example is overriding the default actions of the dialog box. By changing the <script>
part of the file dialogbox.html to the following:
<script>
function cbGetDialog(){
var dlg = mymod.dialog.msgBoxGet("A nice app","Go on with this?",{
dlgStyle:"question",
dlgButtons:"okcancel",
dlgCallbackOk:function(){cbGetDialogResult(true)},
dlgCallbackCancel:function(){cbGetDialogResult(false)},
dlgOkLabel:"Yes",
dlgCancelLabel:"Stop!",
dlgInputBox: false,
})
mymod.dialog.msgBoxShow(dlg)
}
function cbGetDialogResult(val){
var dlg = mymod.dialog.msgBoxGet("A nice app","GoOn="+val)
mymod.dialog.msgBoxShow(dlg)
}
</script>
The resulting dialog box from function cbGetDialogResult
will either show true
or false
depending on the button pushed:
Note that in the above example, I can simply define an anonymous function(){cbGetDialogResult()}
for the callback functions since their names are not a var
.
Example 4
The last example shows how a user element can be added to the dialog box. As an example, I will add the image (included in the source code): amsterdam_1836.jpg. The <script>
part of the file dialogbox.html looks like this:
<script>
function cbGetDialog(){
var dvi = document.createElement("div")
var img = document.createElement("img")
img.setAttribute("src","./amsterdam_1836.jpg")
img.setAttribute("width","100%")
img.setAttribute("height","100%")
dvi.onclick = function(){var dlg = mymod.dialog.msgBoxGet("That's All","Folks");
mymod.dialog.msgBoxShow(dlg)}
dvi.appendChild(img)
var dlg = mymod.dialog.msgBoxGet("A nice image","Of Amsterdam in 1836",{
dlgCustElement:dvi
})
mymod.dialog.msgBoxShow(dlg)
}
</script>
The result is shown below. If you click on the image, you'll get yet another dialog box (see the dvi.onclick
).
And the Details...
The dialog module simply extends any existing JavaScript module (called mymod
in this example) and creates a dialog
namespace
. The module exposes only two public
functions (see source code file dialogbox.js). For the contents of the local functions, refer to the source code.
'use strict';
var mymod = mymod || {};
mymod.dialog = (function() {
var _exposed = {
msgBoxGet: msgbxGet,
msgBoxShow: msgbxShow,
}
function msgbxGet(title,msg,options) {...}
function msgbxShow(msgbox) {...}
function getIcon(dlgstl){...}
function getDialogButton(txt,tbindx,lab){...}
function splitMsg(msg){...}
function oninputKeydown(e,clb,dlg){...}
function ondlgKeydown(e,okclb,dlg){...}
function setElmStyle(elm,props) {...}
return _exposed;
})(mymod.dialog || {});
Functions Reference and Usage
Function msgBoxGet()
constructs a dialogbox
with a title and a message and optionally sets dialog style and function parameters. The function returns an HTML
element.
Syntax | <mod_name>.dialog.msgBoxGet(title, message, {options}) |
Return | HTML element |
Arguments | Type | Description |
title | String | Title of the dialog |
message | String | The message displayed. The message is split up into paragraphs based on the occurrence of '\n ' character or the <br> tag |
options | Object | See below |
Options | Type | Description |
dlgStyle | String | Style of the dialogbox. Can be any of info , exclamation , warning , question , error or none . The dlgStyle also sets the font-awsome icon to use for the dialog. |
dlgButtons | String | Buttons to show. Can be any of ok , okcancel , okapplycancel . |
dlgCallbackOk | Function | Function to call when the Ok button is clicked. Default action closes the dialog. Any supplied function is executed before the default action. Can be null . |
dlgCallbackApply | Function | Function to call when the Apply button is clicked. Default action is null . Can be null . |
dlgCallbackCancel | Function | Function to call when the Cancel button is clicked. Default action closes the dialog. Any supplied function is executed before the default action. Can be null . |
dlgOkLabel | String | Overriding Ok button label. |
dlgApplyLabel | String | Overriding Apply button label. |
dlgCancelLabel | String | Overriding Cancel button label. |
dlgInputBox | Boolean | When true shows an input value box. The input value is passed to the dlgInputBoxCallback . |
dlgInputBoxCallback | Function | Function to call when input value is returned (by either Ok or Return). This function overrides any function specified for dlgCallbackOk or dlgCallbackApply . |
dlgCustElement | HTML element | Custom user element to be added after the message (and input box if checked). Element should include its own style and callbacks. |
Function msgBoxShow()
shows a previously constructed dialog box while preventing the main app from receiving input (keyboard, mouse events, etc.):
Syntax | <mod_name>.dialog.msgBoxShow(dlgBox) |
Return | true/false |
Arguments | Type | Description |
dlgBox | HTML element | A dialog box created by msgBoxGet() |
History
- October 2017: First published