# php und Ajax



## ChrisRoo (26. Januar 2019)

Hallo zusammen,

ich bin neu hier und beschäftige mich normalerweise mit Mikrocontrollern. Nun habe ich aber ein Projekt gestartet, bei dem ich gewisse Zustände von Sensoren in einer Website visualisieren möchte. Hierzu lade ich über ein Webinterface eine Datenbank mit Informationen.
Meine Website greift mittels PHP (mysqli-query) auf die Datenbank zu und lädt ein paar php - variablen mit 0 oder 1.

Ich möchte nun, dass die variablen jede Sekunde gecheckt werden. Bei einer Änderung von 0 auf 1 soll ein GIF-Bild dynamisch (ohne reload der Site) und absolut auf der Website positioniert angezeigt werden. Wenn die Varable von 1 auf 0 geht, dann soll das Bild wieder verschwinden - natürlich wieder ohne reload.

Ich denke, mit Ajax und jquery bin ich schon auf dem richtigen Weg. Nur leider habe ich noch nicht damit gearbeitet und habe überhaupt keine Ahnung wie so eine function aussehen müsste.

Vielleicht hat jemand eine Lösung für mich parat.
Danke und viele Grüße
Chris


----------



## Sempervivum (26. Januar 2019)

Ja, mit Ajax und jQuery bist Du schon auf dem richtigen Wege. Hier ist eine gute Kurzanleitung dafür:
JS: Einführung in AJAX (Quickstart) mit JQuery und PHP

Und dann soll das Ganze ja jede Sekunde aktualisiert werden. Dazu brauchst Du die Funktion setInterval:
JavaScript/Window/setInterval – SELFHTML-Wiki



> Bei einer Änderung von 0 auf 1 soll ein GIF-Bild dynamisch (ohne reload der Site) und absolut auf der Website positioniert angezeigt werden.


Dabei ist mir unklar: Es sind ja mehrere Variablen und entspr. können es auch mehrere GIF-Bilder sein. Sollen die dann in einer Zeile oder in einer Matrix o. ä. angezeigt werden? Und meinst Du mit "absolut positioniert" dass sie den anderen Inhalt der Seite überdecken sollen?


----------



## ChrisRoo (26. Januar 2019)

Hallo,
danke für die schnelle Antwort.
Also es sind insgesamt 4 variablen, deren Inhalt sich ändern kann (0 oder 1).
Die variablen sollen sekündlich abgefragt werden und bei einer Änderung soll ein div-container geändert werden. 
Ich habe also 4 div-containder mit der id 1-4. In den containern soll bei "0"  das null.gif und bei "1" das eins.gif geladen werden. Positioniert ist das Ganze schon über die div-id und css. 

Es geht also nur um das Script, welches mir sekündlich die 4 variablen abfragt und die div-container ohne reload ändert bzw. aktualisiert.


----------



## Sempervivum (26. Januar 2019)

Dann fehlt dir ja gar nicht mehr viel. Für die GIFs brauchst Du je ein img-Tag und dann kannst Du die Grafik folgender Maßen austauschen:
`document.getElementById("id-des-img-tags").src = "null.gif";`
bzw. anders herum mit eins.gif.


----------



## ChrisRoo (26. Januar 2019)

Oha,
ich glaube, die Lösung ist nahe, aber ich komm nicht so richtig mit...
Also wenn ich das richtig verstehe, dann muss ich in den HTML-Teil folgendes Script einbauen:


```
document.addEventListener('DOMContentLoaded', function(event) {
if(var1 == 0){
document.getElementById(1).src = "null.gif";
}
elseif (var1 == 1){
document.getElementById(1).src = "eins.gif";
,1000}
```
Im div-container(id1) steht dann nichts mehr drin?
Sorry, hab wirklich noch nie was mit Java-Script zu tun gehabt - merkt man, gell.


----------



## Sempervivum (26. Januar 2019)

Du hast jetzt addEventListener und setInterval verwechselt. Es müsste etwa so aussehen:

```
setInterval(function() {
    // hier mit Ajax die Daten holen wie in der Kurzanleitung
    // beschrieben
}, 1000);
```
Ich empfehle dann, die Zustände als Array zu übertragen. Dann kannst Du die Anzeige wie folgt in der success-Funktion durchführen:

```
success: function(data) {
    for (var i = 0; i < data.length; i++) {
        if (data[i]) {
            document.getElementById("status" + (i + 1)).src = "eins.gif";
        } else {
            document.getElementById("status" + (i + 1)).src = "null.gif";
        }
    }
}
```
Die IDs müssen dann so aufgebaut sein:
`<img id="status1">`


----------



## Sempervivum (26. Januar 2019)

