Wie benutzt man jQuery’s $.ajax() Funktion

Registrierer

Erfahrenes Mitglied
Ich hatte mein Problem bereits in php.de geschildert, leider rutscht das Thema nun ohne Antwort immer weiter nach hinten. Ich hoffe, ich verstoße nicht gegen die guten Sitten, wenn ich hier nochmal nachfrage.

Ich habe:
PHP:
<!DOCTYPE html>
<html>
 <head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <script type="text/javascript">
    $(document).ready(function() {
     function anzeige(){
      var arr = $.map($('input:checkbox:checked'), function(e, i) {
      return +e.value;
     });
     $('span').text('' + arr.join(','));
     var str = "";
     str = str + arr.join(','); // für die weitere Verwendung
     $.ajax({
      url: "ajax_index.php",
      data: {jahre: str},
      type: "POST",
      success: function(data) { ShowMsg(data); }
     });
    }
    anzeige();
    $('form').delegate('input:checkbox', 'click', anzeige);
   });
   function ShowMsg(data) {
    var response = $.parseJSON(data);
    document.getElementById("outputAll").innerHTML = response;
   }
  </script>
</head>
<body>
 <form>
  <input type="checkbox" value="2000" name="jahr[]">2000<br>
  <input type="checkbox" value="2001" name="jahr[]">2001<br>
  <input type="checkbox" value="2002" name="jahr[]">2002<br>
 </form>
 <span></span>
 <div id="outputAll">&nbsp;</div>
 </body>
</html>
ajax_index.php:
PHP:
<?PHP
include ('datenbankverbindung.php');
echo "<pre>". print_r($_POST, true) ."</pre>";
$ergebnis = $pdo->query("SELECT JAHR FROM rechnungen WHERE JAHR IN (".implode(",", $_POST['jahre']).") GROUP BY JAHR");
while ($ergebnis_suche = $ergebnis->fetch()) {
 echo 'Jahre: '.$ergebnis_suche['JAHR'].'<br>';
}
?>
Der Teil im $.ajax wird aber offensichtlich nicht ausgeführt, und ich komme nicht dahinter warum?

Ziel ist es, dass alle geklickten Kontrollkästchen durch Komma getrennt in ein array gepackt werden, und dieses wiederum asyncron die DB Abfrage aktualisiert.

Am Ende soll ein Liniendiagramm mit den Daten gefüttert werden und schnelle Vergleiche ermöglichen.
 
Hallo,

du gibst höchstwahrscheinlich kein gültiges JSON aus. Speicher alle Ergebnisse in einem Array uns lass es am Ende (d. h. nach der while-Schleife!) durch json_encode() laufen.

Außerdem solltest du via DevTools die Anfrage sowie die Antwort des Servers überprüfen (wie Bodo in deinem Crossposting schrieb)
 
Speicher alle Ergebnisse in einem Array uns lass es am Ende (d. h. nach der while-Schleife!) durch json_encode() laufen.

Außerdem solltest du via DevTools die Anfrage sowie die Antwort des Servers überprüfen

Du meinst die Ergebnisse der DB Abfrage in der ajax_index.php? Da gibt es ja leider keine.
PHP:
$ergebnis = $pdo->query("SELECT JAHR FROM rechnungen WHERE JAHR IN (".implode(",", $_POST['jahre']).") GROUP BY JAHR");
while ($ergebnis_suche = $ergebnis->fetch()) {
 $testarray[]  = $ergebnis_suche['JAHR'];
}
$fertig = json_encode($testarray);
echo $fertig;

Methode: POST
Angefragte Adresse: ajax_index.php
Die Netzwerkanalyse sagt Status Code 200 OK.
Parameter Formulardaten: jahre: "2000,2001,2002" wenn alle 3 markiert sind

Werden die Daten so tatsächlich angefragt? Ich bin mir da unsicher.
 
Ich bin jetzt sicher, dass die Daten korrekt in der ajax_index.php ankommen. Wenn ich GET verwende, werden die Parameter mitgesendet: ajax_index.php?jahre=2000,2001,2002
Die DB Abfrage habe ich mal um diese Fehelerquelle auszuschließen händisch in
PHP:
$ergebnis = $pdo->query("SELECT JAHR FROM rechnungen WHERE JAHR IN (2000,2001,2003) GROUP BY JAHR");
geändert, welche auch 3 richtige Ergebnisse liefert.

Trotzdem erhalte ich keine Ausgabe. Woran kann das jetzt noch liegen?
 
