Hallo portseven,
wenn Du aus PHP heraus HTML-Blöcke in einer Schleife erzeugst, dann darfst Du nie vergessen, dass das in HTML keine Schleife ist, sondern mehrere HTML Blöcke die untereinander stehen. Dieses Problem sehe ich immer wieder bei Leuten, die hier Fragen posten und sich wundern, warum irgendwelche Events nicht so behandelt werden wie gewünscht. Du musst im PHP immer überlegen: welches HTML kommt am Ende 'raus, und wenn JavaScript hinzukommt, agiert dieses Script auf dem erzeugten HTML, nicht auf dem PHP Code.
Wenn Du in PHP in einer Schleife identifizierende Attribute erzeugst (id, name), dann musst Du die die pro Schleifendurchlauf anpassen, sonst hast Du Kollisionen. Beispiel ist deine textarea und auch das file-input, deren IDs sind pro Durchlauf gleich.
Ähnliches gilt für JavaScript. Das solltest Du nur dann innerhalb einer Schleife ins HTML schicken, wenn's gar nicht anders geht. Der Script-Code für deine textarea-Observer wird zweimal ausgegeben; du hast hier Pech, dass in JS eine zweite init-Funktion einfach die erste überschreibt, selbst im strict mode, so dass dein Code SCHEINBAR läuft, in Wahrheit aber auf Treibsand gebaut ist. Durch die doppelt vergebene ID der textarea registrierst Du die Observer zweimal auf der ersten textarea.
Bei Scripten ist es meiner Meinung nach besser, sie in separaten .js Dateien zu halten und so zu schreiben, dass sie sich an Wiederholungsgruppen aus PHP selbst anpassen. D.h. eine bessere Observer-Registrierung würde in einem DOMContentLoaded Eventhandler alle textareas suchen, die entweder selbst eine bestimmte Klasse haben oder beispielsweise innerhalb von .add-comment stehen, und denen die Observer zuordnen. Analog solltest Du auch die change-Handler für die file-Uploads registrieren.
Dass Du pro PHP Durchlauf gleiche IDs generierst, führt auch zu deinem Upload-Problem. Man klickt bei Dir ja nicht auf das file-Input (das versteckst Du), sondern auf das Label dazu. Und das Label ist mit for="file"
spezifiziert, d.h. beide Labels beziehen sich auf das erste Upload-Control. Wenn man im Debugger einen Breakpoint in die changeEventHandler Funktion legt und dann, wenn der hält, den Callstack anschaut, sieht man, dass beide Male das 123-file-Input der Auslöser ist.
Lösung 1: Gib den file-Inputs unterschiedliche IDs
Oder Lösung 2: Lege das file-Input in das Label hinein, dann brauchst Du weder id noch for.
Rolf
--
sumpsi - posui - clusi