Sara: jQuery Formular abschicken & wieder einbleden

Moin,

ich muss gezwungenermaßen mit jQuery beschäftigen, da manche Features immer beliebter werden wie z.B. ein Formular abzuschicken ohne die Seite komplett neu zu laden. Ich persönlich finde dieses zwar totaler qatsch aber ok.

Daher bin ich noch ganz am Anfang und bin für jeden Hinweis dankbar.

Mein Formular schicke ich über diesen Code ab

$("#form_index").submit(function() {
              
  if($("#ctrl_20").val() == "" || $("#ctrl_21").val() == "" || $("#ctrl_22").val() == "" || $("#ctrl_25").val() == "") {
     $("#response").html("Bitte fülle alle Felder ausm die mit einem * versehen sind!");
  } else {
     $("#submit").attr("disabled","disabled");
             
   $.ajax({
      type: "POST",
      url: "senden.php",
      data: "ctrl_20=" + $("#ctrl_20").val() + "&ctrl_21=" + $("#ctrl_21").val() + "&ctrl_22=" + $("#ctrl_22").val() + "&ctrl_23=" + $("#ctrl_23").val() + "&ctrl_25=" + $("#ctrl_25").val(),
                 
      success: function(msg)
        {
          $("#form_index").addClass( "ausblenden");
          $('#ctrl_20').val('');
          $('#ctrl_21').val('');
          $('#ctrl_22').val('');
          $('#ctrl_23').val('');
	  $('#ctrl_25').val('');
          $("#response").html(msg);
  }
});
  }
     return false;
 });

In meiner senden.php habe ich einfach ein

echo "Alles OK";

stehen. Diese erhalte ich auch nach dem abschicken. Scheint also alles zu klappen.

Mein HTML Formular hat ein paar Felder und die Pflichtfelder ein required. Zusätzlich prüfe ich im jQuery Teil ob bestimmte Felder gefüllt sind. Soweit klappt auch alles.

Meine Fragen:

  1. Reicht diese Prüfung oder benötige ich noch weitere Prüfungen mit PHP?

eine PHP Prüfung in der senden.php könnte so aussehen

if(empty($_POST['ctrl_25'])){
            $fehler[] = "Wollen Sie uns nichts sagen?";
}

Um mein echo dann diesen Code

if(isset($_POST['abschicken']) && empty($fehler)) {
}

Nutze ich auch an anderen Stellen. Nur die Frage, wie bekommt mein jQuery davon etwas mit ich benötige ja eine weitere Ausgabe, dass der User weiß, dass hier etwas nicht stimmt?

  1. Nach dem abschicken blende ich mein Formular aus, setzte den Button auf disabled und leere mit $('#ctrl_20').val(''); meine Felder. Ist es benutzerfreundlich das Formular komplett auszublenden oder lieber stehen lassen?

  2. Wäre es möglich mein Formular, welches ich mit $("#form_index").addClass( "ausblenden"); ausgeblendet habe nach sagen wir mal 5 Sekunden wieder einzublenden? Und dafür die $("#response").html(msg); auszublenden?