> Sorry, hab wirklich noch nie was mit Java-Script zu tun gehabt - merkt man, gell.


Wenn Du dich mit Microcontrollern beschäftigst, muss Du aber Erfahrung in anderen Programmiersprachen haben?


----------



## ChrisRoo (26. Januar 2019)

Vielen vielen Dank für Deine Mühe.
Funktioniert noch nicht,wahrscheinlich hab ich Mist gebaut...

Das habe ich nun im Head-Bereich:

```
<script type="text/javascript">
   setInterval(function() {
    var status = new Array(1, 1, 0, 0);
    success(status);
}, 1000);

success: function(data) {
    for (var i = 0; i < data.length; i++) {
        if (data[i]) {
            document.getElementById("status" + (i + 1)).src = "eins.gif";
        } else {
            document.getElementById("status" + (i + 1)).src = "null.gif";
        }
    }
}
</script>
```

Und das steht im div-container id1

```
<div id="1">
   <img id="status1" width="100px" height="10px" alt="">
</div>
```

Völlig daneben,oder?


----------



## ChrisRoo (26. Januar 2019)

Ja, mit C und Python habe ich schon viel gemacht. Php ist mir auch nicht fremd, allerdings handelt mein letztes, gekauftes Buch noch von PHP4 - ist also schon ein Weilchen her . Mit JavaScript hatte ich noch nichts zu tun - naja, außer ein bisschen copy-paste in Homepages -  Besucherzähler usw.


----------



## Sempervivum (26. Januar 2019)

Nein, nicht unbedingt vollständig daneben, als erster Schritt, um sich der Sache anzunähern, ist es nicht verkehrt. Warum es noch nicht funktioniert ist, dass die Funktionsdefinition, die ich dir gegeben habe, sich auf die Verwendung in $.ajax bezieht. In deinem letzten Testcode müsstest Du sie so definieren, wie Du es von C kennst:

```
function success(data) {
            for (var i = 0; i < data.length; i++) {
                if (data[i]) {
                    document.getElementById("status" + (i + 1)).src = "images/bar10.gif";
                } else {
                    document.getElementById("status" + (i + 1)).src = "images/bar1.gif";
                }
            }
        }
```
Wenn ich das so in eine Testseite einfüge und das HTML ergänze, funktioniert es so weit, dass die Grafiken entspr. Status richtig angezeigt werden.


----------



## ChrisRoo (26. Januar 2019)

Es geht tatsächlich. Vielen Dank dafür.
Jetzt muss ich nur noch schauen, dass das Script auch die Daten aus php holt. Da es die selbe Datei ist, sollte es kein Problem sein.

Ich wünsche Dir noch ein schönes Wochenende.
Gruß
Chris


----------



## Sempervivum (26. Januar 2019)

Ja, dann fehlt dir nur noch das Ajax. Das ist auf der Seite, die ich oben gepostet habe, gut beschrieben. Allerdings wirst Du zwei Dateien brauchen, eine, die die Daten mit Ajax abholt und durch die Grafiken anzeigt und eine PHP-Datei, die die Daten aus der DB liest und als JSON-kodiertes Array bereit stellt.
Ich wünsche ebenfalls ein schönes Wochenende!


----------



## ChrisRoo (26. Januar 2019)

Ubs, ich dachte, das Script macht jetzt schon alles was es soll....
Hab es hochgeladen und das GIF wurde angezeigt. Leider habe ich noch nicht getestet, ob es dynamisch und ohne Seiten-Reload geladen bzw. geändert wird.
Könntest Du hier noch einmal unterstützen?
Sorry...


----------



## Sempervivum (26. Januar 2019)

Kein Problem. Nein, ohne das Ajax ist es noch in keiner Weise dynamisch, weil das Array ja statisch definiert ist. Du müsstest es folgender Maßen ändern:

```
setInterval(function () {
            $.ajax({
                url: "getdata.php",
                dataType: "json",
                success: mysuccess
            });
        }, 1000);
        function mysuccess(data) {
            for (var i = 0; i < data.length; i++) {
                if (data[i]) {
                    document.getElementById("status" + (i + 1)).src = "images/bar10.gif";
                } else {
                    document.getElementById("status" + (i + 1)).src = "images/bar1.gif";
                }
            }
        }
```
Den Funktionsnamen habe ich mal auf mysuccess geändert, weil es sonst etwas verwirrend wäre, wenn links und rechts vom Doppelpunkt das selbe steht. Würde aber auch funktionieren.


----------



## ChrisRoo (26. Januar 2019)

Also,
ich habe jetzt den Code eingebaut und die getdata.php erstellt, die die Daten der letzten id aus der Datenbank holt und per ->bind_result den Inhalt den variablen var1, var2, var3, var4  zuweist.

