Das wunderbare Bespiel unter selfhtml -> javascript -> tutoraials -> eigene modale Dialogfenster, dort unter "komplexere Dialogbox" wollte ich gern weiterverwenden. Mein Aufrufbutton soll aber zwischen <form> und </form> stehen. Dann blitzt die Dialogbox kurz auf und verschwindet wieder. Also, mit folgendem HTML-Code tritt diese Dysfunktionalität auf:
<main>
<form>
<p>Eine Dialog-Box mit mehreren Eingabefeldern als modales Fenster. <button>anzeigen</button>. </p>
<pre id="result"></pre>
<dialog id="my-dialog" role="dialog" aria-labelledby="my-dialog-heading">
<button class="close">Schließen</button>
<h2 id="my-dialog-heading">Eingabe</h2>
<p class="button-row">
<button name="ok">OK</button>
<button name="cancel">Abbrechen</button>
</p>
</dialog>
</form>
</main>
und wenn ich <form> und </form> lösche, dann wartet das modale Fenster wie gewünscht auf Eingaben. Kann mir jeman einen Tipp geben, wie es auch mit innerhalb von <form> gehen könnte?
Hier zur Vervollständigung der zugehörige Javascript-Code aus dem Tutorial:
'use strict';
document.addEventListener("DOMContentLoaded", function () {
var button = document.querySelector("main button");
// 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) {
var currentElement = event.target || event.soureElement,
prevent = (currentElement.tagName && currentElement.tagName.match(
/^button|input|select|textarea$/i));
Array.prototype.slice.call(document.querySelectorAll("dialog"))
.forEach(function (dialog) {
if (dialog.hasAttribute("open")) {
// ENTER
if (event.keyCode == 13 && !prevent) {
dialog.close();
setTimeout(function () {
dialog.triggerCallback("ok");
}, 50);
}
// ESC
if (event.keyCode == 27) {
dialog.close();
setTimeout(function () {
dialog.triggerCallback("cancel");
}, 50);
}
}
});
}, true);
}());
// komplexere Dialog-Box anzeigen
window.myDialog = function (data, OK, cancel) {
var dialog = document.querySelector("#my-dialog"),
buttonRow = document.querySelector("#my-dialog .button-row"),
heading = document.querySelector("#my-dialog-heading"),
element, p, prop;
if (dialog && buttonRow) {
// Standard-Titel
if (heading) {
heading.textContent = "Eingabe";
}
// jedes <ul> und <p> entfernen, außer <p class="button-row">
Array.prototype.slice.call(dialog.querySelectorAll(
"ul, p:not(.button-row)"))
.forEach(function (p) {
p.parentNode.removeChild(p);
});
// Elemente erstellen und gegebenenfalls mit Inhalten befüllen
for (prop in data) {
// alles bekommt ein <p> drumherum
p = document.createElement("p");
buttonRow.parentNode.insertBefore(p, buttonRow);
// simple Textausgabe
if (data[prop].type && data[prop].type == "info") {
p.textContent = data[prop].text;
}
// anderer Titel
if (data[prop].type && data[prop].type == "title" && heading) {
heading.textContent = data[prop].text;
// neues <p> wird hierfür nicht benötigt
p.parentNode.removeChild(p);
}
// numerischer Wert
if (data[prop].type && data[prop].type == "number") {
// <label> als Kindelement für Beschriftung
p.appendChild(document.createElement("label"));
p.lastChild.appendChild(document.createTextNode(data[prop].text + " "));
// <input type="number">
element = p.appendChild(document.createElement("input"));
if (data[prop].hasOwnProperty("max")) {
element.max = data[prop]["max"];
}
if (data[prop].hasOwnProperty("min")) {
element.min = data[prop]["min"];
}
if (data[prop].hasOwnProperty("step")) {
element.step = data[prop]["step"];
}
element.name = prop;
element.type = "number";
element.value = element.min = data[prop]["min"] || 0;
if (data[prop].default) {
element.value = data[prop].default;
}
}
// Mehrfachauswahl
if (data[prop].type && data[prop].type == "multiple") {
p.textContent = data[prop].text;
// alle Optionen wandern in ein <ul>
element = document.createElement("ul");
buttonRow.parentNode.insertBefore(element, buttonRow);
data[prop].options.forEach(function (d, index) {
var input = document.createElement("input"),
label = document.createElement("label"),
li = document.createElement("li");
// <li> in <ul> einhängen
element.appendChild(li);
input.id = prop + "-" + index;
input.name = prop + "-" + index;
input.type = "checkbox";
input.value = d;
li.appendChild(input);
label.htmlFor = prop + "-" + index;
label.textContent = " " + d
li.appendChild(label);
if (data[prop].default && data[prop].default == d) {
input.setAttribute("checked", "checked");
}
});
}
// Einfachauswahl
if (data[prop].type && data[prop].type == "select") {
// <label> als Kindelement für Beschriftung
p.appendChild(document.createElement("label"));
p.lastChild.appendChild(document.createTextNode(data[prop].text + " "));
// alle Optionen wandern in ein <ul>
element = p.appendChild(document.createElement("select"));
element.name = prop;
data[prop].options.forEach(function (d) {
var o = document.createElement("option");
o.textContent = d;
o.value = d;
element.appendChild(o);
if (data[prop].default && data[prop].default == d) {
o.setAttribute("selected", "selected");
}
});
}
// Texteingabe
if (data[prop].type && data[prop].type == "text") {
// <label> als Kindelement für Beschriftung
p.appendChild(document.createElement("label"));
p.lastChild.appendChild(document.createTextNode(data[prop].text));
// alle Optionen wandern in ein <ul>
element = p.appendChild(document.createElement("textarea"));
element.name = prop;
if (data[prop].default) {
element.textContent = data[prop].default;
}
}
}
dialog.setCallback("cancel", cancel);
dialog.setCallback("ok", function () {
var result = {},
elements;
// Ergebnisse ermitteln
for (prop in data) {
elements = Array.prototype.slice.call(dialog.querySelectorAll(
'[name^="' + prop + '"]'));
if (data[prop].type && data[prop].type == "multiple") {
result[prop] = [];
elements.forEach(function (element) {
if (element.checked) {
result[prop].push(element.value);
}
});
} else {
if (data[prop].type != "title" && data[prop].type != "info") {
result[prop] = null;
if (elements[0]) {
result[prop] = elements[0].value;
}
}
}
}
// Ergebnisse an die Callback-Funktion zurück geben
OK(result);
});
dialog.show();
}
}
// anzeigen-Button aktivieren
if (button) {
button.addEventListener("click", function () {
myDialog(
// data
{
instructions: {
text: "Bitte seien Sie jetzt komplett ehrlich und füllen Sie wahrheitsgemäß alles aus!",
type: "info"
},
title: {
text: "Sonderabfrage",
type: "title"
},
sex: {
"default": "weiblich",
options: ["männlich", "weiblich"],
text: "Geschlecht",
type: "select"
},
age: {
"default": 18,
"max": 150,
"min": 0,
step: 1,
text: "Alter",
type: "number"
},
preferences: {
"default": "Pop",
options: ["Jazz", "Swing", "Latin", "Klassik", "Hiphop", "Pop"],
text: "Diese Musik mag ich gerne",
type: "multiple"
},
message: {
text: "Das will ich mitteilen",
type: "text"
}
},
// OK
function (data) {
var output = document.querySelector("main pre"),
prop,
result = "Ergebnis:\r\n=========\r\n\r\n";
for (prop in data) {
result += prop + ":";
if (typeof data[prop] == "object") {
data[prop].forEach(function (value, index) {
result += (index ? "," : "") + "\r\n\t" + value;
});
} else {
result += " " + data[prop];
}
result += "\r\n";
}
if (output) {
output.textContent = result;
}
},
// cancel
function () {
var output = document.querySelector("main pre");
if (output) {
output.textContent = "(kein Ergebnis)";
}
});
});
}
});