Rolf B: mit input type radio formular absenden

Beitrag lesen

Hallo Apolle,

ist diese check5-Seite die, auf der das gemacht werden soll? In dem Fall wäre dein Wunsch kontraproduktiv, weil ja 2 Fragen zu beantworten sind.

Vom wüsten HTML red ich lieber gar nicht, das sieht nach Wordpress aus und vermutlich kommt das ganze div Geraffel nicht von Dir, sondern von WP oder irgendwelchen Plugins. Wenn doch: das geht garantiert cleaner.

Einen Radiobutton mit left:-9999px zu verstecken ist ein Antipattern. Das scheint zu funktionieren, führt aber dazu, dass der Browser einen Viewport aufbaut, der unnötige 10000 Pixel zu breit ist. Das kostet zumeist über 10 MB Speicher! Gerade auf einer Stele, die vermutlich einen schwachbrüstigen Computer enthält, kann das kritisch sein. Schau Dir die Klasse visually-hidden an, die im Wiki unter Dropdown-Menü verwendet wird. Nimm diese Regel in dein Stylesheet und gib deinen input type=radio Elemente diese Klasse.

Wenn Du zwei Sets von Radiobuttons hast, hast Du eine weitere Anforderung. Der Submit sollte erst passieren, wenn in beiden Sets etwas ausgewählt wurde. Denn andernfalls bekommt der Server nach der ersten Auswahl Nachricht, und nach der zweiten Auswahl auch.

Zu den Events: click könnte gehen, kommt aber vermutlich zu früh. Ein checked-Event gibt es nicht. Du brauchst input oder change, bei einem Radiobutton ist das egal.

Mein Vorschlag wäre:

  • registriere einen input Handler auf dem Form (nicht auf jedem Radiobutton einzeln - die input Events blubbern vom Radio zum Form hoch)
  • frage im input-Handler ab, ob in beiden Radiogruppen etwas ausgewählt wurde. Wenn ja, submitte das Form. Bspw. so:
   const uf = document.forms.uf;
   const f4 = uf.querySelector("[name='4']:checked");
   const f5 = uf.querySelector("[name='5']:checked");
   const complete =  f4 && f5;
   if (complete) {
      form.style="pointer-events: none";
      setTimeout(function() { uf.submit(); }, 1000)
   }

Das sollte zu einem Reload der Seite führen, wodurch die Buttons wieder ungecheckt gesetzt werden.

Dieser Submit im input-Event sorgt allerdings dafür, dass man die Animation des zweiten Buttons nicht mehr sieht. Deshalb hab ich den setTimeout hinzugefügt, der wartet eine Sekunde, bis er das Form abschickt. Und damit nach dem Aktivieren des zweiten Radiobuttons keine weiteren Klicks mehr akzeptiert werden, setze ich das Form auf pointer-events:none.

Für eine Stele ist das OK, die hat keine Tastatur oder sonstige Zusatzinputs, nur den Touchscreen. Auf einem PC würde pointer-events:none immer noch die Tastatur erlauben. Oder eine Sprachsteuerung.

Und dann brauchst Du eigentlich auch noch eine Logik, die nach X Sekunden zuschlägt, wenn einer der beiden Buttons gedrückt wurde, aber der zweite nicht. Dann kannst Du entweder den gedrückten Button zurücksetzen, oder das Form mit dem einen gedrückten Button abschicken.

Basisbeispiel - mit addEventListener statt oninput:

<form method="get" name="uf" action="#">
  <input type="radio" name="4" value="a">
  <input type="radio" name="4" value="b">
  <input type="radio" name="4" value="c">
  <input type="radio" name="5" value="a">
  <input type="radio" name="5" value="b">
  <input type="radio" name="5" value="c">
</form>

Script:

document.addEventListener("DOMContentLoaded", function() {
   let watchdog = 0;
   let form = documents.form.uf;   
   form.addEventListener("input", handleInput);

   function handleInput(event) {
      let f4 = form.querySelector("[name='4']:checked");
      let f5 = form.querySelector("[name='5']:checked");

      if (f4 && f5) { 
         setTimeout(function() { form.submit(); }, 2000);
      }
      
      if (watchdog)
         clearTimeout(watchdog);
      watchdog = setTimeout(resetChecked, 5000);
   }
   
   function resetChecked() {
      let f4 = form.querySelector("[name='4']:checked"),
          f5 = form.querySelector("[name='5']:checked");
      if (f4) f4.checked = false;
      if (f5) f5.checked = false;   
   }
});

Das Einpacken in einen DOMContentLoaded-Handler kannst Du Dir sparen, wenn das Script entweder im Body hinter dem Form steht, oder wenn Du es mit der defer-Option laden kannst. Weiß nicht was WP hergibt.

Rolf

--
sumpsi - posui - obstruxi