Jetzt sagtest Du, in der getdata.php muss ich jetzt ein JASON-codiertes ARRAY erzeugen.
In der Kurz-Anleitung wird das in der sendInfo.php gemacht, oder?


----------



## Sempervivum (26. Januar 2019)

Leider lässt mich diese Kurzanleitung nicht mehr herein sondern will ein Login mit Facebook oder Google, so dass ich nicht mehr genau weiß, was dort steht. Ich habe es jedoch inzwischen in meine Testseite aufgenommen und mit diesem getdata.php funktioniert es:

```
<?php
$status = Array(1,1,0,0);
echo json_encode($status);
?>
```
D. h. wenn ich mit dem Editor den Inhalt des Arrays ändere, reagiert die Anzeige der Grafiken und zeigt dynamisch die richtigen Zustände an.


----------



## ChrisRoo (26. Januar 2019)

Könnte man nicht alles in einer Datei machen? Also anstelle von getdata.php die Abfrage der Datenbank und die HTML--Ausgabe mit dem JAVA/AJAX-Script in einer datei (index.php)?


----------



## Sempervivum (26. Januar 2019)

Könnte man schon, aber dann wird es komplizierter: Du müsstest mit dem Ajax die ganze index.php aufrufen und bekämst dann das ganze HTML, inkl. dem, was durch PHP generiert wurde und müsstest dann mühsam die Werte der Variablen irgend wie heraus suchen. Bei einem (Affen-)Formular geht das noch ganz gut, aber für eine solche Anwendung wie bei dir ist es weniger zu empfehlen.


----------



## ChrisRoo (26. Januar 2019)

Schade, bei mir lädt nichts dynamisch.
Wenn ich mit dem editor die getdata.php ediere und alles auf "0" setze, reagiert die Website nicht. Erst bei einem reload verschwindet das GIF.


----------



## Sempervivum (26. Januar 2019)

Werden denn die GIFs angezeigt? Das wäre dann schon ein gutes Zeichen, weil es bedeuten würde, dass das Ajax und die getdata.php zumindest ohne Fehler durchlaufen.
Wenn es gar nicht funktioniert, dann poste doch noch Mal deinen vollständige Code einschl. HTML, aber vor allem das PHP.


----------



## ChrisRoo (26. Januar 2019)

So sieht nun mein Head-Bereich aus:

```
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
   <script type="text/javascript">
   setInterval(function () {
            $.ajax({
                url: "getdata.php",
                dataType: "json",
                success: mysuccess
            });
        }, 1000);
        function mysuccess(data) {
            for (var i = 0; i < data.length; i++) {
                if (data[i]) {
                    document.getElementById("status" + (i + 1)).src = "1.gif";
                } else {
                    document.getElementById("status" + (i + 1)).src = "0.gif";
                }
            }
        }
 
</script>
```

So die getdata.php nach dem mysqly-query:

```
$status = Array(0,0,0,0);
echo json_encode($status);
```

Und so der div-container:

```
<div id="1">
   <img id="status1" width="100px" height="10px" alt="">
</div>
```


----------



## ChrisRoo (26. Januar 2019)

Das 1.gif wurde angezeigt. Es ging aber nicht weg, nachdem ich im Array der getdata.php alles aus "0" gesetzt hatte.


----------



## ChrisRoo (26. Januar 2019)

Sorry, habe den Fehler gefunden.
Ich hatte noch kein 0.gif auf dem Server.
Ich dachte, das das 1.gif auf jedenfall verschwindet, wenn Status 0. Dem ist aber nicht so. Das Script will auf jedenfall das Bild austauschen.


----------



## Sempervivum (26. Januar 2019)

Ja, so ist es. Dann funktioniert es jetzt offenbar.
Ich habe jetzt eine andere Aktivität, wenn doch noch etwas nicht funktioniert, unterstützt dich sicher jemand anders.
Vielleicht bis demnächst - beste Grüße!


----------



## ChrisRoo (26. Januar 2019)

Auf jeden Fall. Werde öfter mal vorbei schauen.
Scheint jetzt soweit zu funktionieren. Außer beim wechsel von 1.gif auf 0.gif scheint es zu haken. Komisch...
Ich habe jetzt die Abfragezeit von 1 sec auf 5 sec erhöht. jetzt scheint es besser zu funktionieren.

Beste Grüße und noch einmal vielen Dank für die Hilfe.
Chris


----------



## ChrisRoo (26. Januar 2019)

