Hallo
Ich denke ich spreche von der Technik unter 1.)
Gut, also die JS-eigenen Dialoge mit der Gefahr, dass ihre Anzeige von den Browsern von vornherein unterdrückt wird.
Nur sind die drei genannten "Fenster" nicht sehr schön und ich hätte sie gerne mit einem eigenen Stil versehen …
Womit wir bei Technik Nr. 2, HTML-Elemente als Dialog zu erzeugen, wären.
… und halt den Progamm-Fluß genauso unterbrechen, bis der User etwas eingibt.
Ich weiß nicht, warum du dich so sehr auf die Unterbrechung des Programmflusses kaprizierst. Dass das bei Technik Nr. 2 nicht geht, ist klar. Dass diese Unterbrechnung unnötig ist und durch einen geteilten Programmablauf ersetzt wird, hat dedlfix lang und breit erklärt.
Beispiel:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- mehr Elemente -->
<title>Dialogtest</title>
</head>
<body>
<header>
<h1>Dialogtest</h1>
<nav id="mainmenu">
<ul>
<!-- diverse Listenelemente -->
<li><a href="?dataset=search" class="indoc">Adressen suchen</a></li>
</ul>
</nav>
</header>
<main>
<!-- diverse Elemente -->
</main>
<template id="template-search">
<dialog id="popupform" class="entryform simple" open>
<header class="titlebar">
<h2>Suche von Adressen</h2>
</header>
<p>Teileingaben sind mit angehängtem Sternchen (*) möglich. Ohne Stern wird <em>exakt</em> nach dem eingegebenen Wert gesucht.</p>
<form method="post" id="entryform">
<fieldset>
<legend>Suchparameter</legend>
<div>
<label for="id-strasse">Straße, Hausnummer</label>
<input type="text" id="id-strasse" name="fld-strasse">
</div>
<div>
<label for="id-plz">PLZ</label>
<input type="text" id="id-plz" name="fld-plz">
</div>
<div>
<label for="id-ort">Ort</label>
<input type="text" id="id-ort" name="fld-ort">
</div>
</fieldset>
<p>
<button name="btn-search" id="id-btn-search">Suche ausführen</button>
<button type="reset">Eingaben zurücksetzen</button>
<button type="button" id="close-popupform">Formular schließen</button>
</p>
</form>
</dialog>
<div class="backdrop"></div>
</template>
</body>
</html>
In einem HTML-Dokument wird per Template ein Suchformular bereitgehalten. Per JS wird ein Eventhandler für den Link im Hauptmenü der Seite registriert …
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('mainmenu').addEventListener('click', runActionMainMenu, true);
document.getElementById('mainmenu').addEventListener('touchstart', runActionMainMenu, true);
});
… damit auf den Klick des Links reagiert werden kann, um den Dialog einzublenden.
function runActionMainMenu(event) {
var c, i, em = null;
var elem = event.target;
if (elem.classList.contains('indoc')) {
var url = elem.getAttribute('href');
if (url == null) {
return null;
}
var urlTarget = gup('dataset', url); // gup: Hilfsfunktion, um an den Wert des URL-Parameters zu kommen
if (urlTarget == 'search') {
var em = document.querySelector('#template-search').content; // finde das richtige Template
}
if (em !== null) {
var clone = document.importNode(em, true); // importiere den Inhalt des Templates in die Variable clone
document.querySelector('main').appendChild(clone); // hänge den Inhalt des Templates ins DOM ein
/**
* Der Dialog wurde bereitgestellt, das Programm kann beendet werden, wenn …
* … die Events zum absenden und schließen des Dialogs registriert wurden
*/
document.getElementById('entryform').addEventListener('submit', searchDatasets, true);
document.getElementById('close-popupform').addEventListener('click', closePopupForm, true);
} else {
console.log("kein zur Aktion (" + urlTarget + ") passendes Template gefunden.");
}
event.preventDefault(); // verhindere, dass dem angegebenen Linkziel gefolgt wird
}
}
In closePopupForm werden die Events zum schließen des Dialogs deregistriert und der Dialog aus dem DOM entfernt und in searchDatasets
wird zudem zuvor per Ajax/Fetch die Suchanfrage an den Server gestellt. Und auch dort geht man nach dem selben Prinzip vor, eine Aufgabe zu erledigen, und zu definieren, was bei der irgendwannn auftretenden reaktion zu erfolgen hat (asynchrone Abarbeitung).
function closePopupForm(event) {
var elem = event.target;
var dialog = document.getElementById('popupform');
var backdrop = document.getElementsByClassName('backdrop');
if (elem.id == 'close-popupform' || elem.id == 'close-popupform-icon') {
document.getElementById('close-popupform').removeEventListener('click', closePopupForm, true);
dialog.remove();
for (var i = 0; i < backdrop.length; i++) {
backdrop[i].remove();
}
}
return false;
}
Zu guter Letzt gehört der Dialog zum Rest der Seite passend per CSS formatiert.
dialog {
position: fixed;
left: 0;
right: 0;
top: 2em;
margin: auto;
padding: 1rem;
border: 1px solid #cbd4d8;
border-radius: 0.25rem;
background-color: #fff;
display: block;
z-index: 3;
}
dialog + .backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.375);
z-index: 2;
}
Du brauchst also keine Möglichkeit, dass das Programm auf etwas wartet und bis dahin keine anderen Aufgaben erfüllt, sondern nur eine Trennung der Aufgaben in Erzeugung des Dialogs und die Reaktionen auf die möglichen Eingaben.
Das Ganze geht bestimmt auch eleganter und eine Bedienung des Formulars per Touch habe ich im Codebeispiel nicht berücksichtigt, aber zur Verdeutlichung des Prinzips sollte es, so hoffe ich, reichen.
Tschö, Auge
Ein echtes Alchimistenlabor musste voll mit Glasgefäßen sein, die so aussahen, als wären sie beim öffentlichen Schluckaufwettbewerb der Glasbläsergilde entstanden.
Hohle Köpfe von Terry Pratchett