Fünf Anmerkungen:

  • Korrigiere deine Einrückungen im Java-Script-Code und du wirst feststellen, dass die Klammer-Setzung anscheinend nicht passt. Da man jedoch Funktionen aus den globalen Scope rausnehmen kann, dürfte es dennoch funktionieren, wie es jetzt da steht. Sicher bin ich da aber nicht. Ich würde den Funktionscode dennoch allein der Übersichtlichkeit halber aus der document.ready-Funktion rausnehmen.
  • Du legst keinen dataType für den Ajax-Call fest. Abhängig davon, was dein Server auf den Call hin ausliefert, kannst du den dataType auf "json", "jsonp", "xml", "html", "script" oder "text" setzen. Näheres hier: http://api.jquery.com/jquery.ajax/
  • Wenn du als dataType "json" festlegst, dürfte sich der parseJSON-Aufruf im Callback erübrigen.
  • Setze mal probehalber den async-Parameter auf false.
  • Baue in das success-Callback "ShowMsg" mal ein alert(data); ein, um direkt zu sehen, was da drin steht. Könnte mir vorstellen, dass da "object" (wegen dem parseJSON-Aufruf) zurück kommt. In diesem Falle rate ich zum Einsatz von Firebug um das Callback zu debuggen. Denn dann wirst du für die Ausgabe auf ein Kind-Element von "data" zugreifen müssen.

Hier mal ein bisschen Code:

Javascript:
    function ShowMsg(data) {
      //var response = $.parseJSON(data);
      document.getElementById("outputAll").innerHTML = data;
    }

    function anzeige(){
      var arr = $.map($('input:checkbox:checked'), function(e, i) {
        return +e.value;
      });
    
      $('span').text('' + arr.join(','));
      var str = "";
      str = str + arr.join(','); // für die weitere Verwendung
    
      $.ajax({
        url: "ajax_index.php",
        data: {jahre: str},
        type: "POST",
        async: false,
        dataType: "json",
        success: function(data) { ShowMsg(data); }
      });
    }
  
    $(document).ready(function() {
      anzeige();
      $('form').delegate('input:checkbox', 'click', anzeige);
    });

Und eine Anmerkung zum Schluss: Der Einsatz eine error-Callbacks ist in den meisten Fällen durchaus anzuraten.
 
Hier noch eine ajax_index.php zum Testen davon:

PHP:
<?php

header('Content-Type: application/json');

echo json_encode($_POST['jahre']);

PS: Kannst das async dann natürlich wieder auf true setzen.

Edit: Habe das implode rausgenommen. Das passte nur zu meiner Variante der HTML-Seite. So wird es aber mit dem Code von saftmeister klappen.
 
Vielen Dank für die ausführliche Antworten.

Hier jetzt eine funktionierende Version.
Ich kann bei der Klammersetzung keinen Fehler erkennen?
Auf die Variable str habe ich verzichtet und statt dessen data: {jahre: arr} genommen.
Sollte im (document).ready Teil wirklich nur so wenig stehen?
Muß oder sollte man den Datentyp zwingend festlegen?
$.parseJSON(data) verursachte, dass keine Anzeige kam. Da half auch dataType: "json" nicht.
Übrigens ist alert() ein hervorragendes Mittel um zu sehen wo es hängt ;-)
PHP:
<!DOCTYPE html>
<html>
 <head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <script type="text/javascript">
   $(document).ready(function() {
    $('form').delegate('input:checkbox', 'click', anzeige);
   });
   function ShowMsg(data) {
    var response = data;
    document.getElementById("outputAll").innerHTML = response;
   }
   function anzeige(){
    var arr = $.map($('input:checkbox:checked'), function(e, i) {
     return +e.value;
   });
   $.ajax({
    url: "ajax_index.php",
    data: {jahre: arr},
    type: "POST",
    success: function(data) {
     ShowMsg(data);
    }
   });
  }
  </script>
 </head>
 <body>
  <form>
   <input type="checkbox" value="2000" name="jahr[]">2000<br>
   <input type="checkbox" value="2001" name="jahr[]">2001<br>
   <input type="checkbox" value="2002" name="jahr[]">2002<br>
  </form>
  <div id="outputAll">&nbsp;</div>
 </body>
</html>
ajax_index.php:
PHP:
<?PHP
include ('datenbankverbindung.php');
if (isset($_POST['jahre']) && $_POST['jahre'] > 1999)  {
 foreach ($_POST['jahre'] as $val) {
  $jahre[] = intval($val);
 }
 $ergebnis = $pdo->query("SELECT JAHR FROM haase_rechnungen WHERE JAHR IN (".implode(",", $jahre).") GROUP BY JAHR");
 while ($ergebnis_suche = $ergebnis->fetch()) {
  echo $ergebnis_suche['JAHR']."<br>\n";
 }
}
?>
Ich hab mich bisher nur mit PHP beschäftigt und tat mich bisher schwer mit JS & Co.
Man verzeihe mir meine einfachen Fragen ;-)
Da fällt mir ein: error-Callbacks in JS, was tut man da üblicherweise? alert, exit?
 