Ich hab noch was...
Das Script funktioniert nun super. *Danke noch Mal an Sempervivum!*
Ich würde jetzt gerne mehrere Variablen aus der getdata.php übernehmen und weiterverarbeiten.
Wie baue ich das denn in die setInterval function ein?
Anstelle eines Bildes würde ich in einem div-container gerne einen Text anzeigen, wenn eine der 4 Variablen "1" enthält. 
Also so z.B.:
Wenn status[0] eine 1 hat, dann schreibe in den div-container id="alpha" :"Var1 eingeschaltet!"

Ist soetwas möglich?
Die Texte würden in einem Text Array auf getdata.php liegen. Die " Indexe " der beiden Arrays (status und text) passen zusammen. Also wenn status[1] == 1 dann gib den Text von text[1] aus.

Viele Grüße
Chris


----------



## Sempervivum (26. Januar 2019)

Das ist selbstverständlich kein Problem. Aber wenn wir bei dem Verfahren mit JSON bleiben wollen, müssen alle Parameter in einer Struktur liegen. Das wäre dann auf PHP-Seite ein assoziatives Array und auf JS-Seite ein Objekt, was im wesentlichen das Gleiche ist, wie ein ass. Arr.
Dann müsste die Struktur bzw. das Array so aussehen:
{"status": [1,0,1,1]], "text": ["Var1 eingeschaltet","Var2 eingeschaltet","Var3 eingeschaltet","Var4 eingeschaltet"]}
Die Funktion für die Anzeige müsste dann so aussehen:

```
function mysuccess(data) {
            for (var i = 0; i < data.status.length; i++) {
                if (data.status[i]) {
                    document.getElementById("status" + (i + 1)).src = "1.gif";
                    document.getElementById("text" + (i + 1)).textContent = data.text[i];
                } else {
                    document.getElementById("status" + (i + 1)).src = "0.gif";
                    document.getElementById("text" + (i + 1)).textContent = "";
                }
            }
        }
```
Edit: Oder habe ich es jetzt falsch verstanden und Du möchtest die Texte *anstelle *der Bilder anzeigen? Wenn ja, kannst Du das Verfahren sicher entspr. vereinfachen.


----------



## ChrisRoo (26. Januar 2019)

Gut das Du wieder da bist. 
Ist das so eine Art mehrdimensionales Array oder tatsächlich ein assoziatives Array?
Bei einem Assoziativem Array wäre ja status der key und dann gibt es noch einen Index pro key?
Muss mal schauen, wie der genaue Syntax in php ist. Habe bisher noch kein Assoziatives Array gebraucht. 
Ich denke es wird Zeit sich wieder mehr mit der Materie zu beschäftigen. Macht wieder richtig Spass.


----------



## ChrisRoo (26. Januar 2019)

Das sieht doch schon mal gut aus, oder?


```
$status = array(1,0,1,1);
$text = array('Variable 1 ein', 'Variable 2 ein', 'Variable 3 ein', 'Variable 4 ein');
$status = array_combine($status, $text);
```


----------



## Sempervivum (26. Januar 2019)

Denke eher, dass es das nicht ist: array_combine war mir neu und das setzt lt. Doku voraus, dass ein Array die Schlüssel und das andere die Werte enthält. Das würde nicht funktionieren, weil Schlüsselwerte mehrfach auftreten würde. IMO müsste es eher so aussehen:
`$data = array("status" => $status, "text" => $text);`
So würde es jedenfalls zu dem JS passen, was ich oben gepostet habe.


----------



## ChrisRoo (27. Januar 2019)

Guten Morgen,
auch das funktioniert nun. Vielen Dank für Deine Hilfe bisher.
So wie ich das sehe, kann ich dieses Array ja nun beliebig erweitern. Ich denke, ich kann auch auf einzelne Inhalte, unabhängig von der funktion mysuccess()  zu greifen, ist das richtig?
Nee doch nicht, das Array wird ja oben von $.ajax geholt und sofort an die funktion mysuccess () übergeben.  Hmm, würde ungern die getdata.php includen um an die Variablen zu kommen.
Habe mir gedacht, ich könnte einfach mit einem Print-Befehl (oder so ähnlich)  den Inhalt aus z.B. data.date[0] ausgeben.
Mal schauen...


----------



## Sempervivum (27. Januar 2019)

> Ich denke, ich kann auch auf einzelne Inhalte, unabhängig von der funktion mysuccess() zu greifen, ist das richtig?


Das kommt darauf an: Sollen die Informationen ebenso dynamisch jede Sekunde aktualisiert werden, wird es ohne Ajax nicht gehen. Sind es aber zusätzliche statische Informationen, kannst Du diese selbstverständlich beim Laden der Seite mit PHP holen.


----------



## ChrisRoo (27. Januar 2019)

Oh Mann, bin schon den ganzen Morgen am rumbasteln, aber ich komme nicht dahinter...
Die Schleife scheint nicht durchzulaufen, mir erschließt sich aber nicht, warum das so sein soll.