Bevor jetzt gleich eine Diskussion aufkommt warum ich Bezeichnungen wie ctrl_20 nutzte, diese sind nur zum Testen vorhanden.

  1. Tach!

    ich muss gezwungenermaßen mit jQuery beschäftigen, da manche Features immer beliebter werden wie z.B. ein Formular abzuschicken ohne die Seite komplett neu zu laden.

    Das geht auch ohne jQuery, aber mit ist es bequemer. Vor allem zu der Zeit, als noch einige Browser ihre eigene Meinung hatte, wie das XHR zu instantiieren sei. Auch ist es bequemer, statt zu Fuß die Statuscodes-Zahlen auszuwerten, sprechenden Bezeichnern (success, error, complete) die Handler-Funktonen zuzuweisen.

    Ich persönlich finde dieses zwar totaler qatsch aber ok.

    Man kann auch ohne AngularJS Single-Page-Applications erstellen, aber genauso gut kann man mit telnet im Web surfen.

    
    >       data: "ctrl_20=" + $("#ctrl_20").val() + "&ctrl_21=" + $("#ctrl_21").val() + "&ctrl_22=" + $("#ctrl_22").val() + "&ctrl_23=" + $("#ctrl_23").val() + "&ctrl_25=" + $("#ctrl_25").val(),
    
    

    So nicht! Wenn der Nutzer ein & eingibt, sind deine Daten kaputt. Mit und ohne jQuery. Dabei macht es dir jQuery doch so einfach, du musst es nur seine vorhandene Funktionalität nutzen. Erstell dir ein Objekt und übergib das dem data.

    data: {
      ctrl_20: $("#ctrl_20").val(),
      ctrl_21: $("#ctrl_21").val(),
      ctrl_22: $("#ctrl_22").val(),
      ctrl_23: $("#ctrl_23").val(),
      ctrl_25: $("#ctrl_25").val()
    },
    
    1. Reicht diese Prüfung oder benötige ich noch weitere Prüfungen mit PHP?

    Man kann einen Server immer auch zu Fuß kontaktieren und beliebige Daten hinschicken. Eine clientseitige Prüfung allein ist nicht ausreichend, weil diese umgangen werden kann.

    Nutze ich auch an anderen Stellen. Nur die Frage, wie bekommt mein jQuery davon etwas mit ich benötige ja eine weitere Ausgabe, dass der User weiß, dass hier etwas nicht stimmt?

    Indem du ihm das antwortest. Dazu solltest du dir eine Datenstruktur ausdenken, mit der du am Client die Daten den entsprechenden Eingabefeldern oder was auch immer zuordnen kannst.

    Am besten erstellst du dazu ein (assoziatives) Array und packst das mit json_encode() ein. Dem jQuery.ajax auf der anderen Seite sagst du mittels dataType-Option, dass du JSON zurückschickst. Du bekommst dann ein fertig ausgepacktes Objekt, das du ohne weitere Schritte verwenden kannst.

    1. Nach dem abschicken blende ich mein Formular aus, setzte den Button auf disabled und leere mit $('#ctrl_20').val(''); meine Felder. Ist es benutzerfreundlich das Formular komplett auszublenden oder lieber stehen lassen?

    Frag das deine Benutzer für diesen Fall. Am besten ist, wenn du dir selbst immer wieder die Frage stellst, ob du das als einfacher Anwender gut zu bedienen findest.

    1. Wäre es möglich mein Formular, welches ich mit $("#form_index").addClass( "ausblenden"); ausgeblendet habe nach sagen wir mal 5 Sekunden wieder einzublenden? Und dafür die $("#response").html(msg); auszublenden?

    Natürlich, es gibt setTimeout().

    dedlfix.

    1. Hallo,

      So nicht! Wenn der Nutzer ein & eingibt, sind deine Daten kaputt. Mit und ohne jQuery. Dabei macht es dir jQuery doch so einfach, du musst es nur seine vorhandene Funktionalität nutzen. Erstell dir ein Objekt und übergib das dem data.

      data: {
        ctrl_20: $("#ctrl_20").val(),
        ctrl_21: $("#ctrl_21").val(),
        ctrl_22: $("#ctrl_22").val(),
        ctrl_23: $("#ctrl_23").val(),
        ctrl_25: $("#ctrl_25").val()
      },
      

      danke für die Verbesserung, habe ich in meinem Code abgeändert

      $("#form_index").submit(function() {
                    
              if($("#ctrl_20").val() == "" || $("#ctrl_21").val() == "" || $("#ctrl_22").val() == "" || $("#ctrl_25").val() == "") {
              	 $("#response").html("Bitte fülle alle Felder ausm die mit einem * versehen sind!");
              } else {
                   $("#submit").attr("disabled","disabled");
                   
                   $.ajax({
                       
                       type: "POST",
                       url: "senden.php",
                       data: {
      			ctrl_20: $("#ctrl_20").val(),
      			ctrl_21: $("#ctrl_21").val(),
      			ctrl_22: $("#ctrl_22").val(),
      			ctrl_23: $("#ctrl_23").val(),
      			ctrl_25: $("#ctrl_25").val()
      		},
                       
                       success: function(msg)
                          {
                            $("#form_index").addClass( "ausblenden");
                            $('#ctrl_20').val('');
                            $('#ctrl_21').val('');
                            $('#ctrl_22').val('');
                            $('#ctrl_23').val('');
      					  $('#ctrl_25').val('');
                            $("#response").html(msg);
      
                            setTimeout(function(){
      				$("#form_index").removeClass( "ausblenden");
      				$("#response").html("");
      		    }, 3000);
                          }
                      });
                  }
                     return false;
               });
      

      Indem du ihm das antwortest. Dazu solltest du dir eine Datenstruktur ausdenken, mit der du am Client die Daten den entsprechenden Eingabefeldern oder was auch immer zuordnen kannst.

      Dazu habe ich ja in meinem HTML bereits dieses Feld

      <p id="response"></p>
      

      Am besten erstellst du dazu ein (assoziatives) Array und packst das mit json_encode() ein. Dem jQuery.ajax auf der anderen Seite sagst du mittels dataType-Option, dass du JSON zurückschickst. Du bekommst dann ein fertig ausgepacktes Objekt, das du ohne weitere Schritte verwenden kannst.

      Ab hier verstehe ich leider gar nichts mehr :/ Hast du mir hier vielleicht ein kleines Beispiel?

      1. Tach!

        Am besten erstellst du dazu ein (assoziatives) Array und packst das mit json_encode() ein. Dem jQuery.ajax auf der anderen Seite sagst du mittels dataType-Option, dass du JSON zurückschickst. Du bekommst dann ein fertig ausgepacktes Objekt, das du ohne weitere Schritte verwenden kannst.

        Ab hier verstehe ich leider gar nichts mehr :/ Hast du mir hier vielleicht ein kleines Beispiel?

        Das was du mit dem PHP-Script auf die Ajax-Anfrage ausgibst, ist das was du am Client auswerten musst. Du kannst da einen Text antworten, aber wie wertest du den aus? Du willst ja zum Beispiel Fehlermeldungstexte schicken, die Feldern zugeordnet werden sollen. Wie aber erkennst du in einer Textwurst, welche Teile was bedeuten? Die Lösung ist, dass die Textwurst eine konkrete Struktur haben muss, beispielsweise mit | getrennte Texte. Das geht aber nur solange gut, bis ein | in den Daten auftaucht. Man kann sich nun selbst Maskierungsregeln ausdenken, um das Poblem zu lösen. Es gibt aber auch Datenaustauschformate, die schon lange im Einsatz sind, beispielsweise CSV, XML, JSON. Du packst am besten deine Daten (zum Beispiel ein Array mit den Meldungen) auf PHP-Seite in JSON ein und am Client wieder aus. jQuery übernimmt das auf Clientseite bereits für dich. PHP macht es dir aber auch nicht schwer:

        $result = [
          'errors' => [
             ['name' => 'feld1', 'messages' => ['meldung11', 'meldung12']],
             ['name' => 'feld2', 'messages' => ['meldung21', 'meldung22']],
          ],
          'anderes_zeug' => ...
        ];
        
        echo json_encode($result);
        

        Client:

        $.ajax({
          type: "POST",
          url: "senden.php",
          data: { ... },
          dataType: 'json',
        }).done(function (result) {
          console.log('alles auf einmal:');
          console.log(result);
        
          console.log('die fehler einzeln:');
          result.errors.forEach(function (item) {
            console.log(item.name);
            item.messages.forEach(function (message) {
              console.log(message);
            });
          });
        }).fail(function (xhr, status, error) {
          // was auch immer
          console.log(status);
          console.log(error);
        });
        

        dedlfix.

        1. Hallo,

          danke für deine sehr ausführliche Erklärung ist mir allerdings um einiges zu hoch. Ich bleibe erstmal bei meiner Version und hoffe dass keiner den Quelltext manipuliert. Im schlimmsten Falle habe ich eben jede Menge Spam Mails in meinem Postfach.

          1. Seit ich meine Mailformulare komplett auf Ajax umgestellt habe, kommt überhaupt kein Spam mehr. Könnte jedoch auch daran liegen, dass ich PUT als Request-Methode einsetze und alles Andere der Server abweist ;)

            1. Seit ich meine Mailformulare komplett auf Ajax umgestellt habe, kommt überhaupt kein Spam mehr. Könnte jedoch auch daran liegen, dass ich PUT als Request-Methode einsetze und alles Andere der Server abweist ;)

              Hallo hotti, ws, Klempo, Dag womit möchtest du angesprochen werden? Als Sockenpuppe machst du es dieser Leserschaft unnötig schwer.

  2. Du kümmerst Dich (mit einem umständlichen Code) nicht um das Percent-Encoding. Das ist schlecht. Nimm doch besser gleich JQuery.serialize() damit läuft das alles RFC-gerecht.

    Siehe auch: enctype="application/x-www-form-urlencoded"

    Klempo

    1. Hallo,

      funktioniert nicht, ich erhalte sofort folgende Meldung

      Failed to load resource: the server responded with a status of 500 (Internal Server Error)

      So hatte ich es auch schon

      $('#form_index').bind('submit', function() {
              var form = $('#form_index');
              var data = form.serialize();
              
      $.post('senden.php', data, function(response) {
                             
      });
         return false;           
      });   
      
      1. Hallo,

        funktioniert nicht, ich erhalte sofort folgende Meldung

        Failed to load resource: the server responded with a status of 500 (Internal Server Error)

        Hier wäre eine serverseitige Fehlersuche angebracht weil das ein serverseitiger Fehler ist.

        MfG

        1. Hallo,

          Hier wäre eine serverseitige Fehlersuche angebracht weil das ein serverseitiger Fehler ist.

          in der PHP Datei steht nur

          <?php
          echo "Test";
          ?>
          

          da gibt es nicht viel zu suchen. Nutze ich wieder mein Code, funktioniert alles wieder.

          1. Internal Server Error

            500 Internal Server Error is shown if your php code has fatal errors but error displaying is switched off. You may try this to see the error itself instead of 500 error page: Link s.o.

            1. 500 Internal Server Error is shown if your php code has fatal errors but error displaying is switched off. You may try this to see the error itself instead of 500 error page: Link s.o.

              Ich bleibe bei meinem Code bzw. ich schmeiße die ganze Ajax Scheiße wieder raus, macht nur Ärger und funktioniert nicht richtig.

              1. Hallo,

                in meinem ersten Script bin ich von der ID #ctrl_20 ausgegangen. In serialize() wird der name="" übergeben. Kein Wunder erhalte ich keine PHP eine Fehlerhafte Ausgabe.

                Edit:

                Mein jQuery Code sieht jetzt so aus

                $("#form_index").submit(function() {
                        
                        var form = $('#form_index');
                        var data = form.serialize();
                        
                		$.post('senden.php', data, function(msg) {
                		      $("#form_index").addClass( "ausblenden");
                                      $('#ctrl_20').val('');
                                      $('#ctrl_21').val('');
                                      $('#ctrl_22').val('');
                                      $('#ctrl_23').val('');
                                                          $('#ctrl_25').val('');
                                      $("#response").html(msg);
                
                                      setTimeout(function(){
                                                $("#form_index").removeClass( "ausblenden");
                                                $("#response").html("");
                                    }, 3000);         
                		});
                		   return false;           
                		});     
                
  3. @@Sara

      if($("#ctrl_20").val() == "" || $("#ctrl_21").val() == "" || $("#ctrl_22").val() == "" || $("#ctrl_25").val() == "")
    

    Wozu das denn? Wenn die Pflichtfelder richtig ausgezeichnet sind, d.h. ein required-Attribut haben, muss man doch nur abfragen, ob das Formular valide ausgefüllt ist:

    if(!$('#form_index').isValid())
    

    LLAP 🖖

    --
    Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
    1. Hallo,

      Wozu das denn? Wenn die Pflichtfelder richtig ausgezeichnet sind, d.h. ein required-Attribut haben, muss man doch nur abfragen, ob das Formular valide ausgefüllt ist:

      if(!$('#form_index').isValid())
      

      ich erhalte hier eine Fehlermeldung

      Alternativ-Text

      1. Hallo,

        auch diesen Fehler habe ich behoben (wenn ich es richtig verstanden habe)

        $.fn.isValid = function(){
            		return this[0].checkValidity()
        }
        
        $("#form_index").submit(function() {
        
             if(!$('#form_index').isValid()) {
             	$("#response").html("Bitte fülle alle Felder ausm die mit einem * versehen sind!");
          	 
          	 } else {
        
             var form = $('#form_index');
             var data = form.serialize();
             
             $("#submit").attr("disabled","disabled");
                
        		$.post('senden.php', data, function(msg) {
        		      $("#form_index").addClass( "ausblenden");
                              $('#ctrl_20').val('');
                              $('#ctrl_21').val('');
                              $('#ctrl_22').val('');
                              $('#ctrl_23').val('');
                              $('#ctrl_25').val('');
                              $("#response").html(msg);
        
                              setTimeout(function(){
                                        $("#form_index").removeClass( "ausblenden");
                                        $("#response").html("");
                            }, 3000);         
        		});
           }	  
        	 return false;           
        }); 
        
  4. @@Sara

    z.B. ein Formular abzuschicken ohne die Seite komplett neu zu laden. Ich persönlich finde dieses zwar totaler qatsch aber ok.

    Wenn das als progressive enhancement implementiert ist, das Formular also auch ohne JavaScript abgeschickt werden kann, ist das völlig OK, wenn’s denn dem Nutzer denn eine bessere UX bringt.

    if($("#ctrl_20").val() == "" || $("#ctrl_21").val() == "" || $("#ctrl_22").val() == "" || $("#ctrl_25").val() == "") { $("#response").html("Bitte fülle alle Felder ausm die mit einem * versehen sind!");

    Braucht man denn eine solche generelle Meldung? Was man braucht, sind Meldungen am betreffenden Eingabefeld à la „Bitte fülle dieses Feld aus“. Und dafür braucht man nicht unbedingt JavaScript; eine solche Medung kommt bei required-Feldern ohnehin.

    LLAP 🖖

    --
    Ist diese Antwort anstößig? Dann könnte sie nützlich sein.
    1. Hallo,

      Braucht man denn eine solche generelle Meldung? Was man braucht, sind Meldungen am betreffenden Eingabefeld à la „Bitte fülle dieses Feld aus“. Und dafür braucht man nicht unbedingt JavaScript; eine solche Medung kommt bei required-Feldern ohnehin.

      eigentlich braucht man diese Meldung nicht wie du schon richtig gesagt hast kann man dieses auch mit required machen wie ich es auch mache.

      <label for="ctrl_20">Ansprechpartner *</label>
      <input type="text" name="ansprechpartner" id="ctrl_20" value="" required>
      

      Allerdings gibt es ein paar Idioten die meinen die müssen z.B. mit dem Firebug den Code manipulieren und dann versuchen das Formular abzuschicken. Dann kommt die nächste Hürde :)

      Wenn auch dieses manipuliert wird, dann bitte! dedlfix hat mir gestern zwar eine Lösung gezeigt wie ich dieses Serverseitig machen kann, bekomme ich leider nicht hin.

      1. Hallo

        Braucht man denn eine solche generelle Meldung? Was man braucht, sind Meldungen am betreffenden Eingabefeld à la „Bitte fülle dieses Feld aus“. …

        Allerdings gibt es ein paar Idioten die meinen die müssen z.B. mit dem Firebug den Code manipulieren und dann versuchen das Formular abzuschicken. Dann kommt die nächste Hürde :)

        Soweit, so normal. Wer den HTML-Code mit Firebug (oder ähnlichen Werkzeugen) manipulieren kann, kann auf diesem Wege auch das JavaScript der Seite entfernen. An der Stelle greift die serverseitige Prüfung, die, wie dedlfix schon ansagte [1], auch bei einer vorherigen clientseitigen Prüfung zwingend erfolgen muss.

        Tschö, Auge

        --
        Es schimmerte ein Licht am Ende des Tunnels und es stammte von einem Flammenwerfer.
        Terry Pratchett, „Gevatter Tod“

        1. „Man kann einen Server immer auch zu Fuß kontaktieren und beliebige Daten hinschicken. Eine clientseitige Prüfung allein ist nicht ausreichend, weil diese umgangen werden kann.“ ↩︎

        1. Hallo,

          An der Stelle greift die serverseitige Prüfung, die, wie dedlfix schon ansagte [^1], auch bei einer vorherigen clientseitigen Prüfung zwingend erfolgen muss.

          richtig und ich würde dieses auch gerne nutze / umsetzuten. Wie ich es hier bereits geschrieben habe, bekomme ich es derzeit nicht hin, muss ich also erstmal damit leben.

          1. Hallo

            An der Stelle greift die serverseitige Prüfung, die, wie dedlfix schon ansagte [^1], auch bei einer vorherigen clientseitigen Prüfung zwingend erfolgen muss.

            richtig und ich würde dieses auch gerne nutze / umsetzuten. Wie ich es hier bereits geschrieben habe, bekomme ich es derzeit nicht hin, muss ich also erstmal damit leben.

            Nichts für ungut, aber: Nein! Wenn du die Übertragung und Prüfung mit Ajax momentan nicht hinbekommst, lasse sie weg. Die abschließende serverseitige Prüfung nach dem Absenden des Formulars wegzulassen, ist ein No-Go.

            Ich denke, wir kommen hier weiter, wenn du ansagst, was an dedlfix' Ausführungen du nicht verstehst.

            Er beschreibt den Aufbau der von PHP zu generierenden Antwort auf die Ajax-Anfrage. Diese erfolgt also vorher. Es wird ein die Eingaben verarbeitendes PHP-Skript aufgerufen und dieses soll nach der Verarbeitung der Daten eine Antwort zurückgeben, die in einer Status- oder Fehlermeldung und/oder weiteren Daten bestehen soll.

            Dedlfix' Vorschlag besteht nun darin, für die Antwort ein erprobltes und robustes Format zu benutzen. Er nennt CSV, XML und das von ihm präferierte JSON. Im ersten Codecontainer baut er mit PHP ein Array und daraus eine JSON-Nachricht zusammen und im zweiten Container liest er sie mit JavaScript/JQuery wieder aus und schreibt sie im Beispiel in die Konsole.

            Wo hakt es?

            Tschö, Auge

            --
            Es schimmerte ein Licht am Ende des Tunnels und es stammte von einem Flammenwerfer.
            Terry Pratchett, „Gevatter Tod“
            1. Hallo,

              Ich denke, wir kommen hier weiter, wenn du ansagst, was an dedlfix' Ausführungen du nicht verstehst.

              wenn ich ehrlich bin, verstehe ich gleich 0 :/ Also gehen wir mal von diesem jQuery Code aus

              $("#form_index").submit(function() {
              
                   if(!$('#form_index').isValid()) {
                   	$("#response").html("Bitte fülle alle Felder aus, die mit einem * versehen sind!");
                	 
                	 } else {
              
                	 var form = $('#form_index');
                   var data = form.serialize();
                   
                   $("#submit").attr("disabled","disabled");
                      
              		$.post('senden.php', data, function(msg) {
              		      $("#form_index").addClass( "ausblenden");
                                    $('#ctrl_20').val('');
                                    $('#ctrl_21').val('');
                                    $('#ctrl_22').val('');
                                    $('#ctrl_23').val('');
                                    $('#ctrl_25').val('');
                                    $("#response").html(msg);
              
                            setTimeout(function(){
                                    $("#form_index").removeClass( "ausblenden");
                                    $("#response").html("");
                                  }, 3000);         
              		});
              	}	  
              		 return false;           
              });          
              

              Dieser klappt auch. Jetzt kommt die senden.php mit ins Spiel. Um meine Mail zu versenden nutzte ich den Swiftmailer der auch im Wiki empfohlen wird.

              Dieses Script sieht so aus und funktioniert auch

              $data = array();
              
              	$data['smtp'] = array();
              	$data['smtp']['host'] = '';
              	$data['smtp']['port'] = '';
              	$data['smtp']['username'] = '';
              	$data['smtp']['password'] = '';	
              	
              	$data['from'] = array('name' => $_POST['ansprechpartner'], 'email' => $_POST['email']);
              	$data['to'] = array('name' => '', 'email' => '');
              	$data['charset'] = 'utf-8';
              	
              	$data['subject'] = "";
              	$data['ctrl_25'] = $_POST['nachricht'];
              	$data['ctrl_20'] = $_POST['ansprechpartner'];
              	$data['ctrl_21'] = $_POST['email'];
              	$data['ctrl_22'] = $_POST['telefon'];
              	$data['ctrl_23'] = $_POST['aufmerksam'];
              
              	$data['html'] = '
              	<html>
              		<head>
              			<title>'.$data['subject'].'</title>
              		</head>
              		<body>
              			<div>
              				<p>'.$data['ctrl_20'].'</p>
              				<p>'.$data['ctrl_21'].'</p>
              				<p>'.$data['ctrl_22'].'</p>
              				<p>'.$data['ctrl_23'].'</p>
              				<p>----------------------</p>
              				<p>'.nl2br($data['ctrl_25']).'</p>
              			</div>
              		</body>
              	</html>';
              
              
              	$smtp = new Swift_SmtpTransport($data['smtp']['host'], $data['smtp']['port']);
              	$smtp->setUsername($data['smtp']['username']);
              	$smtp->setPassword($data['smtp']['password']);
              	
              	$mail = new Swift_Message($data['subject']);
              	$mail->setBody($data['html'])
              		 ->setCharset($data['charset'])
              		 ->setContentType("text/html")
              		 ->setFrom($data['from']['email'], $data['from']['name'])
              		 ->setTo($data['to']['email'], $data['to']['name']);      
              	
              	$swift = new Swift_Mailer($smtp);
              	$swift->send($mail,$recipient);
              
              	echo 'OK';
              

              Wenn ich das ganze ohne jQuery abschicken würde, dann würde ich mein Script um folgendes erweitern

              $Fehler = array();
              
              if(empty($_POST['ansprechpartner'])) {
                          $Fehler[] = "Bitte geben Sie Ihren Namen an";
               }
              
              if(isset($_POST['abschicken']) && empty($Fehler)) {
                [Hier das Script von etwas weiter oben]
              }
              

              Klappt auch (ohne jQuery). Jetzt kommt eben mein Problem was ich nicht verstehe. Wenn in $Fehler etwas vorhanden ist, dann darf das Formular ja nicht abgeschickt werden, was es auch nicht macht aber der User sollte eine Rückmeldung erhalten dafür kann ich in meiner Index Datei

              <p id="response"></p>
              

              nutzten, wie ich es jetzt auch schon bei meiner Meldung mache, die ich erhalte wenn das Formular erfolgreich abgeschickt wurde. Außerdem dürfen die Anweisungen die in

              $.post('senden.php', data, function(msg) {
              }
              

              stehen nicht ausgeführt werden, wenn ein Fehler vorhanden sind. Und dieses ganze Zusammenspiel verstehe ich einfach nicht.

              1. Hallo

                Ich versuche das mal ohne Code in der Reihenfolge des Abläufe darzustellen.

                ##Absenden mit Ajax

                • Der Benutzer drückt den Submit-Button.
                • Das JS-Skript prüft daraufhin die Eingaben clientseitig (Vollständigkeit, evtl. Fehleingaben). Wir brauchen hier nur den Erfolgsfall betrachten.
                • Das JS-Skript erstellt im Erfolgsfall einen Datensatz, der an ein PHP-Skript gesendet wird.
                • Das PHP-Skript prüft die übermittelten Daten der Formulareingaben erneut und richtig™. Jetzt kommt die Verzweigung!
                  • Die Eingaben sind vollständig: speichern der Daten, versenden der Email, Rückgabe einer Erfolgsmeldung an das JS-Skript (Fehlercode, Text).
                  • Die Eingaben sind unvollständig oder (teilweise) falsch: kein speichern der Daten, kein Versand einer Email aber Rückgabe der Meldung über die Fehleingabe(n) (Fehlercode, Text).
                • Das JS-Skript empfängt die Rückgabe aus dem PHP-Skript und entscheidet über die bloße Ausgabe der Erfolgsmeldung oder den Hinweis auf Fehleingabe(n).

                ##Absenden ohne Ajax

                • Der Benutzer drückt den Submit-Button.
                • Der Inhalt des Formulars wird an ein PHP-Skript gesendet.
                • Das PHP-Skript prüft die übermittelten Daten der Formulareingaben. Auch hier kommt die Verzweigung.
                  • Die Eingaben sind vollständig: speichern der Daten, versenden der Email, Rückgabe einer Erfolgsmeldung als neu ausgelieferte Seite.
                  • Die Eingaben sind unvollständig oder (teilweise) falsch: kein speichern der Daten, kein Versand einer Email. Rückgabe der Meldung über die Fehleingabe(n) als erneute Auslieferung des Formulars mit Hinweisen auf zu korrigierende Felder.

                Schlussfolgerungen

                Im Browser gibt es keine Unterschiede bis auf die eventuell nicht stattfindende Ausführung des JS-Skripts. Der Unterschied ist die Behandlung der Formulareingaben auf dem Server. Gleich ist die Prüfung der Eingaben an sich und die Aktionen speichern und E-Mail versenden. Unterschiedlich ist die Entgegennahme der Daten und die Art der Rückgabe an den Benutzer/Browser. Es gibt also Teile des PHP-Codes, die in beiden Fällen benutzt werden und welche, die bei einer Art des Versands benutzt, bei der anderen Art aber nicht benutzt werden.

                An der Stelle lohnt es sich, über die Ansprache zweier Skripte nachzudenken, die ihrerseits auf identische Codeteile in einem weiteren Skript zugreifen (Auslagerung von Code in Funktionen oder Aufruf des gemeinsam genutzten Codes über require_once).

                Tschö, Auge

                --
                Es schimmerte ein Licht am Ende des Tunnels und es stammte von einem Flammenwerfer.
                Terry Pratchett, „Gevatter Tod“
                1. Hallo,

                  danke für deine Erklärung die mir leider 0 weiterhilft und genau das ist auch das Problem dieses Forums. Es wird Seitenweise erklärt und geschrieben aber ohne Beispiele bringt dieses gleich 0, das war früher schon in der Schule (beim Lehrer an der Tafel als auch in den Büchern) der Fall.

                  Daher bleibe ich bei meiner Aussage von gestern Abend, ich lass es einfach so wie es jetzt ist muss damit leben dass eben Spam durchkommt.

                  1. Hallo,

                    jetzt will ich es doch wissen. Bis jetzt habe ich irgendwie alles hinbekommen. Sorry wenn ich gerade vielleicht etwas gereizt reagiert habe.

                    Mein jQuery Code sieht nun so aus

                    	 $("#form_index").submit(function() {
                    
                      	var form = $('#form_index');
                             var data = form.serialize();
                         
                        $("#submit").attr("disabled","disabled");
                            
                    	$.post('senden.php', data, function(msg) {
                    
                            if(msg == "success"){ 
                    
                    	    $("#form_index").addClass( "ausblenden");
                                $('#ctrl_20').val('');
                                $('#ctrl_21').val('');
                                $('#ctrl_22').val('');
                                $('#ctrl_23').val('');
                                $('#ctrl_25').val('');
                                $("#response").html(msg);
                    
                                setTimeout(function(){
                                  $("#form_index").removeClass( "ausblenden");
                                  $("#response").html("");
                                }, 3000);         
                    		} else {
                    
                          $("#response").html("TEST");
                        }
                      });
                    		   return false;           
                    		}); 
                    

                    Neu ist dieser Bereich

                    if(msg == "success"){ 
                    } else {
                    }
                    

                    In meiner PHP Datei habe ich folgendes eingefügt

                    if(empty($_POST['ansprechpartner'])) {
                                $Fehler[] = "Bitte geben Sie Ihren Namen an";
                     }
                    
                    if(isset($_POST['abschicken']) && empty($Fehler)) {
                     [Hier der eMail versand]
                     echo "success";
                    } 
                    

                    Wenn alles Ok ist, erhalte ich success zurück und kann damit weiter arbeiten (siehe Code oben) wenn nicht, erhalte ich nichts zurück und er das Script geht in diesen Bereich

                    else {
                     $("#response").html("TEST");
                    }
                    

                    Klappt auch. Aber jetzt möchte ich entweder die Felder rot markieren oder Ausgeben lassen was falsch ist. Nur wie kann ich dieses jetzt machen?

                    1. Korrektur im PHP Code ein Posting weiter oben hat sich ein Fehler eingeschlichen, ich darrf nur so prüfen

                      if(empty($errors)) {
                      }
                      

                      Hatte es erst so, da kam aber immer "fail" raus

                       if(isset($_POST['abschicken']) && empty($errors)) {
                      }
                      

                      Die Frage aus dem Posting darüber bleibt natürlich gleich.

                      PS: Ich finde es ganz schlimm, dass man seine Beiträge nicht länger bearbeiten kann, das ganze macht es so unübersichtlich :/ Habe ich bis jetzt in keinem Forum gehen.

                      1. Hallo,

                        ich muss mich langsam vorantasten und den Code von dedlfix verstehe ich leider noch immer nicht, ist für mich wie ein Buch mit 7 Siegel, vor allem der JS Code. Und da man hier seine Meinung nicht schreiben darf lass ich es einfach bleiben.

                        Daher habe ich eine andere Lösung, sobald ein Fehler auftritt, wird das Script abgebrochen

                        if($_POST['ansprechpartner'] == ''){exit ("ctrl_20");}
                        

                        Und im jQuery Code füge ich dieses hinzu

                        $("#" + msg).css({"border": "#F00 1px solid"}); 
                        

                        Damit erreiche ich dass das besagte Feld rot wird.

                        Bin ich damit auf der sicheren Seite?

                        1. Tach!

                          ich muss mich langsam vorantasten und den Code von dedlfix verstehe ich leider noch immer nicht, ist für mich wie ein Buch mit 7 Siegel, vor allem der JS Code. Und da man hier seine Meinung nicht schreiben darf lass ich es einfach bleiben.

                          Du darfst deine Meinugn schon schreiben, nur bringt es dir nichts, wenn sich dann die Helfer zurückziehen. Deine Meinung zu schreiben ist beim Lernen auch nicht sonderlich hilfreich. Besser wäre, wenn du den Code soweit zu verstehen versuchst, wie es geht und die Stellen konkret benennst, die du nicht verstehst. Dann kann man da nachhaken, ansonsten nur mit den Schultern zucken.

                          dedlfix.

                          1. Hallo,

                            Besser wäre, wenn du den Code soweit zu verstehen versuchst, wie es geht und die Stellen konkret benennst, die du nicht verstehst. Dann kann man da nachhaken, ansonsten nur mit den Schultern zucken.

                            ich habe es gestern Abend bereits geschrieben, ich verstehe deinen sehr komplizierten Code nicht. Was soll ich noch dazu schreiben? Wenn ich es nicht verstehe, verstehe ich es nicht kann also auch nichts weiter dazu schreiben.

                            1. Tach!

                              ich habe es gestern Abend bereits geschrieben, ich verstehe deinen sehr komplizierten Code nicht. Was soll ich noch dazu schreiben? Wenn ich es nicht verstehe, verstehe ich es nicht kann also auch nichts weiter dazu schreiben.

                              Ich glaube dir nicht, dass du nicht ein Fitzelchen davon verstehst. Das würde bedeuten, dass du überhaupt kein Javascript verstehst.

                              Mal so als Beispiel: Du verstehst sicher, was ein if macht. Du verstehst natürlich auch, was der Ausdruck in den ()-Klammern danach macht. Du verstehst garantiert, was msg == 'success' bedeutet. Das hast du ja selbst geschrieben und ich hab es nur wiederholt. Du verstehst vielleicht nicht, was typeof msg == 'object' bedeutet. Also sag dann konkret, dass du diesen Teil nicht verstehst. Ich kann versuchen, diesen Teil zu erläutern, aber ich kann nicht jedes Zeichen einzeln erklären.

                              dedlfix.

                              1. Hallo,

                                bleiben wir bei diesem Code von gestern Abend:
                                Linkbeschreibung

                                $result = [
                                  'errors' => [
                                     ['name' => 'feld1', 'messages' => ['meldung11', 'meldung12']],
                                     ['name' => 'feld2', 'messages' => ['meldung21', 'meldung22']],
                                  ],
                                  'anderes_zeug' => ...
                                ];
                                
                                echo json_encode($result);
                                

                                Ich verstehe z.B. schon mal nicht, was du mit den ganzen Felder meinst, Warum muss das alles so kompliziert und umständlich sein und wie könnte ich diese mit meinem Beispiel füllen?

                                Warum reicht es nicht einfach so

                                if($_POST['ansprechpartner'] == ''){exit ("ctrl_20");}
                                if($_POST['email'] == ''){exit ("ctrl_21");}
                                if($_POST['nachricht'] == ''){exit ("ctrl_25");}
                                

                                Dann kommen wir zu deinem JS Code

                                $.ajax({
                                  type: "POST",
                                  url: "senden.php",
                                  data: { ... },
                                  dataType: 'json',
                                }).done(function (result) {
                                  console.log('alles auf einmal:');
                                  console.log(result);
                                
                                  console.log('die fehler einzeln:');
                                  result.errors.forEach(function (item) {
                                    console.log(item.name);
                                    item.messages.forEach(function (message) {
                                      console.log(message);
                                    });
                                  });
                                }).fail(function (xhr, status, error) {
                                  // was auch immer
                                  console.log(status);
                                  console.log(error);
                                });
                                

                                Bei deinem data: { ... }, kommt wahrscheinlich mein var data = form.serialize(); also in diesem Fall data: data, den Rest von deinem Code verstehe ich nicht und schon gar nicht verstehe ich, wie ich diesen in meinen Code intergrieren soll

                                $("#form_index").submit(function() {
                                
                                     var form = $('#form_index');
                                     var data = form.serialize();
                                     
                                    $("#submit").attr("disabled","disabled");
                                        
                                	$.post('senden.php', data, function(msg) {
                                
                                        if(msg == "success"){ 
                                
                                	    $("#form_index").addClass( "ausblenden");
                                            $('#ctrl_20').val('');
                                            $('#ctrl_20').css({"border": "none"});
                                            $('#ctrl_21').val('');
                                            $('#ctrl_21').css({"border": "none"});
                                            $('#ctrl_22').val('');
                                            $('#ctrl_23').val('');
                                            $('#ctrl_25').val('');
                                            $('#ctrl_25').css({"border": "none"});
                                            $("#response").html('<img src="accept.gif">Danke!');
                                            $(".hinweis").addClass( "ausblenden");
                                
                                            setTimeout(function(){
                                              $("#form_index").removeClass( "ausblenden");
                                              $(".hinweis").removeClass( "ausblenden");
                                              $("#response").html("");
                                            }, 3000);         
                                		    
                                        } else {
                                            $("#" + msg).css({"border": "#F00 1px solid"}); 
                                        } 
                                
                                    });
                                		   return false;           
                                	});
                                
                                1. Tach!

                                  $result = [
                                    'errors' => [
                                       ['name' => 'feld1', 'messages' => ['meldung11', 'meldung12']],
                                       ['name' => 'feld2', 'messages' => ['meldung21', 'meldung22']],
                                    ],
                                    'anderes_zeug' => ...
                                  ];
                                  
                                  echo json_encode($result);
                                  

                                  Ich verstehe z.B. schon mal nicht, was du mit den ganzen Felder meinst, Warum muss das alles so kompliziert und umständlich sein und wie könnte ich diese mit meinem Beispiel füllen?

                                  Das ist so "kompliziert und umständlich", damit es einerseits die fachlichen Anforderungen erfüllt und andererseits an anderer Stelle sehr leicht zu handhaben ist. Ich baue diese verschachtelte Struktur in der Variable $result zusammen, damit ich diese mit einem einzigen json_encode() versandsicher verpacken kann und damit sie auf der Empfängerseite ordnungsgemäß gelesen und weiterverarbeitet werden kann.

                                  Das 'anderes_zeug' ersetze ich mal durch 'status' und dann sieht das Ergebnis nach dem json_encode() wie folgt aus:

                                  {
                                      "errors": [
                                          {
                                              "name": "feld1",
                                              "messages": [
                                                  "meldung11",
                                                  "meldung12"
                                              ]
                                          },
                                          {
                                              "name": "feld2",
                                              "messages": [
                                                  "meldung21",
                                                  "meldung22"
                                              ]
                                          }
                                      ],
                                      "status": "failed"
                                  }
                                  

                                  Das ergibt dann nach dem Auspacken durch jQuery ein Objekt mit den beiden Eigenschaften errors und status. status kannst du auslesen, um zu erkenenn, ob es Fehler gab oder nicht. Andererseits kann man das auch weglassen und schauen, ob errors leer oder gefüllt ist. errors ist ein Array, das für jedes (fehlerhafte) Feld einen Eintrag hat. Durch dieses Array kann man laufen den Namen des Feldes daraus lesen und die zugehörigen Meldungen. Damit kann man dann zum Feld gehen und machen, was immer man machen will.

                                  Ich habe zwei Meldungen als Beispiel genommen. Vielleicht brauchst du in deinem Fall nur eine, wenn du nur auf "ist nicht leer" prüfen möchtest. Die Erfahrung zeigt aber, dass es oftmals nicht bei einer solchen einfachen Prüfung bleibt und man mehrere Kriterien auswerten muss. Die erzeugen dann auch mehrere potentielle Meldungstexte.

                                  Warum reicht es nicht einfach so

                                  if($_POST['ansprechpartner'] == ''){exit ("ctrl_20");}
                                  if($_POST['email'] == ''){exit ("ctrl_21");}
                                  if($_POST['nachricht'] == ''){exit ("ctrl_25");}
                                  

                                  Weil im Fehlerfall das erste exit deine Auswertung beendet. Damit kannst du dem Anwender das entsprechende Feld markieren, aber ein Meldungstext ist nicht dabei. Falls er erraten hat, was falsch sein könnte, kann er den Feldinhalt dann auch korrigieren, nur um beim zweiten Absenden an einem anderen Feld hängenzubleiben. Er muss unter Umständen für jeden einzelnen Fehler eine Extra-Runde drehen. Mit meiner Struktur können alle Fehler auf einmal ermittelt und im Paket zur Verbesserung vorgelegt werden. Diese Struktur soll nicht mit einer einzigen Anweisung zusammengebaut werden, der Code sollte nur zeigen, wie sie am Ende aussehen muss. Vielmehr wird jeder Fehler durch deine Prüfungen einzeln festgestellt und die Struktur Stück für Stück ergänzt.

                                  $.ajax({
                                    type: "POST",
                                    url: "senden.php",
                                    data: { ... },
                                    dataType: 'json',
                                  }).done(function (result) {
                                    console.log('alles auf einmal:');
                                    console.log(result);
                                  
                                    console.log('die fehler einzeln:');
                                    result.errors.forEach(function (item) {
                                      console.log(item.name);
                                      item.messages.forEach(function (message) {
                                        console.log(message);
                                      });
                                    });
                                  }).fail(function (xhr, status, error) {
                                    // was auch immer
                                    console.log(status);
                                    console.log(error);
                                  });
                                  

                                  Bei deinem data: { ... }, kommt wahrscheinlich mein var data = form.serialize(); also in diesem Fall data: data, den Rest von deinem Code verstehe ich nicht und schon gar nicht verstehe ich, wie ich diesen in meinen Code intergrieren soll

                                  Der Rest vom Code wird ausgeführt, wenn der Ajax-Call fertig ist. Der done-Teil im Gut-Fall, der fail-Teil, wenn das Ajax den Server nicht kontaktieren konnte. Dass done und fail hinter der ajax-Methode hängen und nicht wie url oder data oder success übergeben wurden, ist lediglich eine andere Art und Weise, wie jQuery den Umgang mit diesen Handlern ermöglicht. Den fail-Teil kannst du weglassen, aber dann passiert nichts im Falle eines Fehler. Der Nutzer bekommt dann aber keine Reaktion und weiß nicht, dass sein Kontaktversuch misslungen ist. Das ist nicht besonders anwenderfreundlich. Man muss eigentlich immer mit Fehlern rechnen und sich überlegen, was man in dem Fall tun möchte. Und ja, das kann ein Programm um ein Vielfaches verlängern, als wenn man nur von bestem Kaiserwetter ausgeht. Die Funktion in done() ist das was du über den Parameter success übergeben hattest, beziehungsweise nach deinem Umstieg auf $.post() als dessen dritter Parameter.

                                  In result jedenfalls steht die oben gezeigte Struktur, so wie sie mit PHP erstellt wurde, aber quasi übersetzt in Javascript-Objekt/Array, denn jQuery hat das, was ich mit json_encode() eingepackt habe, bereits wieder ausgepackt. Die console.log()-Ausgaben sollten zeigen, wie man auf die Einzelteile zugreifen kann. Mit der Zeile

                                  result.errors.forEach(function (item) {

                                  laufe ich über das Array mit den Fehlermeldungen. Für jedes (fehlerhafte) Eingabefeld wird die Funktion aufgerufen und in item steht der Datensatz zu einem Feld. In item.name ist der Feldname zu finden, in item.messages ein weiteres Array mit den Meldungstexten (wenn es mehrere Fehler gegeben hat). Die Meldungen könntest du in der Nähe der Felder anzeigen lassen.

                                  Eine radikale Vereinfachung wäre, wenn du die Fehlermeldungstexte alle nacheinander in einen einzelnen String hängen würdest. Dann hast du sozusagen einen Roman, den du ohne weiteres so wie deine bisherige success-Message übertragen kannst. Und den kannst du zum Beispiel über oder unter dem Formular anzeigen. Nur ist das nicht besonders anwenderfreundlich, weil der sich dann selbst zusammensuchen muss, zu welchem Feld nun welcher Teil des Meldungsromans gehört. Mit diesem Roman weißt auch du nicht, auf welche Felder er sich bezieht und kannst diese nicht markieren. Deswegen ist meine Lösung eine "komplizierte und umständliche" Struktur, damit man alle benötigten Daten transportieren kann, um dem Anwender die bestmögliche Lösung bieten zu können und nicht er "kompliziert und umständlich" vorgehen muss, um das Formular abschicken zu können.

                                  dedlfix.

                    2. Tach!

                      Aber jetzt möchte ich entweder die Felder rot markieren oder Ausgeben lassen was falsch ist. Nur wie kann ich dieses jetzt machen?

                      Du musst dazu statt des "success" die Namen der Felder und die dazugehörigen Nachrichtentexte an den Browser schicken. Das Problem dabei ist, wie du das so schickst, dass dum Im Browser erkennen kannst, was Name und was zugehöriger Text ist, damit du daraufhin die Elemente ansprechen kannst.

                      Zunächst einmal, musst du dir auf der Serverseite die benötigten Informationen zusmamensammeln. Ein einfaches $Fehler-Array reicht dazu nicht, denn da stehen nur die Texte und noch keine Feldnamen dabei. Außerdem musst du dir überlegen, ob du pro Feld immer nur maximal eine Nachricht ausgeben können möchtest, oder ob es beliebig viele Nachrichten sein sollen. Dementsprechend muss erstmal die Datenstruktur zum Sammeln der Fehler aussehen.

                      $Fehler = [
                        'feldname1' => 'text1',
                        'feldname2' => 'text2'
                      ];
                      
                      $Fehler = [
                        'feldname1' => ['text11', 'text12'],
                        'feldname2' => ['text21', 'text22'],
                      ];
                      

                      Alternativ kannst du auch die schon gezeigte Struktur nehmen.

                      Diese schöne Struktur jedenfalls muss nun zum Browser. Und sie wird dir vom jQuerys post() auch bereits ausgepackt und weiterverarbeitungsgerecht zur Verfügung gestellt, wenn du sie "richtig" einpackst, was in dem Fall JSON heißt.

                      // Variante mit nur einem Text
                      $.post('senden.php', data, function(msg) {
                        if(msg == "success"){ 
                          // ...
                        } else if (typeof msg == 'object') {
                          Object.keys(msg).forEach(function (key) {
                            var text = msg[key];
                            $('#'+key).append($('<span>').text(text));
                          });
                        }
                      });
                      

                      Das sollte funktionieren, aber schön ist das noch nicht. Denn im Gut-Fall gibt das PHP-Script einen String, im Fehlerfall ein JSON-Objekt zurück. jQuery versucht das zwar entsprechend dem Inhalt zu erraten, doch besser wäre es, wenn es in beiden Fällen JSON wäre.

                      Die Struktur kann dazu auf PHP-Seite wie folgt aussehen.

                      $result = [
                        'status' => 'success', // oder 'failed'
                        'errors' => [
                          'feldname1' => 'text1',
                          'feldname2' => 'text2'
                        ]
                      ];
                      

                      Und das Javascript muss dazu noch entsprechend angepasst werden.

                      dedlfix.