dialog from js

Basic proof of concept for a dialog created in javascript and then how to handle results from dialog. Also showcase some more advanced usage and some pitfalls.

by Laurens Maneschijn

HTML

Basic proof of concept for a dialog created in javascript and then how to handle results from dialog.<br>
Also showcase some more advanced usage and some pitfalls.
<hr>

<button onclick="showDialog();">showDialog()</button> Open a dialog; reopens previous one if any.<br>
<button onclick="showNewDialog();">showNewDialog()</button> Create a new one.<br>

<div id="result">
	<h2>dialog form submit result:</h2>
	dialog.returnValue = <code id="result_returnvalue"></code><br>
	<br>
	FormData to simple object to json:
	<pre id="result_json"></pre>
</div>

<hr>
links:<br>
<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog">MDN dialog</a><br>
<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/returnValue">MDN dialog.returnValue</a><br>
<a target="_blank" href="https://jsfiddle.net/ElMoonLite/pjn8btqm/">jsfiddle multiple dialogs experiment</a><br>
<a target="_blank" href="https://codepen.io/geckotang/post/dialog-with-animation">fancy dialog css with animation</a><br>

CSS

h1,h2,h3,h4,h5,h6 {
	font-size: 100%;
}
pre {
	tab-size: 2;
}
#result {
	display: none;
	margin: 2px;
	padding: 2px;
	border: 1px solid #888;
}
#result_returnvalue ,
#result_json {
	background: #8884;
}

/* Use these to style the dialog:
dialog {}
dialog:modal {}
dialog[open] {}
dialog::backdrop {}
*/

dialog {
	background: #eef;
    border: 3px solid #008;
    border-radius: 5px;
    padding: 5px;
    box-shadow: 2px 2px 5px 5px #2282;
}
dialog::backdrop {
	background: #0004;
	backdrop-filter: blur(1px);
}

JavaScript

var dialog;
function showDialog() {
	if(!dialog) {
		dialog = createDialog();
		document.body.appendChild(dialog); // add to DOM
	}
	// NB: make sure to initialize dialog.returnValue before showing it,
	// to prevent confusion when reusing a dialog.
	// (see further below at if ( dialog.returnValue === "ok") {...} )
	// Note dialog.returnValue can only be a string. (e.g. setting to null will become 'null').
	dialog.returnValue = '';
	dialog.showModal();
}
function showNewDialog() {
	if (dialog) {
		dialog.remove(); // remove from DOM
		dialog = null;
	}
	showDialog();
}

function createDialog() {
	var dialog = document.createElement('dialog');
	var html = `
		<form method="dialog">
			Demo dialog<hr>
			<input type="text" name="mytext"><br>
			<select name="select1">
				${[null,1,2,3].map(v => `<option value="${v}">${v}</option>`).join('')}
			</select>
			<select multiple name="select2">
				<option>1</option>
				<option selected>2</option>
				<option selected>3</option>
			</select>
			<br>
			<input type="checkbox" name="checkbox_samename" value="1">
			<input type="checkbox" name="checkbox_samename" value="2" checked>
			<input type="checkbox" name="checkbox_samename" value="3" checked>
			<br>
			<input type="radio" name="radio" value="1">
			<input type="radio" name="radio" value="2">
			<input type="radio" name="radio" value="3">
			<br>
			<button type="submit" name="submitname" value="ok">ok</button>
			<button type="submit" name="submitname" value="cancel">cancel</button>
		</form>
`;
	dialog.innerHTML = html;
	// document.body.appendChild(dialog);
	// dialog.showModal();

	// Optional: Close dialog if clicking outside it:
	document.addEventListener('click', (event) => {
		if (event.target.contains(dialog)) {
			dialog.close();
		}
	});

	dialog.addEventListener('close', (e) => {
		// dialog.remove(); // remove from DOM, if not reusing it.

		console.log('dialog close event', e);
		console.log('dialog element:', dialog);

		//...