javascript, eigenes modales Fenster, Aufrufbutton in <form>
gschade
- javascript
- programmiertechnik
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)";
}
});
});
}
});
Liebe(r) gschade,
Dein Button ist ein submit
-Button (das ist der Default-Typ und bei Dir steht kein type
-Attribut), der das Formular versendet:
<p>Eine Dialog-Box mit mehreren Eingabefeldern als modales Fenster. <button>anzeigen</button>. </p>
Probiere doch einmal, ob ein type="button"
das Problem bereits löst.
Liebe Grüße
Felix Riesterer
Servus!
Liebe(r) gschade,
Dein Button ist ein
submit
-Button (das ist der Default-Typ und bei Dir steht keintype
-Attribut), der das Formular versendet:<p>Eine Dialog-Box mit mehreren Eingabefeldern als modales Fenster. <button>anzeigen</button>. </p>
Probiere doch einmal, ob ein
type="button"
das Problem bereits löst.
Das kommt so oft vor (und passiert selbst mir immer mal wieder), dass man's noch mal deutlich irgendwo hinschreiben müsste.
Ich hab's jetzt im Artikel zum form-Element getan. Wo sollte es sonst noch hin?
Herzliche Grüße
Matthias Scharwies
Hi there,
vielleicht sollte man das ein bisschen besser kommunizieren, es kommt in der letzten Zeit immer öfter vor, daß jemand als "Problematische Seite" den Verweis auf jene Seite im selfhtml-Wiki einträgt, die er gerade nicht versteht...😉
Servus!
Hi there,
vielleicht sollte man das ein bisschen besser kommunizieren, es kommt in der letzten Zeit immer öfter vor, daß jemand als "Problematische Seite" den Verweis auf jene Seite im selfhtml-Wiki einträgt, die er gerade nicht versteht...😉
Na ja, teilweise ist dort ja der Fehler oder das Problem zu finden - duckundwech. 😀
Es gab schon Diskussionen, diese Linkmöglichkeit umzubenennen, aber die perfekte Lösung wird's da nicht geben.
Herzliche Grüße
Matthias Scharwies
Hallo klawischnigg,
es kommt in der letzten Zeit immer öfter vor, daß jemand als "Problematische Seite" den Verweis auf jene Seite im selfhtml-Wiki einträgt, die er gerade nicht versteht...😉
Ja, er hat also mit der Wiki-Seite ein Problem 😉
vielleicht sollte man das ein bisschen besser kommunizieren,
Wie lautet dein Vorschlag?
Bis demnächst
Matthias
Hi there,
es kommt in der letzten Zeit immer öfter vor, daß jemand als "Problematische Seite" den Verweis auf jene Seite im selfhtml-Wiki einträgt, die er gerade nicht versteht...😉
Ja, er hat also mit der Wiki-Seite ein Problem 😉
vielleicht sollte man das ein bisschen besser kommunizieren,
Wie lautet dein Vorschlag?
Gute Frage. Vielleicht irgendetwas mit "Meine problematische Seite" und "Seite im Wiki, die ich nicht versteh'"...😉
Hallo,
Ich finde es ok, die
"Seite im Wiki, die ich nicht versteh'"
als problematische Seite zu bezeichnen. Man kann das als Arbeitshypothese nehmen und in der folgenden Diskussion gradebiegen…
Gruß
Kalk
Hi there,
Ich finde es ok, die
"Seite im Wiki, die ich nicht versteh'"
als problematische Seite zu bezeichnen. Man kann das als Arbeitshypothese nehmen und in der folgenden Diskussion gradebiegen…
Weiß nicht, ich klick' da immer drauf, in einer leicht masochistischen Erwartungshaltung auf absolut grottiges Webdesign und haarsträubend schlechtes Javascript - und wenn ich dann auf einer Seite des selfhtml-Wikis lande...ich muß es bekennen, ich bin dann echt ein bisschen entäuscht...😉
Lieber klawischnigg,
ich bin dann echt ein bisschen entäuscht...😉
davon, dass Du kein absolut grottiges Webdesign findest, oder vom Wiki? Oder empfindest Du das Wiki als absolut grottiges Webdesign und bist nur enttäuscht, dass es "schon wieder das Wiki" ist?
Disclaimer: Dieses Posting ist nicht ernst gemeint.
Liebe Grüße
Felix Riesterer
Hi there,
ich bin dann echt ein bisschen entäuscht...😉
davon, dass Du kein absolut grottiges Webdesign findest, oder vom Wiki?
Das Wiki hat mich noch nie enttäuscht. Das selfhtml-Wiki ist für mich der Leuchtturm an den rauhen, gischtspritzenden und vor Untiefen nur so strotzenden Gewässern der Webgestaltung.
Oder empfindest Du das Wiki als absolut grottiges Webdesign und bist nur enttäuscht, dass es "schon wieder das Wiki" ist?
Ersteres nein, zweiteres ja...😉