Hier der Testcode in getdata.php:

```
$status = array(0,0,1,0);
$alarm = array("","","Alarm","");
$data = array("status" => $status, "text" => $alarm);
echo json_encode($data);
```

Hier die Ausgabe bei direktem Aufruf der getdata.php im Browser:

```
{"status":[0,0,1,0],"text":["","","Alarm",""]}
```

Hier das JavaScript:

```
<script src="incl/jquery.min.js"></script>
   <script type="text/javascript">
   setInterval(function () {

            $.ajax({
                url: "getdata.php",
                dataType: "json",
                success: mysuccess
            });
        }, 2000);
          function mysuccess(data) {

            for (var i = 0; i < data.status.length; i++) {
                if (data.status[i]) {
                    document.getElementById("status" + (i + 1)).src = "1.gif";
                    document.getElementById("text" + (1)).textContent = data.text[i];
                } else {
                    document.getElementById("status" + (i + 1)).src = "0.gif";
                    document.getElementById("text" + (i + 1)).textContent = "Keine Daten";
                }
            }
        }

</script>
```
Da ist doch nichts falsch, oder?
Beim Aufruf der Seite wird der Text: Keine Daten angezeigt.
Es wird nur bei img id status1 und status 2 das 0.gif geladen.
Bei Status 3 und 4 wird überhaupt kein Bild geladen.
Was kann das sein?


----------



## Sempervivum (27. Januar 2019)

Ist dies so gewollt:
`document.getElementById("text" + (1)).textContent = data.text[i];`
Ich würde dies erwarten:
`document.getElementById("text" + (i + 1)).textContent = data.text[i];`


----------



## ChrisRoo (27. Januar 2019)

Oje, ich wieder...
Es scheint so, dass das das Problem ist.
Der Text soll ja immer nur an einem Ort angezeigt werden. Deswegen bleibt die ID immer gleich.

```
function mysuccess(data) {

            for (var i = 0; i < data.status.length; i++) {
                if (data.status[i]) {
                    document.getElementById("status" + (i + 1)).src = "1.gif";
                    document.getElementById("text1").textContent = data.text[i];
                } else {
                    document.getElementById("status" + (i + 1)).src = "0.gif";
                    document.getElementById("text1").textContent = "Keine Daten";
                }
            }
        }
```
Ich habe es jetzt so geändert, nun scheint es wieder zu funktionieren.
Muss mal weiter versuchen...


----------



## ChrisRoo (27. Januar 2019)

Komisch, nun zeigt er zwar das 1.gif an aber in der Box steht : Keine Daten.
Auch wenn ich alle 4 Plätze im Array fülle, 
	
	
	



```
{"status":[0,0,1,0],"text":["Alarm0","Alarm1","Alarm2","Alarm3"]}
```
 funktioniert es nicht.


----------



## Sempervivum (27. Januar 2019)

Wenn ich mir den Code ansehe, scheint mir das genau das zu sein, was programmiert ist: Beim letzten Schleifendurchlauf  ist der Status 0 und der else-Zweig wird durchlaufen. Dort wird der der Text wieder auf "Keine Daten" gesetzt, obwohl er zuvor auf "Alarm" gesetzt wurde.
Da Du nur ein Textfeld hast, vermute ich mal, Du möchtest eine Sammelmeldung anzeigen, d. h. wenn mindestens ein Status 1 ist, soll ein Text z. B. "Alarm3" angezeigt werden? Dann müsstest Du es so ändern:

```
function mysuccess(data) {

            document.getElementById("text1").textContent = "Keine Daten";
            var text = "";
            for (var i = 0; i < data.status.length; i++) {
                if (data.status[i]) {
                    document.getElementById("status" + (i + 1)).src = "1.gif";
                    text += data.text[i];
                } else {
                    document.getElementById("status" + (i + 1)).src = "0.gif";
                }
            }
            document.getElementById("text1").textContent = text;
        }
```
Ungetestet, ich hoffe, ich habe dich richtig verstanden.


----------



## ChrisRoo (27. Januar 2019)

Ja das hast Du. 
Ich werde es sofort mal testen.
Habe gerade zum Spass mal die beiden Arrays (status und text) um zwei weitere Pätze erweitert. Nur bei status (0,0,0,0,0,1) wurde auch der korrekte Text angezeigt. Nämlich: Alarm5. Habe alle Variationen einzeln getestet.


----------



## ChrisRoo (27. Januar 2019)

