Hartmut Kroos: Form, Input, Button - Warum muß der Button mit?

problematische Seite

Ein kleines Problem, kurz erklärt.

Php stellt mittels sql eine List aller Menschen zusammen, ein Shortcut-Button soll diese Auswahl auf alle blauäugigen mit sonnigem Gemüt und Schuhgröße 37 reduzieren. Mein Script sendet bei der Eingabe des Textes aber auch immer (nur) den ersten Button mit. Wie kann man das elegant verhindern/abfangen?

Im Beispiel werden die Daten nicht erhalten, was in der Realität natürlich anders ist.

Vielen Dank für Eure Hilfe

<!DOCTYPE	 html>
<html lang = "de">
  <head>
  </head>
  <body>
    <?php
      var_dump($_POST);
    ?>
    <br/>
    <form
      action = "Formular.php"
      method="post"
      enctype = "multipart/form-data">
      <select onchange = "this.form.submit()" name = "Dropdown">
        <option value = "Auswahl 1">Auswahl 1</option>
        <option value = "Auswahl 2">Auswahl 2</option>
      </select><br/>
      <button type = "submit" name = "VorauswahlA" value = "VorauswahlA">
        Komplexer Filter (A)
      </button><br/>
      <button type = "submit" name = "VorauswahlB" value = "VorauswahlB">
        Komplexer Filter (B)
      </button><br/>
      <input type = "text" name = "Texteingabe" value = "Ihre Eingabe bitte" onchange = 'this.form.submit()'/>
    </form>
  </body>
  1. problematische Seite

    Nachtrag

    Nur das Input-Tag zeigt dieses Verhalten.

  2. problematische Seite

    Hallo,

    Php stellt mittels sql eine List aller Menschen zusammen, ein Shortcut-Button soll diese Auswahl auf alle blauäugigen mit sonnigem Gemüt und Schuhgröße 37 reduzieren.

    Glück gehabt, ich bin nicht dabei. 😉

    Mein Script sendet bei der Eingabe des Textes aber auch immer (nur) den ersten Button mit. Wie kann man das elegant verhindern/abfangen?

    Ich verstehe noch nicht, wozu du das brauchst. Aber beim Formularversand mit HTML ist festgelegt, dass nur der "erfolgreiche" Submit-Button auch übermittelt wird. Das ist derjenige, der angeklickt/ausgelöst wurde - oder der erste, wenn das Formular anders, z.B. durch Drücken der Enter-Taste in einem input-Feld abgeschickt wurde.

    Wenn du bestimmte vorbelegte Werte bei der Weiterverarbeitung alle brauchst, bietet es sich an, diese in einem hidden input mitzuschleifen. Oder sie gar nicht erst wieder zum Client zu schicken, sondern gleich in PHP auf dem Server zu behalten - z.B. in einer Session.

    Übrigens: Die Leerzeichen um die '=' bei deinen Attributwerten sind zwar erlaubt, aber ungewöhnlich und machen das Markup daher für mich(!) schwerer lesbar. YMMV.

    Live long and pros healthy,
     Martin

    --
    Fische, die bellen, beißen nicht.
    1. problematische Seite

      Das entspricht meiner Beobachtung, aber wie kann ich im php-Bereich feststellen, was den „submit“ ausgelöst hat? Schließlich will ich den Filter nicht auslösen, wenn ich im Eingabefeld „Peter“ eingebe, um meine Auswahl weiter einzuschränken?

      1. problematische Seite

        Moin Hartmut,

        Das entspricht meiner Beobachtung, aber wie kann ich im php-Bereich feststellen, was den „submit“ ausgelöst hat?

        Du kannst allen Submit-Buttons den gleichen Namen, aber unterschiedliche Werte geben.

        Schließlich will ich den Filter nicht auslösen, wenn ich im Eingabefeld „Peter“ eingebe, um meine Auswahl weiter einzuschränken?

        Dann entferne dort doch einfach onchange = 'this.form.submit()'. Du möchtest wahrscheinlich, dass das Formular durch Drücken von ENTER oder RETURN abgesendet wird. Dafür brauchst du den Eventhandler meines Wissens gar nicht.

        Viele Grüße
        Robert

        1. problematische Seite

          Hallo,

          Du kannst allen Submit-Buttons den gleichen Namen, aber unterschiedliche Werte geben.

          ja, das kann er natürlich. Und dann?

          Schließlich will ich den Filter nicht auslösen, wenn ich im Eingabefeld „Peter“ eingebe, um meine Auswahl weiter einzuschränken?

          Dann entferne dort doch einfach onchange = 'this.form.submit()'. Du möchtest wahrscheinlich, dass das Formular durch Drücken von ENTER oder RETURN abgesendet wird.

          Das ist im Moment mein Problem: Ich habe noch nicht verstanden, was Hartmut tatsächlich erreichen möchte. Seine Beschreibung und/oder sein Beispiel geben mir nicht geug Info.

          Dafür brauchst du den Eventhandler meines Wissens gar nicht.

          Das ist korrekt.

          Live long and pros healthy,
           Martin

          --
          Fische, die bellen, beißen nicht.
  3. problematische Seite

    Moin Hartmut,

    <form
        action = "Formular.php"
        method="post"
        enctype = "multipart/form-data">
    

    Wofür brauchst du hier den expliziten enctype? PHP kommt doch auch mit dem Default application/x-www-form-urlencoded klar.

    <select onchange = "this.form.submit()" name = "Dropdown">
        <option value = "Auswahl 1">Auswahl 1</option>
        <option value = "Auswahl 2">Auswahl 2</option>
    </select><br/>
    <button type = "submit" name = "VorauswahlA" value = "VorauswahlA">
        Komplexer Filter (A)
    </button><br/>
    <button type = "submit" name = "VorauswahlB" value = "VorauswahlB">
        Komplexer Filter (B)
    </button><br/>
    <input type = "text" name = "Texteingabe" value = "Ihre Eingabe bitte" onchange = 'this.form.submit()'/>
    

    Hier sind vier Elemente, die jeweils ihren eigenen Submit direkt bei der Zustandsänderung triggern – und es sind drei verschiedene Eingabeelemente (select, button, input type=text) – ist das vom Standpunkt des User Experience verständlich? Dazu kommen noch fehlende label, so dass nicht klar ist, welche Funktion die Elemente haben. Und bei der Texteingabe fällt auf, dass hier der value als placeholder missbraucht wird.

    Viele Grüße
    Robert

    1. problematische Seite

      Und alle drei oder vier Elemente sollen dazu dienen, die Daten zu filtern, was auch gut funktioniert. Um das Beispiel mit Leben zu füllen ;-) Per Dropdown wird zwischen Männlein, Weiblein, Sonstige unterschieden Per Textfeld wird der Nachname „Meyerdierks“ gesucht und die Schalter finden dann die Blondschöpfe mit Sternzeichen Löwe (oder so). Das Dropdown funktioniert, liefert nur seinen Inhalt und den des Textfeldes. Die Buttons funktionieren, liefern den jeweils gedrückten Button, sowie den Inhalt von Dropdown und Textfeld. Das Textfeld liefert seinen und den Inhalt des Dropdown UND zusätzlich das Ergebnis des ersten Buttons :-( Damit bekomme ich automatisch alle „Meyerdierks“ mit blonden Haaren und Sternzeichen Löwe :-(

      1. Moin Hartmut,

        Und alle drei oder vier Elemente sollen dazu dienen, die Daten zu filtern, was auch gut funktioniert.

        So gut kann es dann doch nicht funktionieren, sonst fragtest du hier nicht um Rat 😉

        Das Textfeld liefert seinen und den Inhalt des Dropdown UND zusätzlich das Ergebnis des ersten Buttons :-(

        Was passiert denn, wenn du

        • auf das automatische Absenden des Formulars in den Eventhandlern verzichtest
        • aus den Submit-Buttons „normale Buttons“ machst?

        Viele Grüße
        Robert

      2. problematische Seite

        Hallo,

        Und alle drei oder vier Elemente sollen dazu dienen, die Daten zu filtern, was auch gut funktioniert.

        mehr oder weniger. 😉

        Ich bekomme aber den Eindruck, du hast ein grundsätzliches Verständnisproblem mit der Formularverarbeitung. Du lässt bei jeder Nutzer-Aktion das gesamte Formular absenden (und ich schließe mich Roberts Zweifeln an der Sinnhaftigkeit an).

        Formular absenden heißt aber: Alle darin enthaltenen "erfolgreichen" [1] Controls mit ihren aktuellen Werten. Das sind "gewöhnliche" inputs, selects, hidden inputs; bei Radiobuttons und Checkboxen nur die ausgewählten, und bei Submit-Buttons derjenige, der das Formular abgeschickt hat. Das ist per Default der erste.

        Per Dropdown wird zwischen Männlein, Weiblein, Sonstige unterschieden
        Per Textfeld wird der Nachname „Meyerdierks“ gesucht und die Schalter finden dann die Blondschöpfe mit Sternzeichen Löwe (oder so).

        Dann wären Checkboxen anstatt der Buttons vieleicht die passenderen Elemente. Und auf das automatische Absenden nach jeder Eingabe würde ich auch verzichten. Ich würde das als Ärgernis empfinden.

        Das Dropdown funktioniert, liefert nur seinen Inhalt und den des Textfeldes.

        Und den ersten Button.

        Die Buttons funktionieren, liefern den jeweils gedrückten Button, sowie den Inhalt von Dropdown und Textfeld.

        Works as specified.

        Das Textfeld liefert seinen und den Inhalt des Dropdown UND zusätzlich das Ergebnis des ersten Buttons :-(

        Works as specified.

        Live long and pros healthy,
         Martin

        --
        Fische, die bellen, beißen nicht.

        1. In der Spec ist tatsächlich von successful controls die Rede. ↩︎

  4. problematische Seite

    Hallo Hartmut,

    Mein Script sendet bei der Eingabe des Textes aber auch immer (nur) den ersten Button mit. Wie kann man das elegant verhindern/abfangen?

    Indem Du nicht die ENTER Taste drückst, um den Wert zu bestätigen, sondern TAB.

    Grund: ENTER betätigt automatisch den ersten Submitbutton im Form, und dieser Submit kommt dem Submit zuvor, den Du in deinem Change-Handler vornimmst.

    Spaß beiseite, das hilft Dir natürlich nicht wirklich. Aber das, was ich als Grund genannt habe, ist der Auslöser deines Problems.

    Da Du auf jedem Eingabeelement ein Auto-Submit hast, willst Du offenbar von jedem Eingabeelement isoliert benachrichtigt werden. Oder zumindest möchtest Du in PHP erfahren, welches Eingabeelement den Autosubmit auslöste. Das kann man mit JavaScript und versteckten Eingabefeldern lösen, aber die einfachste Vorgehensweise dürfte sein, drei Forms zu machen.

    Eins für das <select>
    Eins für die beiden Buttons
    Eins für das Textfeld.

    Dann kann es zu keinen unerwünschten Querbeziehungen kommen.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. problematische Seite

      Hallo Rolf,

      Mein Script sendet bei der Eingabe des Textes aber auch immer (nur) den ersten Button mit. Wie kann man das elegant verhindern/abfangen?

      Indem Du nicht die ENTER Taste drückst, um den Wert zu bestätigen, sondern TAB.

      auch dann würde AFAIK das Auto-Submit den erstbesten Submit-Button mitsenden.

      Da Du auf jedem Eingabeelement ein Auto-Submit hast, willst Du offenbar von jedem Eingabeelement isoliert benachrichtigt werden. Oder zumindest möchtest Du in PHP erfahren, welches Eingabeelement den Autosubmit auslöste.

      Aber das erscheint mir nicht sinnvoll. Es sind doch (im Beispiel) vier Controls, die alle ein gemeinsames Thema haben: Reduzieren einer Ergebnismenge durch Filter.

      aber die einfachste Vorgehensweise dürfte sein, drei Forms zu machen.

      Eins für das <select>
      Eins für die beiden Buttons
      Eins für das Textfeld.

      Ich würde genau davon abraten, sondern zusammenhalten, was zusammengehört.

      Live long and pros healthy,
       Martin

      --
      Fische, die bellen, beißen nicht.
      1. problematische Seite

        Hallo Martin,

        auch dann würde AFAIK das Auto-Submit den erstbesten Submit-Button mitsenden.

        Nein. form.submit() sendet keinen Button. Hab ich probiert 😉

        Ich würde genau davon abraten,

        Aber deine Begründung fordert das Gegenteil

        zusammenhalten, was zusammengehört.

        Exakt. Deswegen trennen. Denn sie gehören nicht zusammen. Jedes der vier Controls löst eine eigene Aktion aus und benötigt die Daten der anderen Controls nicht. Im Gegenteil. Die Daten der anderen Controls stören und verhindern, dass Du den Auslöser der Anforderung erkennst.

        Zumindest verstehe ich Toni - äh - Hartmut so.

        Deswegen finde ich deine Idee mit den Checkboxen auch nicht gut. Was nützt es, Vorauswahl A und Vorauswahl B anzukreuzen und dann noch einen Text einzugeben? Das ist doch unabhängig voneinander, oder?

        Aber vielleicht habe ich ja auch was falsch verstanden; dazu müsste Hartmut was sagen.

        Wie unabhängig sind diese Eingabeelemente voneinander? Gibt es am Server Verarbeitungen, die die Inhalte von mehr als einem der Eingabeelemente benötigen?

        Rolf

        --
        sumpsi - posui - obstruxi
        1. problematische Seite

          Hallo Rolf,

          auch dann würde AFAIK das Auto-Submit den erstbesten Submit-Button mitsenden.

          Nein. form.submit() sendet keinen Button. Hab ich probiert 😉

          dann habe ich entweder die Spec oder frühere eigene Versuche falsch in Erinnerung.

          Ich würde genau davon abraten,

          Aber deine Begründung fordert das Gegenteil

          zusammenhalten, was zusammengehört.

          Exakt. Deswegen trennen. Denn sie gehören nicht zusammen. Jedes der vier Controls löst eine eigene Aktion aus und benötigt die Daten der anderen Controls nicht. Im Gegenteil. Die Daten der anderen Controls stören und verhindern, dass Du den Auslöser der Anforderung erkennst.

          Ich verstehe es so, dass alle diese vier Controls Filter für eine DB-Abfrage sind. Die erwartete Funktion für mich als Nutzer wäre also: Ich trage alle meine Filterkriterien ein (select-Auswahl, Checkboxen anstatt Buttons wie schon vorgeschlagen, irgendein Freitext-Feld). Und dann klicke ich auf einen Submit-Button, der meinetwegen mit "Jetzt anwenden" oder "Aktualisieren" beschriftet ist und erwarte die Anzeige der entsprechend reduzierten Ergebnismenge.

          Zumindest verstehe ich Toni - äh - Hartmut so.

          Hmm. Ich nicht. Und wieso Toni? 🤔

          Deswegen finde ich deine Idee mit den Checkboxen auch nicht gut. Was nützt es, Vorauswahl A und Vorauswahl B anzukreuzen und dann noch einen Text einzugeben? Das ist doch unabhängig voneinander, oder?

          Kommt auf die eigentliche Anwendung an. Ich habe hier eine Windows-Anwendung vor mir (firmenintern), mit der ich auf Prüf- und Zertifizierungsdaten von unseren Produkten zugreifen kann. Da ist eine solche Kombination durchaus sinnvoll: Select für den Testplan-Status (Entwurf, Review, Freigegeben, Historisch), Checkboxen für "nur Artikel mit CE-Erklärung", "nur Artikel mit UL-Zulassung", ein Textfeld für Teile der Artikelbezeichnung.

          Aber vielleicht habe ich ja auch was falsch verstanden; dazu müsste Hartmut was sagen.

          Wie unabhängig sind diese Eingabeelemente voneinander? Gibt es am Server Verarbeitungen, die die Inhalte von mehr als einem der Eingabeelemente benötigen?

          Guter Punkt. Ich bin bisher ganz selbstverständlich davon ausgegangen, dass es nur ein Script ist, dass alle gesetzten Filter anwendet. Nacheinander, so wie Hartmut es realisiert hat; aber ich gehe davon aus, dass auch mehrere Kriterien gleichzeitig (also mit nur einem Aufruf) möglich sind.

          Live long and pros healthy,
           Martin

          --
          Fische, die bellen, beißen nicht.
          1. problematische Seite

            Hi,

            Zumindest verstehe ich Toni - äh - Hartmut so.

            Hmm. Ich nicht. Und wieso Toni? 🤔

            Anspielung auf Toni Kroos, Fußball-Nationalspieler.

            cu,
            Andreas a/k/a MudGuard

            1. problematische Seite

              Hallo,

              Und wieso Toni? 🤔

              Anspielung auf Toni Kroos, Fußball-Nationalspieler.

              ah, danke. Sagte mir bis eben nichts, deswegen ist mir der Name nicht aufgefallen.

              Live long and pros healthy,
               Martin

              --
              Fische, die bellen, beißen nicht.
          2. problematische Seite

            Hallo Martin,

            Und dann klicke ich auf einen Submit-Button

            Das ist ein Unterschied in der Bedienphilosophie. Antragsformular ausfüllen und einreichen vs "Mach das. JETZT!"

            Die Eventhandler mit form.submit deuten auf letzteres hin.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. problematische Seite

              Hi,

              Und dann klicke ich auf einen Submit-Button

              Das ist ein Unterschied in der Bedienphilosophie. Antragsformular ausfüllen und einreichen vs "Mach das. JETZT!"

              Die Eventhandler mit form.submit deuten auf letzteres hin.

              ja, ich weiß - und ich hatte auch schon kritisiert, dass ich als Nutzer das als sehr störend empfinden würde. Ich mag es nicht, wenn Computer schon anfangen zu arbeiten, während ich noch nicht mit dem Denken fertig bin.

              Live long and pros healthy,
               Martin

              --
              Fische, die bellen, beißen nicht.
              1. problematische Seite

                Mal sehen, vielleicht hilft ja eine Abbildung, um zu verdeutlichen, warum ich es mit so vielen Submits versuche. Man stelle sich vor, Volkswagen, ein Golf soll es sein mit verschiedenen Features und ohne andere. Dazu dann natürlich nur die aktuellen Fahrzeuge, ein zusätzliches Suchwort und das ganze als registrierter Nutzer. all diese Faktoren haben Ihren Einfluss auf die Auswahl und tatsächlich läuft auch alles, nur die Textfelder nehmen immer den ersten Button mit.

                Das neutralisierte Auswählmenü

                1. problematische Seite

                  Hallo Hartmut,

                  da scheine ich dann doch auf dem falschen Weg gewesen zu sein. Wenn ich oben "Volkswagen" und "Golf" auswähle und dann auf "Neuheiten" klicke, dann soll man nur die VW Golf-Neuheiten sehen?

                  Das ist für den Nutzer und für deine Server ggf. eine mühsame Sache. Ich wähle "VW" aus. Es gibt einen Postback und der Server liefert eine Trefferseite für alle VWs. Dann wähle ich "Golf". Es gibt noch einen Postback und der Server liefert eine Trefferseite für alle VW Golf. Dann drücke ich Bremensien, und ich finde alle VW Golf Produkte, die brementypisch sind (z.B. ein VW-Symbol, das grün-weiß ist und nach Fisch riecht)?

                  die Textfelder nehmen immer den ersten Button mit.

                  Den Grund dafür hatte ich Dir um 12:29 genannt: Du drückst ENTER. Das tust Du bei den Dropdown-Selektionen nicht. Und das führt zu einem Submit des Forms über den ersten Button. Works as specified.

                  Ist ein weiterer Button "Suchen", der an erster Stelle steht, da nicht doch sinnvoller als Auto-Postbacks? Dieser Button würde dann auch das Textfeldproblem lösen.

                  Ohne diesen Button bräuchtest Du wohl eine Prise clientseitiges JavaScript, um die ENTER-Taste im Textfeld daran zu hindern, den Default-Submit auszulösen. Und zwar einen keydown-Handler am form. Ich mach's mal mit

                  <form id="suchform" action="#" method="GET">
                    <label>Suchbegriff:<br>
                      <input type="text" name="bar" onchange="this.form.submit()">
                    </label>
                    <button name="shortcut" value="neu">Neuheiten</button>
                    <button name="shortcut" value="jahr">Rund ums Jahr</button>
                    <button name="shortcut" value="fisch">Bremensien</button>
                  </form>
                  
                  <script>
                  document.getElementById("suchform")
                          .addEventListener("keydown", function(event) {
                             if (event.code == "Enter") {
                                event.preventDefault();
                                event.target.form.submit();
                             }
                          });
                  // Erweiterung: Ersetzt alle onchange-Attribute an den <select> 
                  //              und <input> Elementen
                  document.getElementById("suchform")
                          .addEventListener("change", function(event) {
                             event.target.form.submit();
                          });
                  </script>
                  

                  Das <script> Element muss hinter dem <form> stehen, sonst brauchst Du noch einen ready-Handler. Am besten setzt Du es an das Ende des <body> (aber VOR das </body> Tag).

                  Der erste Eventhandler reagiert auf das Drücken der ENTER Taste und verhindert, dass das Form daraufhin seine Default-Aktion auslöst: den ersten Button als Default-Button setzen und sich dann abschicken. Statt dessen wird nur submitted.

                  Für den zweiten Eventhandler kannst Du Dir überlegen, ob Du das willst. Events über onXxxx Attribute zu registrieren ist nämlich eigentlich etwas, was veraltet ist. Man verwendet addEventListener, um auf einem DOM Element einem Event eine Funktion zuzuordnen. Die bekommt dann auch gleich einen Parameter: das event-Objekt.

                  Events werden nicht nur auf dem Objekt gemeldet, auf dem sie ausgelöst werden. Die meisten von ihnen "blubbern" in der Elementhierarchie nach oben, und das change-Event gehört dazu (unser Wiki weiß, welche Events blubbern und welche nicht). Wenn Du also bei jedem Eingabeelement auf change reagieren willst und das auch noch für alle Elemente gleich, dann kannst Du Dich auf das form setzen, die change-Events zu Dir hin blubbern lassen und sie dort behandeln. Das onchange-Attribut auf den <select> und <input> Elementen entfällt dann und dein HTML ist sauberer. Man nennt diese Technik "unaufdringliches JavaScript".

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. problematische Seite

                    Herzlichen Dank, das gibt mir viele wertvolle Hinweise. Hartmut Kroos