Beispiel:JS-dialog-ersatz-fuer-alert-confirm-prompt.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!DOCTYPE html>
<html lang="de">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0;" />
		<link rel="stylesheet" type="text/css" media="screen" href="./Beispiel:SELFHTML-Beispiel-Grundlayout.css" />
		<title>Ersatz-Dialoge für alert(), confirm() und prompt()</title>
		<style>
/* Darstellungen für die Dialog-Box */

dialog {
    background: white;
    border: 1px solid grey;
	border-radius: 0 .5em .5em;
	box-shadow: 0 0 15px 5px #888;
	display: none;
	height: auto;
	padding: .5em 1em;
	position: relative;
	width: 100%;
	z-index:1002;
}

dialog[open] {
    display: block;
}

@media (min-width: 30em) {
  dialog {
	position: absolute;
	top: 50%;
	margin-top: -10em;
	left: 50%;
	margin-left: -10em;
	width: 20em;
  }
}

/* Ebene zwischen Hintergrund und Dialog-Box, Pseudoelement noch nicht implementiert */
dialog::backdrop, #backdrop {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.8);
}

dialog .button-row {
	text-align: center;
}

dialog .close {
	position: absolute;
	right: 3px;
	top: 1px;
	height: 2em;
    cursor: pointer;
    background-color: red;
    color: white;
	font-weight: bold;
	font-size: 1.5em;
	border-radius: 0 .5em .5em;
}

dialog [name="ok"] {
	background: #0b0;
	border-radius: 0 .5em .5em;
	color: white;
	font-weight: bold;
	font-size: 1.5em;
}

dialog [name="cancel"] {
	background: #f00;
	border-radius: 0 .5em .5em;
	color: white;
	font-weight: bold;
	font-size: 1.5em;
}

/* Darstellungen für die Demo-Seite */

.js #js-notice,
:not(.js) > section {
	display: none;
}

output {
	border: 2px solid #888;
	border-radius: 0.5em;
	font-weight: bold;
	margin-left: 0.5em;
	padding: 0.2em 1em;
}

output.false {
	border-color: red;
}

output.ok {
	border-color: #0b0;
}
			</style>
		<script>
