Rolf B: Nummerierung bei dynamischen Formular

Beitrag lesen

Hallo Jochbart,

es gibt da ein paar Fallstricke, die sich um deine Waden wickeln.

Aber eins hast Du aus meiner Vorlage nicht verstanden: "unobtrusive javascript". Heißt: Man verwendet heute eigentlich keine ondingsbums Attribute mehr - sie passen nicht zum Konzept der Aufgabentrennung HTML = Struktur, CSS = Layout, JavaScript = Verhalten. Statt dessen schreibt man im Script einen DOM-ready Handler: document.addEventListener("DOMContentLoaded", function() { ... }); und verkuppelt alle Event-Handler in dieser Funktion.

Wenn man eine Gruppe von Elementen hat, auf die man mit einem Eventhandler gleichartig reagieren will, dann registriert man den Eventhandler nicht auf jedem einzelnen Element. Statt dessen nutzt man die "bubble" Eigenschaft von JavaScript Events und registriert den Listener auf einem gemeinsamen Container dieser Elemente - bei Dir das form. Für den "Entfernen" Handler habe ich das in meinem Beispiel bereits gemacht, hier nochmal gezeigt:

	 form.addEventListener("click", removeSection);

   function removeSection(evt) {
      if (evt.target.name == "remove") form.removeChild(evt.target.parentNode.parentNode);
   }

Dein Event für Änderungen auf dem Überschriften-Feld solltest Du ähnlich registrieren.

ABER die Frage vorweg wäre - warum machst Du das? Warum machst Du das input Element im h2 nicht einfach readwrite und verzichtest auf das Überschrift-Element?

Bei Dir konkret funktioniert nicht, dass this.form.Ausgabe nicht existiert, es ist this.form.elements.Ausgabe. Aber das ist nicht nur ein Element, sondern die Menge aller Elemente mit name="Ausgabe". Du müsstest also mindestens mal auf this.form.elements.Ausgabe[0] zugreifen. Damit löst Du aber nicht das Problem, Änderungen des zweiten "uberschrift" input auch in das zweite "Ausgabe" Element zu übertragen. Um das zu machen, musst Du analog zur remove Funktion zuerst vom Element, auf dem das Ereignis ausgelöst wurde, auf den Container wechseln (also 2x .parentNode) und kannst darauf dann querySelector("input[name=Ausgabe]") aufrufen, um das gewünschte Element zu finden. Damit bekommst Du ein eindeutiges Ergebnis.

Ich würde dann aber auch nicht ein input-Feld in die Überschrift legen, sondern den span überschreiben wo "Arbeitsplatz" drinsteht. Es sei denn, das Überschriftfeld ist leer, dann setze "Arbeitsplatz" als Standardtext ein. Ich hab dazu mal wieder gespielt - wenn Du davon was übernehmen willst, beachte bitte dass ich aus dem div eine section gemacht habe, was Änderungen im CSS und JS zur Folge hat. Die Standardaufgabe, die Teilsektion zu finden, in der ein Element liegt, habe ich in eine Funktion verschoben.

Man könnte noch argumentieren, dass statt <section> eine <ol> Liste angebrachter wäre, weil semantisch passender. Wie man dann das Markup korrekt aufbaut, um auch Accessibility-konform zu sein, müsste jemand anderes beisteuern.

Für eine perfekte Lösung müsstest Du das Ganze noch so gestalten, dass es auch ohne JavaScript funktioniert. In diesem Fall müssten die Buttons das form posten und der Server baut es entsprechend neu auf. Das ist etwas Arbeit, aber für eine Zugänglichkeit der Seite nötig. Den Zusatz type='button' bei den Aktionsbuttons lässt Du dann weg und rufst in den Eventhandler-Funktionen als letztes evt.preventDefault() auf, um keinen Submit auszulösen. Ist JavaScript aus, führen die Buttons einfach einen Submit aus und du kannst am Server reagieren.

Rolf

--
sumpsi - posui - clusi