Jetzt klappt es. Danke Dir!
Jetzt gehts weiter mit der Darstellung der Alarmmeldungen. Ich habe in der Visualisierung eine niedrige div-box dafür vorgesehen. jetzt versuche ich einen vertikalen Lauftext dort einzubauen.
Das wird wohl noch eine Herausforderung.
Auf jeden Fall bin ich jetzt erstmal happy, dass das so funktioniert. Nun kann ich anfangen, die Arrays mit der Datenbankabfrage zu befüllen. Das sollte ich hinbekommen   Wegen dem Lauftext oder wenigstens wegen einem Zeilenumbruch für jeden Wert, werde ich sicher noch einmal nerven müssen.


----------



## ChrisRoo (28. Januar 2019)

Hallo,
wie gesagt hänge ich an dem Zeilenumbruch (Vom vertikalen Lauftext bin ich weg).

Ich weiß, das Steuerzeichen müsste in dieser Variablen-Zuweisung kommen:

```
text += data.text[i];
```
Ich weiß aber nicht, in welcher Form...
+ "<br>" und + \n hab ich schon probiert.
Kann mir jemand helfen?


----------



## Sempervivum (28. Januar 2019)

<br> sollte funktionieren, oder den Text in ein p-Element legen:

```
text += '<p>' + data.text[i] + '</p>';
```


----------



## ChrisRoo (29. Januar 2019)

Hallo Sempervivum,
das ist genau wie beim <br>.
Es wird einfach mit ausgegeben. 
Da steht jetzt:
<p>Alarm1</p><p>Alarm2
</p><p>Alarm3</p>
Der Zeilenumbruch kommt von der zu kleinen div-box. 
Wenn sie groß genug wäre, dann würde wohl alles in einer Reihe stehen.

Viele Grüße
Chris


----------



## Sempervivum (29. Januar 2019)

Jetzt wird es mir klar: Ich hatte dir textContent empfohlen, um den Text einzutragen, damit die HTML-Tags interpretiert werden, muss man jedoch innerHTML nehmen:
`document.getElementById("text1").innerHTML = data.text[i];`


----------



## ChrisRoo (29. Januar 2019)

Habs dank Deiner Hilfe hinbekommen.
Musste es nur ein wenig ändern.


```
document.getElementById("text1").innerHTML = text;
```

Vielen Dank Sempervivum.
Gruß
Chris


----------



## ChrisRoo (5. Februar 2019)

Hallo zusammen,
ich habe bezüglich des Javascriptes noch eine Frage:
Kann man auch dynamisch html-code an eine bestimmte Stelle einfügen lassen, der dann auch ausgeführt wird.
Das hier habe ich versucht:


```
$status = array(1,0,1,0);
$text = array("Alarm1","Alarm2","Alarm3","Alarm4");
$sub = array("<form action='' method='post'><button name='submit1'
             id='subInput' type='submit'></button></form>",
             "<form action='' method='post'><button name='submit2'
             id='subInput' type='submit'></button></form>",
             "<form action='' method='post'><button name='submit3'
             id='subInput' type='submit'></button></form>",
             "<form action='' method='post'><button name='submit4'
             id='subInput' type='submit'></button></form>");
```


```
$data = array("status" => $status, "text" => $text  "sub" => $sub);
```


```
function mysuccess(data) {
               document.getElementById("alarmZeit0").textContent = data.alarmZeit;
                document.getElementById("text1").textContent = "Keine Daten";
            var text = "";
            for (var i = 0; i < data.status.length; i++) {
                if (data.status[i]) {
                    document.getElementById("status" + (i + 1)).src = "1.gif";
                    document.getElementById("status" + (i + 1)).textContent = data.sub[i];
                          text += data.text[i] + '<br>';
                } else {
                    document.getElementById("status" + (i + 1)).src = "0.gif";
                }
            }
                 document.getElementById("text1").innerHTML = text;

        }
```
Die Submitbuttons sollen in den div-containern status1-4 dargestellt werden, wenn $status == 1
Muss das vielleicht auch mit .innerHTML gemacht werden?

Viele Grüße
Chris


----------



## Sempervivum (5. Februar 2019)

> Die Submitbuttons sollen in den div-containern status1-4 dargestellt werden, wenn $status == 1
> Muss das vielleicht auch mit .innerHTML gemacht werden?


Ja, innerHTML ist ein guter und leicht lesbarer Weg. Du kannst auch zu vorhandenem HTML etwas hinzufügen. Performanter ist es, die Elemente mit document.createElement zu erzeugen, aber wenn es nur einige sind, spielt das keine Rolle.
Was mir noch nicht klar ist: Am Anfang gab es ja diese GIF-Bilder. Sollen diese Buttons zusätzlich angelegt werden oder sollen sie jetzt anstelle der Bilder angelegt werden?
Außerdem ist noch anzumerken: IDs müssen eindeutig sein, d. h. die selbe ID darf nicht mehrfach vergeben werden. Du müsstest z. B. eine Nummer hinzu fügen.
Ein Formular, das nur einen Submit-Button enthält, macht wenig Sinn. Was soll denn dieser Button bewirken, wenn man ihn drückt?