'use strict';
document.addEventListener("DOMContentLoaded", function () {

	// Polyfill für Browser, die das dialog-Element nicht komplett unterstützen
	(function () {
		var backdrop;

		Array.prototype.slice.call(
			document.querySelectorAll("dialog")
		).forEach(function (dialog) {
			var callBacks = {
					cancel: function () {},
					ok: function () {}
				},
				close = dialog.querySelector(".close");

			if (!dialog.close) {
				dialog.close = function () {

					if (dialog.hasAttribute("open")) {
						dialog.removeAttribute("open");
					}

					if (backdrop && backdrop.parentNode) {
						backdrop.parentNode.removeChild(backdrop);
					}
				}
			}

			if (!dialog.show) {
				dialog.show = function () {
					var closeButton = dialog.querySelector(".close");

					dialog.setAttribute("open", "open");

					// after displaying the dialog, focus the closeButton inside it
					if (closeButton) {
						closeButton.focus();
					}

					if (!backdrop) {
						backdrop = document.createElement("div");
						backdrop.id = "backdrop";
					}

					document.body.appendChild(backdrop);
				}
			}

			dialog.setCallback = function (key, f) {
				callBacks[key] = f;
			};

			dialog.triggerCallback = function (key) {
				if (typeof callBacks[key] == "function") {
					callBacks[key]();
				}
			};

			if (close) {
				close.addEventListener("click", function () {
					dialog.close();
					dialog.triggerCallback("cancel");
				});
			}

			// handle buttons for user input
			["cancel", "ok"].forEach(function (n) {
				var button = dialog.querySelector('[name="'+n+'"]');

				if (button) {
					button.addEventListener("click", function () {
						dialog.close();
						dialog.triggerCallback(n);
					});
				}
			});
		});

		// ESC and ENTER closes open dialog and triggers corresponding callback
		document.addEventListener(
			"keydown",
			function (event) {
				Array.prototype.slice.call(
					document.querySelectorAll("dialog")
				).forEach(function(dialog) {

					if (dialog.hasAttribute("open")) {

						// ENTER
						if (event.keyCode == 13) {
							dialog.close();

							setTimeout(function () {
								dialog.triggerCallback("ok");
							}, 50);
						}

						// ESC
						if (event.keyCode == 27) {
							dialog.close();

							setTimeout(function () {
								dialog.triggerCallback("cancel");
							}, 50);
						}
					}
				});
			},
			true
		);
	}());

	// Darstellung mit "JavaScript vorhanden" aktivieren
	document.querySelector("body main").className = "js";

	// die Ersatz-Methoden
	window.myAlert = function (text, OK, cancel) {
		var dialog = document.querySelector("#alert"),
			textElement = document.querySelector("#alert [data-text]");

		if (dialog && textElement) {
			textElement.innerText = (text && text.length ? text : "");
			dialog.setCallback("cancel", cancel);
			dialog.setCallback("ok", OK);
			dialog.show();
		}
	}

	window.myConfirm = function (text, OK, cancel) {
		var dialog = document.querySelector("#confirm"),
			textElement = document.querySelector("#confirm [data-text]");

		if (dialog && textElement) {
			textElement.innerText = (text && text.length ? text : "");
			dialog.setCallback("cancel", cancel);
			dialog.setCallback("ok", OK);
			dialog.show();
		}
	}

	window.myPrompt = function (text, OK, cancel, defaultValue) {
		var dialog = document.querySelector("#prompt"),
			inputElement = document.querySelector('#prompt [name="data"]'),
			textElement = document.querySelector("#prompt [data-text]");

		if (dialog && textElement) {

			inputElement.value = (defaultValue && defaultValue.length ? defaultValue : "");
			textElement.innerText = (text && text.length ? text : "");
			dialog.setCallback("cancel", cancel);
			dialog.setCallback("ok", function () {
				OK(inputElement.value);
			});
			dialog.show();
		}
	}

	// Demo: alle Buttons mit Funktionalität ausrüsten
	Array.prototype.slice.call(
		document.querySelectorAll("section")
	).forEach(function(section) {
		var button = section.querySelector("[data-js]"),
			output = section.querySelector("output");

		if (button) {

			button.addEventListener("click", function () {

				switch (button.dataset.js) {

					case "alert":
						myAlert("Dieses Fenster können Sie bedenkenlos wieder schließen.");
					break;

					case "confirm":
						myConfirm(
							"Sind Sie mit SELFHTML zufrieden?",
							function () {
								output.className = "ok";
								output.value = "ok";
							},
							function () {
								output.className = "false";
								output.value = "false";
							}
						);
					break;

					case "prompt":
						myPrompt(
							"Was möchten Sie uns sagen?",
							function (result) {
								output.className = "ok";
								output.value = '"' + result + '"';
							},
							function () {
								output.className = "false";
								output.value = "false";
							}
						);
					break;
				}
			});
		}
	});
});
		</script>
	</head>
	<body>
		<h1>Ersatz-Dialoge für alert(), confirm() und prompt()</h1>
		<main>
			<p id="js-notice">Für diese Beispiele muss JavaScript verfügbar sein.</p>
			<section>
				<h2>Alert-Fenster</h2>
				<p><button data-js="alert">myAlert()</button></p>
			</section>
			<section>
				<h2>Confirm-Fenster</h2>
				<p>
					<button data-js="confirm">myConfirm()</button>
					Ergebnis:
					<output></output>
				</p>
			</section>
			<section>
				<h2>Prompt-Fenster</h2>
				<p>
					<button data-js="prompt">myPrompt()</button>
					Ergebnis:
					<output></output>
				</p>
			</section>
		</main>
		<dialog id="alert" role="dialog" aria-labelledby="alert-dialog-heading">
			<button class="close">Schließen</button>
			<h2 id="alert-dialog-heading">Hinweis</h2>
			<p data-text></p>
			<p class="button-row">
				<button name="ok">OK</button>
			</p>
		</dialog>
		<dialog id="confirm" role="dialog" aria-labelledby="confirm-dialog-heading">
			<button class="close">Schließen</button>
			<h2 id="confirm-dialog-heading">Frage</h2>
			<p data-text></p>
			<p class="button-row">
				<button name="ok">OK</button>
				<button name="cancel">Abbrechen</button>
			</p>
		</dialog>
		<dialog id="prompt" role="dialog" aria-labelledby="prompt-dialog-heading">
			<button class="close">Schließen</button>
			<h2 id="prompt-dialog-heading">Eingabe</h2>
			<p>
				<label data-text for="prompt-data"></label>
				<input id="prompt-data" name="data">
			</p>
			<p class="button-row">
				<button name="ok">OK</button>
				<button name="cancel">Abbrechen</button>
			</p>
		</dialog>
	</body>
</html>