Ich meinte damit nur, dass dein document.onready-Callback sehr viel Code enthält der in Funktionen gepackt ist. Das ist zwar möglich und syntaktisch ok, aber der Leserlichkeit des Codes leistet es keine guten Dienste. Eine Funktion sollte IMHO für sich allein stehen oder in ein Prototyp gepackt werden, um sie als Objekt-Methode zu verwenden. Das beantwortet auch gleich deine zweite Frage.

Der Datentyp sollte festgelegt werden. Es ist einfach sauberer, man sieht auch sofort ohne es prüfen zu müssen, was vom Server als Typ zurück kommen wird. In einem halben Jahr stößt du dann wieder auf einen Fehler im Code oder musst was umbauen und fängst wieder von vorn an zu prüfen, was denn jetzt vom Server kommt.

alert() als Debugging einzusetzen ist genauso wie echo in PHP-Code für das Debugging zu verwenden. Eigentlich nur quick&dirty. Besser ist richtiges Debugging, JS bspw. via Firebug.

Ein error-Callback KANN muss aber nicht alert() verwenden. Du könntest stattdessen ein Div einbauen, das standardmäßig keinen Inhalt hat und nicht zu sehen ist. Im Fehlerfall schreibst du den Fehler-Text da rein und lässt es nach einigen Sekunden ausblenden. Hier ein Beispiel wie man das mit jquery machen kann: http://stackoverflow.com/a/21556942 Macht einen professionellen Eindruck und erfüllt seinen Zweck.
 
Ich kann bei der Klammersetzung keinen Fehler erkennen?

War auch keiner, dachte ich aber euch erst, weil die Einrückung ziemlich irreführend war. Das sehe ich bei deinem letzten Code-Posting übrigens auch wieder so. Ich finde das unnötig schwer lesbar. Konkret lese ich da wegen der Einrückung erst mal:

Code:
$(document).ready(function() {
    $('form').delegate('input:checkbox', 'click', anzeige);
});

function ShowMsg(data) {
    var response = data;
    document.getElementById("outputAll").innerHTML = response;
}

function anzeige(){
    var arr = $.map($('input:checkbox:checked'), function(e, i) {
        return +e.value;
    });
}

$.ajax({
    url: "ajax_index.php",
    data: {jahre: arr},
    type: "POST",
    success: function(data) {
        ShowMsg(data);
    }
});

Ich weiß, dass das nicht das ist, was da steht, aber so sieht es halt aus.

Auf die Variable str habe ich verzichtet und statt dessen data: {jahre: arr} genommen.

Gut.

(Wenn ich zu einem Punkt nichts sage, ist das Zustimmung zu saftmeister.)

$.parseJSON(data) verursachte, dass keine Anzeige kam. Da half auch dataType: "json" nicht.

Das hatte saftmeister in seinem Beispiel allerdings so korrigiert, dass es mit JSON funktioniert.

JSON ist grundsätzlich eine gute Wahl, weil du damit eben auch komplexere Datenstrukturen austauschen kannst und nicht – wie du es jetzt hast – nur Strings.

console.log ist noch eine ganz gute Alternative zu alert. Damit werden die Infos in die JS-Console des Browsers geschrieben. Dann musst du sie nicht ständig wegklicken. (Vor dem Veröffentlichen des Projekts aber in jedem Fall wieder rausnehmen, da das kein Standardfeature von JavaScript ist und deshalb in manchen Browsern nicht funktioniert.)

- https://developer.mozilla.org/en-US/docs/Web/API/Console/log
 
Danke Euch beiden!
Strings sind hier tatsächlich keine gute Wahl.
Wenn ich den Datentyp allerdings auf json festlege, und in der Funktion ShowMsg(data) $.parseJSON(data) schreibe (oder auch nicht), erhalte ich wieder keine Anzeige.
In der Netzwerkanalyse werden aber die Parameter und auch die Antwort in allen Fällen korrekt angezeigt. (Verstehe ich nicht).
Die Konsole gibt mir in allen Fällen: TypeError: invalid 'instanceof' operand scc


Ist die Einrückung subjektiv zu betrachten, oder gibt es dafür Regeln? Wie würdet Ihr das machen?
Die Konsole ist ja mächtig Mächtig ;-)
 

Neue Beiträge

Zurück