----------



## ChrisRoo (5. Februar 2019)

Hallo Sempervivum, 
Die Buttons gibt es hinterher garnicht mehr. Der ganze Div-Container soll zum Button werden und als Reset dienen.Das habe ich schon mit CSS gelöst. Zur Erklärung:
Der Div-Container blinkt bei einem Alarm. Wenn er angeklickt wird, soll der Alarm resetet werden. 
Also insgesamt sind es 16 Container. 
Viele Grüße 
Chris


----------



## ChrisRoo (5. Februar 2019)

Die GIF's sind noch da und für das Blinken zuständig.


----------



## Sempervivum (5. Februar 2019)

Wenn ich das jetzt richtig verstehe, brauchst Du ja kein Formular, denn man kann jedes Element klickbar machen, indem man einen Eventhandler registriert:

```
var stati = document.querySelectorAll("[id^='status']");
for (let i = 0; i < stati.length; i++) {
    stati[i].addEventListener("click", function() {
        // hier die Aktionen, die beim Klick ausgefuehrt werden sollen
        // das geklickte Element ist als "this" verfuegbar
    });
}
```
Bleibt die Frage, wie das Reset ausgeführt wird. Ich vermute, da muss etwas zum Server geschickt werden? Wahrscheinlich am besten mit Ajax, damit die Seite nicht neu geladen wird.


----------



## ChrisRoo (5. Februar 2019)

Wenn dieses Javascript für mich nicht so undurchsichtig wäre. 
Ich muss mich unbedingt mehr damit beschäftigen.
Also, ich brauche einfach nur eine Klick fähige Fläche (der betreffende div-Container).
Wie das Reset schließlich ausgeführt wird bzw. was nach dem Klick passiert, weiß ich selbst noch nicht so genau. Eigentlich müsste etwas zum Mikrocontroller gesendet werden, oder der Mikrocontroller müsste in seiner Schleife in der Datenbank nachsehen, ob ein Reset über die Website gesendet oder in der Datenbank gespeichert wurde. Ich dachte, dass kann man am besten über einen Submit-Button (Formular) machen, in dem man in der Datenbank ein "Flag" setzt, dass der Mikrokontroller abfragt. Alarmzeit mit Flag-Setzzeit vergleichen. Alarmzeit früher als Flag-Setzzeit == Alarm aufheben bzw. ignorieren. Wie geschrieben, hab ich noch nicht den richtigen Weg im Kopf. Ich wollte nur schon mal fragen, wie eine mögliche Variante umzusetzen wäre.
Danke auf jeden Fall für Dein Interesse an meinem Projekt.

Chris


----------



## Sempervivum (5. Februar 2019)

> Ich dachte, dass kann man am besten über einen Submit-Button (Formular) machen


Im Prinzip ist das möglich, hat jedoch, wie gesagt, den Nachteil, dass beim Submit die ganze Seite neu geladen wird. Und da Du ja schon mit Ajax begonnen hast, würde es sich anbieten, den Befehl für das Rücksetzen ebenfalls mit Ajax zu schicken. Ajax ermöglicht es generell, eine Datei auf dem Server auszulesen bzw. auszuführen, wenn es sich um ein PHP-Skript handelt. Bisher hat Du es dazu benutzt, Daten vom Server zu holen, aber es ist genau so möglich, eine Aktion auf dem Server zu veranlassen, wie das Reset, das Du beschreibst bzw. einen Eintrag in der Datenbank zu veranlassen.


----------



## ChrisRoo (5. Februar 2019)

Was Du schreibst, macht für mich absolut Sinn und es wäre natürlich toll, wenn die Seite nicht nach jedem Klick neu laden würde. Das wäre auch für die nachfolgenden Funktionen gut, bei denen ich Schalter aktivieren möchte, die nach dem Klick auch noch weiter "leuchten" sollen.
Aber das kommt noch später... 
Wie Du dir sicher schon denken kannst, ist mir nun nur nicht schlüssig, wie ich das mit dem eventListener über Ajax lösen kann.   Könntest Du mir da auf die Sprünge helfen?

Übrigens, könntest Du mir ein Buch zu dem Thema Javascript und Ajax empfehlen? 

Viele Grüße
Chris


----------



## Sempervivum (5. Februar 2019)

Es ist schon alles da, wir müssen es nur richtig zusammen fügen:

```
var stati = document.querySelectorAll("[id^='status']");
for (let i = 0; i < stati.length; i++) {
    stati[i].addEventListener("click", function() {
            $.ajax({
                url: "reset.php",
                method: "post",

                // Die Daten, die an den Server geschickt werden
                // Die Nummer ist im PHP-Skript als POST-Variable verfügbar:
                // $_POST['nr']
                data: {nr: (i + 1)},

                success: successForReset
            });
    });
}
```
Ungetestet, wenn es nicht funktioniert, mache ich eine Testdatei.


----------



## Sempervivum (5. Februar 2019)

Leider habe ich keine Empfehlung für ein Buch, ich habe mir immer alles, was ich wissen wollte, im Netz heraus gesucht. Ganz gut für den Einstieg könnte dieses sein:
JavaScript-Tutorial / Ajax-Kurs und jQuery lernen


----------



## ChrisRoo (6. Februar 2019)

Hallo Sempervivum,

sorry, musste gestern in die Kiste. 04:30 Uhr klingelt mein Wecker. 
Also, wenn ich das richtig verstehe, ist das nun ein Eigenständiges Programm, welches ich unter das bestehende Script schreibe. Es passt auf, in welchen div-Container geklickt wird und schickt dann einen entsprechenden Request an die reset.php.
Ist das richtig?

So muss ich es zusammenbauen?

```
<script type="text/javascript">
   setInterval(function () {

            $.ajax({
                url: "getdata.php",
                dataType: "json",
                success: mysuccess
            });
        }, 1000);

          function mysuccess(data) {
               document.getElementById("alarmZeit0").textContent = data.alarmZeit;
                document.getElementById("text1").textContent = "Keine Daten";
            var text = "";
            for (var i = 0; i < data.status.length; i++) {
                if (data.status[i]) {
                    document.getElementById("status" + (i + 1)).src = "1.gif";
                          text += data.text[i] + '<br>';
                } else {
                    document.getElementById("status" + (i + 1)).src = "0.gif";
                }
            }
                 document.getElementById("text1").innerHTML = text;

        }
var stati = document.querySelectorAll("[id^='status']");
for (let i = 0; i < stati.length; i++) {
    stati[i].addEventListener("click", function() {
            $.ajax({
                url: "reset.php",
                method: "post",

                // Die Daten, die an den Server geschickt werden
                // Die Nummer ist im PHP-Skript als POST-Variable verfügbar:
                // $_POST['nr']
                data: {nr: (i + 1)},

                success: successForReset
            });
    });
}
</script>
```

Ich verstehe nur noch nicht so ganz, was es mit der $_POST['nr'] auf sich hat und wie das Script weiß, welcher div-Container angeklickt wurde.
Viele Grüße
Chris


----------



## ChrisRoo (6. Februar 2019)

Oh, jetzt hab ich es glaube ich...
Das Script schaut, welcher div-Container geklickt wird, in der for-Schleife bekommt dann "nr" die Nummer des geklickten div-containers mit. Die kann dann die reset.php über $_POST[nr] auswerten und dementsprechend einen Reset auslösen.
Stimmt das so?
Gruß
Chris


----------



## Sempervivum (6. Februar 2019)

Ich hatte vor einer halben Stunde angefangen, eine Antwort zu schreiben und bin dann durch einen Anruf aufgehalten worden. Ich mache mal dort weiter:





> Also, wenn ich das richtig verstehe, ist das nun ein Eigenständiges Programm, welches ich unter das bestehende Script schreibe. Es passt auf, in welchen div-Container geklickt wird und schickt dann einen entsprechenden Request an die reset.php.
> Ist das richtig?


Ja, ist richtig so. Nur die Zeile mit dem `success: successForReset` kannst Du zunächst weg lassen, bis wir wissen, dass wir sie brauchen.



> Das Script schaut, welcher div-Container geklickt wird, in der for-Schleife bekommt dann "nr" die Nummer des geklickten div-containers mit. Die kann dann die reset.php über $_POST[nr] auswerten und dementsprechend einen Reset auslösen.


Genau so ist es, ohne den Post-Parameter müsstest Du für jeden Status ein eigenes Skript schreiben und es wäre sehr änderungsunfreundlich, weil Du jedes Mal in n Skripts ändern müsstest.


----------



## ChrisRoo (6. Februar 2019)

Sehr gut, Javascript gefällt mir immer besser. Bin wirklich froh, dass Du dir die Zeit nimmst, mir Javascript-Legasteniker unter die Arme zu greifen. Leider kann ich gerade nicht weiter am Programm arbeiten, weil ich unterwegs bin. Werde mich aber gleich morgen Nachmittag wieder dransetzen. 
Der Link von Dir ist auch super. Das schau ich mir heute Abend am Tablet an. 
Bis morgen... 
Chris


----------

