# [PHP/SQL/PDO] Stundenplan



## Georgler (23. August 2015)

Hi,

ich bin derzeit am Arbeiten an einem Modul, bei dem jeder Benutzer der Website seinen eigenen Stundenplan (Tage: Montag - Freitag | Stunden: 1 - 11) eintragen kann und dieser dementsprechend auch ausgegeben werden sollte.

*Dafür habe ich folgende Datenbanktabellen (InnoDB):*
Tabelle stundenplan:
| id | user_id | tag | stunde | fach | lehrer | raum |

Tabelle users:
| user_id | username | ...

*Wie ich grob vorgehen wollte:*
Ich wollte für jede Tag-Stunde-Kombination einen Datenbankeintrag machen und die Ergebnisse dann in eine HTML-Tabelle ausgeben lassen.
In jeder Zelle dieser HTML-Tabelle sind dann drei Input-Felder: Eins für das Fach, eins für den Lehrer und eins für den Raum.
In diese Inputfelder sollen dann die jeweiligen Datenbankwerte eingetragen werden.

Bis hierhin erscheint mir das recht richtig aber bei dem Folgenden bin ich mir nicht so sicher, ob das die beste Lösung ist.
Wenn man dann etwas ändern will, ändern man einfach den Wert des entsprechenden Input-Felds, klickt auf „Abschicken" und dann werden alle Werte aller Input-Felder via AJAX an eine andere PHP-Datei weitergegeben (jedes Input-Feld hat dann eine eigene ID). Dann müsste man da ja dort alle 11x5x3 (11 Stunden x 5 Tage x 3 Inputs pro Zelle = 165) POST-Variablen überprüfen und dann weiter in ein Prepared Statement jagen. Ist das nicht etwas unelegant und was macht man wenn manche Felder noch gar nicht mit Werten in der Datenbank vorhanden sind? An diesen Teil vom Code bin ich noch gar nicht rangegangen.

*Derzeit habe ich folgendenen Code:*
Das Problem an diesem Code: Er trägt nur die letzte SQL-Row in die HTML-Tabelle ein.

```
//Variablen
$user_id = htmlentities($_SESSION["user_id"], ENT_QUOTES, 'UTF-8');
$tage = array(1,2,3,4,5);
$stunden = array(1,2,3,4,5,6,7,8,9,10,11);

//SQL
$stmt = $pdo->prepare("
SELECT tag, stunde, fach, lehrer, raum 
FROM stundenplan 
INNER JOIN users ON stundenplan.user_id = users.user_id 
WHERE users.user_id = :user_id
ORDER BY stundenplan.stunde, stundenplan.tag");
$stmt->bindValue(':user_id', $user_id);
$stmt->execute();

$record = array();
$record['stunde'] = 0;
$record['tag'] = 0;

//Output
echo'
<table class="table_standard">
	<tr>
		<th class="th_titlebar" style="white-space:nowrap">Std.</th>
		<th class="th_titlebar"><center>Mo</center></th>
		<th class="th_titlebar"><center>Di</center></th>
		<th class="th_titlebar"><center>Mi</center></th>
		<th class="th_titlebar"><center>Do</center></th>
		<th class="th_titlebar"><center>Fr</center></th>
	</tr>
';
foreach ($stunden as $stunde) {
	echo '<tr>';
	echo '<td align="middle" class="td_contentbar" style="white-space:nowrap">'.$stunde.'</td>';
	foreach ($tage as $tag) {                
		if($stunde > $record['stunde'] || ($tag > $record['tag'] && $stunde <= $record['stunde'])) {
			while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
				$record = $row;
			}
		} 
		echo '<td align="middle" class="td_contentbar">';
		if($stunde == $record['stunde'] && $tag == $record['tag']) {
			echo '<input class="inputfeld sp_input" id="fach_' . $tag . '_' . $stunde . '" value="' . $record['fach'] . '">';
			echo '<input class="inputfeld sp_input" id="lehrer_' . $tag . '_' . $stunde . '" value="' . $record['lehrer'] . '">';
			echo '<input class="inputfeld sp_input" id="raum_' . $tag . '_' . $stunde . '" value="' . $record['raum'] . '">';
		} else {
			echo '<input class="inputfeld sp_input" placeholder="Fach" id="fach_' . $tag . '_' . $stunde . '">';
			echo '<input class="inputfeld sp_input" placeholder="Lehrer" id="lehrer_' . $tag . '_' . $stunde . '">';
			echo '<input class="inputfeld sp_input" placeholder="Raum" id="raum_' . $tag . '_' . $stunde . '">';
		}
		echo '</td>';
	}
	echo '</tr>';
}
echo'</table>';
```

Meine Frage: Was ist an diesem Code falsch bzw. wie muss ich ihn verändern (ich schätze mal bei $record=$row liegt der Fehler). Und macht die oben beschriebene Methode Sinn, die Daten über 165 POST-Variablen zu verarbeiten oder kann man das besser lösen?


----------



## Ap0ll0XT (24. August 2015)

Georgler schrieb:


> Hi,
> 
> ich bin derzeit am Arbeiten an einem Modul, bei dem jeder Benutzer der Website seinen eigenen Stundenplan (Tage: Montag - Freitag | Stunden: 1 - 11) eintragen kann und dieser dementsprechend auch ausgegeben werden sollte.
> 
> ...


Zum ersten: Ja genau da liegt der Fehler. Denn du schreibst in die Variable §record immer nur die letzte Zeile der Tabelle. Schreibe mal statt $record mal $record[] (also so: $record[] = $row; ). Dadurch wird bei jedem durchlauf eine neue Array-Zeile erzeugt und du hast im $record-Array alle Zeilen drin. 

Und nun zu deinem $_POST-Problem. Ich würde persönlich garnicht mit einer direkt editierbaren Tabelle arbeiten. Wenn man schon Ajax nutzt, würde ich die Eingabeelemente bei ein Klick darauf anzeigen, ausfüllen und dann einzeln per Ajax an den Server senden. Wenn du das aber alles auf einmal per Ajax machen willst, würde ich alle Daten per Javascript versuchen, in ein passendes Array zu packen und als JSON-String an den Server zu senden. Dadurch erhälst du in PHP genau das gleiche Array nach json_decode() und kannst das neue mit dem alten vergleichen und nur die Änderungen in die Datenbank schreiben. Das geht zum Beispiel mit Array-Diff: PHP: array_diff - Manual
Ich würde aber wie gesagt das ganze einzeln machen. Dadurch sparst du dir den Vergleich und du schonst den Server. Diff ist Ressourcengierig. Je mehr Elemente das Array hat, umso mehr ackert der Kasten.


----------



## Georgler (24. August 2015)

Danke für die Antwort!

Ich habe nun deinen Tipp mit $record[] = $row übernommen und jetzt wird, wenn ich mir den Array angucke, auch alles abgefragt.
Nur wird bei mir jetzt nichts in die Input-Felder geschrieben. Ich schätze mal das liegt daran: echo $record['fach']

Wenn ich mir das Array mit print_r ausgeben lasse bekomme ich das:

```
Array
(
    [stunde] => 0
    [tag] => 0
    [0] => Array
        (
            [tag] => 1
            [stunde] => 1
            [fach] => DE
            [lehrer] => BE
            [raum] => 319
        )

    [1] => Array
        (
            [tag] => 1
            [stunde] => 2
            [fach] => MA
            [lehrer] => FE
            [raum] => 320
        )

    [2] => Array
        (
            [tag] => 5
            [stunde] => 11
            [fach] => EK
            [lehrer] => GT
            [raum] => 105
        )

)
```

Und zu der Sache mit den vielen POST-Variablen: Würdest du dann einfach ein Ajax auslösen per onclick auf das Input-Feld und dann mit $(this).val() die Daten an eine andere PHP-Datei senden? Bei einem Fehler wird dann ein Fehler ausgegeben, sonst nichts.

Also zum Beispiel so:

```
$(".sp_input").click(function() {
    $(".ajax_response_div").empty();
    $.post("stundenplan_edit.php", 
        {
            $(this).attr("id"),
            $(this).val()
        },
        function(data) {
            $(".ajax_response_div").html(data);
        }
    );
});
```

Ich merke gerade, das click-Event macht da keinen Sinn. Das müsste ja passieren, wenn man rausklickt. Gibt's da auch so eine nette Funktion?


----------



## Ap0ll0XT (24. August 2015)

Zu Problem 1: Das liegt daran, weil in $record["fach"] nichts steht. Es müsste zum Beispiel $record[0]["fach"] heißen. Du müsstest also einen Zähler implementieren. Stetze vor der Schleife eine Variable mit dem Wert 0 und inkrementiere diese *am Ende* (<- Das ist wichtig) eines durchlaufes mit $variable++ oder $variable+=1 um einen hoch. Wenn du die Daten in das Input schreibst, greifst du mit $record[$variable]["fach"] darauf zu. Beim ersten Durchlauf muss also 0, beim zweiten 1, beim dritten die 2 usw. stehen.

Zu Problem 2: Das kannst du mit dem Event onblur machen. Wichtig dabei ebenfalls ist, das du zum einen alle 3 Inputfelder vergleichst, ob sie neue Daten drin haben. Erst dann würde ich die Daten per Ajax an den Server senden. Ansonsten schmeißt der Browser mit Requests nur um sich und ich würde, während der Request arbeitet, alle Felder auf disabled setzen und wenn der Request fertig ist wieder auf enabled. Ansonsten könnten 2 Requests, wenn jemand das ganze schnell ausfüllt, kollidieren und dann zu Datenverlust führen. Ich zum Beispiel nutze dafür im Hintergrund in einem Array eine Art Änderungstabelle, in denen alle geänderten Werte gespeichert werden (zum Beispiel var change_memory["day"]["hour"]). Wenn man dann auf einen Button zum Speichern klickt, geht eine Schleife dieses Array durch, holt alle neuen Daten und sendet diese per Ajax an den Server. Während dieses vorganges würde ich das Formular auf disabled setzen und wenn er fertig ist wieder auf enabled. Mein absoluter Favorit ist aber immernoch der Prompt. Der würde sich sehr gut mit Hilfe vom JQuery-Dialog Plugin machen lassen: jQuery UI Dialog | jQuery Plugin Registry
Dann kannste dir auch das ganze hantieren mit den Inputs, den ganzen onblur etc. sparen und dir für den jeweiligen angeklickten Tag ein eigenes kleines Formular geben lassen. Hier eine Demo vom Dialog/Prompt: Dialog | jQuery UI
Für deine Zwecke wäre das Modal-Form am besten.


----------



## Georgler (25. August 2015)

Hi,

zu Punkt 1:

Ich habe jetzt folgenen Code, dieser zeigt aber weiterhin kein einziges Ergebnis in den Input-Feldern:

```
$co = 0; //COUNTER-VARIABLE
	foreach ($stunden as $stunde) {
		echo '<tr>';
		echo '<td align="middle" class="td_contentbar" style="white-space:nowrap">'.$stunde.'</td>';
		foreach ($tage as $tag) {       
			if($stunde > $record[$co]['stunde'] || ($tag > $record[$co]['tag'] && $stunde <= $record[$co]['stunde'])) {
				while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
					$record[] = $row;
				}
			} 
			echo '<td align="middle" class="td_contentbar">';
			if($stunde == $record[$co]['stunde'] && $tag == $record[$co]['tag']) {
				echo '<input class="inputfeld sp_input" id="fach_' . $tag . '_' . $stunde . '" value="' . $record[$co]['fach'] . '">';
				echo '<input class="inputfeld sp_input" id="lehrer_' . $tag . '_' . $stunde . '" value="' . $record[$co]['lehrer'] . '">';
				echo '<input class="inputfeld sp_input" id="raum_' . $tag . '_' . $stunde . '" value="' . $record[$co]['raum'] . '">';
			} else {
				echo '<input class="inputfeld sp_input" placeholder="Fach" id="fach_' . $tag . '_' . $stunde . '">';
				echo '<input class="inputfeld sp_input" placeholder="Lehrer" id="lehrer_' . $tag . '_' . $stunde . '">';
				echo '<input class="inputfeld sp_input" placeholder="Raum" id="raum_' . $tag . '_' . $stunde . '">';
			}
			echo '</td>';
                     $co++; //COUNTER-VARIABLE UM EINENERHÖHEN
		}
		echo '</tr>';
	}
```

Ich habe mir nun folgenes gedacht:
Das Script geht ja alle Stunden durch und wenn es bei einer Stunde ist geht es bei der erst alle Tage durch, da wäre es doch sinnvoll den Counter in der Tage-Schleife um einen zu erhöhen.

Aber ich bekomme mit diesem Script lediglich das Ergebnis für die 0 (also die, die am Anfang so gesetzt wurde). Wenn ich jedoch $co am Anfang gleich 2 setze und den Counter $co++ weglasse, bekomme ich das entsprechende Ergebnis.


----------



## Ap0ll0XT (25. August 2015)

Georgler schrieb:


> ```
> foreach ($tage as $tag) {
> if($stunde > $record[$co]['stunde'] || ($tag > $record[$co]['tag'] && $stunde <= $record[$co]['stunde'])) {
> while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
> ...


Es kann daran liegen, das ich gerade nicht ausgeschlafen bin, da ich gerade selber an einem PHP-Framework für RIA-Anwendungen arbeite. Aber ich sehe da gerade einen fatalen Fehler im zitierten Code. Und zwar folgender: Wieso rufst du mit $record[$co]['stunde'],  $record[$co]['tag'] und $record[$co]['stunde'] in der zweiten Zeile das Ergebnis selbiger ab, wenn diese noch keine Ergebnisse haben können, da du diese erst 3-5 in das Array $record schreibst? Das macht doch überhaupt keinen Sinn. Oder bin ich vollkommen blöd gerade. Wenn der Interpreter da keinen Fehler raushaut, sollten die Werte alle grundsätzlich NULL/undefined sein. So kann das doch auch irgendwie nichts werden  Aktuell schreibst du bei jedem Schleifendurchlauf sinnloserweise die gesamte Datenbankausgabe aufs neue in das $record-Array.

Ich würde es mal so probieren:

```
<?php
//Variablen
$user_id = htmlentities($_SESSION["user_id"], ENT_QUOTES, 'UTF-8');
$tage = array(1,2,3,4,5);
$stunden = array(1,2,3,4,5,6,7,8,9,10,11);

//SQL
$stmt = $pdo->prepare("
SELECT tag, stunde, fach, lehrer, raum 
FROM stundenplan 
INNER JOIN users ON stundenplan.user_id = users.user_id 
WHERE users.user_id = :user_id
ORDER BY stundenplan.stunde, stundenplan.tag");
$stmt->bindValue(':user_id', $user_id);
$stmt->execute();

$record = array();
$record['stunde'] = 0;
$record['tag'] = 0;

//Output
echo'
<table class="table_standard">
    <tr>
        <th class="th_titlebar" style="white-space:nowrap">Std.</th>
        <th class="th_titlebar"><center>Mo</center></th>
        <th class="th_titlebar"><center>Di</center></th>
        <th class="th_titlebar"><center>Mi</center></th>
        <th class="th_titlebar"><center>Do</center></th>
        <th class="th_titlebar"><center>Fr</center></th>
    </tr>
';

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $record[] = $row;
}
$counter = 0;
foreach ($stunden as $stunde) {
    echo '<tr>';
    echo '<td align="middle" class="td_contentbar" style="white-space:nowrap">'.$stunde.'</td>';
    foreach ($tage as $tag) {                
        echo '<td align="middle" class="td_contentbar">';
        if($stunde == $record[$counter]['stunde'] && $tag == $record[$counter]['tag']) {
            echo '<input class="inputfeld sp_input" id="fach_' . $tag . '_' . $stunde . '" value="' . $record['fach'] . '">';
            echo '<input class="inputfeld sp_input" id="lehrer_' . $tag . '_' . $stunde . '" value="' . $record['lehrer'] . '">';
            echo '<input class="inputfeld sp_input" id="raum_' . $tag . '_' . $stunde . '" value="' . $record['raum'] . '">';
            $counter++;
        } else {
            echo '<input class="inputfeld sp_input" placeholder="Fach" id="fach_' . $tag . '_' . $stunde . '">';
            echo '<input class="inputfeld sp_input" placeholder="Lehrer" id="lehrer_' . $tag . '_' . $stunde . '">';
            echo '<input class="inputfeld sp_input" placeholder="Raum" id="raum_' . $tag . '_' . $stunde . '">';
        }
        echo '</td>';
    }
    echo '</tr>'
}
echo'</table>';
?>
```
Wenn das so immernoch nicht hinhaut, dann stimmt die Sortierung im Query nicht. Aber teste das erstmal.


----------



## Ap0ll0XT (25. August 2015)

Georgler schrieb:


> ```
> foreach ($tage as $tag) {
> if($stunde > $record[$co]['stunde'] || ($tag > $record[$co]['tag'] && $stunde <= $record[$co]['stunde'])) {
> while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
> ...


Es kann daran liegen, das ich gerade nicht ausgeschlafen bin, da ich gerade selber an einem PHP-Framework für RIA-Anwendungen arbeite. Aber ich sehe da gerade einen fatalen Fehler im zitierten Code. Und zwar folgender: Wieso rufst du mit $record[$co]['stunde'],  $record[$co]['tag'] und $record[$co]['stunde'] in der zweiten Zeile das Ergebnis selbiger ab, wenn diese noch keine Ergebnisse haben können, da du diese erst 3-5 in das Array $record schreibst? Das macht doch überhaupt keinen Sinn. Oder bin ich vollkommen blöd gerade. Wenn der Interpreter da keinen Fehler raushaut, sollten die Werte alle grundsätzlich NULL/undefined sein. So kann das doch auch irgendwie nichts werden. Aktuell schreibst du bei jedem Schleifendurchlaufsinnloserweise die gesamte Datenbankausgabe aufs neue in das $record-Array.

Ich würde es mal so probieren:

```
<?php
//Variablen
$user_id = htmlentities($_SESSION["user_id"], ENT_QUOTES, 'UTF-8');
$tage = array(1,2,3,4,5);
$stunden = array(1,2,3,4,5,6,7,8,9,10,11);

//SQL
$stmt = $pdo->prepare("
SELECT tag, stunde, fach, lehrer, raum 
FROM stundenplan 
INNER JOIN users ON stundenplan.user_id = users.user_id 
WHERE users.user_id = :user_id
ORDER BY stundenplan.stunde, stundenplan.tag");
$stmt->bindValue(':user_id', $user_id);
$stmt->execute();

$record = array();
$record['stunde'] = 0;
$record['tag'] = 0;

//Output
echo'
<table class="table_standard">
    <tr>
        <th class="th_titlebar" style="white-space:nowrap">Std.</th>
        <th class="th_titlebar"><center>Mo</center></th>
        <th class="th_titlebar"><center>Di</center></th>
        <th class="th_titlebar"><center>Mi</center></th>
        <th class="th_titlebar"><center>Do</center></th>
        <th class="th_titlebar"><center>Fr</center></th>
    </tr>
';

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $record[] = $row;
}
$counter = 0;
foreach ($stunden as $stunde) {
    echo '<tr>';
    echo '<td align="middle" class="td_contentbar" style="white-space:nowrap">'.$stunde.'</td>';
    foreach ($tage as $tag) {                
        echo '<td align="middle" class="td_contentbar">';
        if($stunde == $record[$counter]['stunde'] && $tag == $record[$counter]['tag']) {
            echo '<input class="inputfeld sp_input" id="fach_' . $tag . '_' . $stunde . '" value="' . $record[$counter]['fach'] . '">';
            echo '<input class="inputfeld sp_input" id="lehrer_' . $tag . '_' . $stunde . '" value="' . $record[$counter]['lehrer'] . '">';
            echo '<input class="inputfeld sp_input" id="raum_' . $tag . '_' . $stunde . '" value="' . $record[$counter]['raum'] . '">';
            $counter++;
        } else {
            echo '<input class="inputfeld sp_input" placeholder="Fach" id="fach_' . $tag . '_' . $stunde . '">';
            echo '<input class="inputfeld sp_input" placeholder="Lehrer" id="lehrer_' . $tag . '_' . $stunde . '">';
            echo '<input class="inputfeld sp_input" placeholder="Raum" id="raum_' . $tag . '_' . $stunde . '">';
        }
        echo '</td>';
    }
    echo '</tr>'
}
echo'</table>';
?>
```
Wenn das so immernoch nicht hinhaut, dann stimmt die Sortierung im Query nicht. Aber teste das erstmal.

*EDIT:* Was im Code vergessen!


----------



## Georgler (25. August 2015)

Vielen Dank! Das funktioniert perfekt. 

Dann setz ich mich mal an diese jQuery Modal-Form ran. Die Lösung scheint mir am Sinnvollsten.


----------



## Ap0ll0XT (25. August 2015)

Georgler schrieb:


> Vielen Dank! Das funktioniert perfekt.
> 
> Dann setz ich mich mal an diese jQuery Modal-Form ran. Die Lösung scheint mir am Sinnvollsten.


Gerne doch. Ein kleiner Tipp nebenbei. Ich persönlich finde die JQuery-UI Lib fürn Eimer. Ich bevorzuge gerade weil ich viel mit RIA mache das JQuery-Plugin w2ui. JQuery UI hat viel zu viel sinnlose Widgets drin, die einfach nicht nötig sind. w2ui ist sehr schlank, aber trotzdem pervers mächtig und sieht professionell aus: Home | JavaScript UI - w2ui

Hier mal einen ganzen haufen Demos, was möglich ist: w2ui Demos

Für deinen Zweck reicht das Dialog-Plugin locker aus. Aber wenn du mal mehr in Richtung Ajax und RIA machen willst, dann ist die w2ui Bibliothek einfach genial.


----------



## Ap0ll0XT (25. August 2015)

Sry ... Doppelpost


----------



## Georgler (25. August 2015)

Habs mir mal angeguckt. Da sind ja schon ein paar sehr nützliche Funktionen dabei. Aufgefallen ist mir zum Beispiel Infinite Scroll, das ist ja perfekt wenn man die Datenbank ausgeben will (zum Beispiel eine Benutzerliste).

Guck ich mir später gerne mal an, erstmal versucht ich das so zum Laufen zu bekommen und dann kann man ja versuchen umzubauen.

Bin gerade an dem jQuery-Dialog:
Wie sollte ich da am besten die bereits bestehenden Daten in den Dialog bekommen?

Sollte ich da per Ajax die ganze HTML-Form reinladen oder die Felder einzeln befüllen, was ich für einfacher halte.
Nur habe ich noch keine Idee, wie ich die Daten da rein bekomme. Ich hätte jetzt so aus dem Stand heraus gesagt, es ist sinnvoller die Daten aus dem Array $record zu ziehen, aber wie mache ich das?


----------



## Ap0ll0XT (25. August 2015)

Georgler schrieb:


> Wie sollte ich da am besten die bereits bestehenden Daten in den Dialog bekommen?


Ich würde es direkt inline machen. Für den Dialog würde ich mir auch  extra eine JS Funktion schreiben. Zuerst sollte PHP jede Zelle mit einem  Link ausstatten, damit die Zellen alle so in etwa aussehen:

```
<td><a href="change_data(this)" id="1_1">Fach: DE<br>Lehrer: XY<br>Raum: 12</a>
```
Die ID besteht an erster Stelle aus Tag und an zweiter Stelle die Stunde. Kann auch umgedreht sein. Der Unterstrich ist nur ein Separator.

In der Funktion change_data holst du den Inhalt des Links und die ID. Beides teilst du an Hand des Separators in Einzelteile. Zum Beispiel so:

```
change_data(ressource) {
    // Tag und Stunde herauslösen
    entry_id = ressource.id.split("_");

    // Prüfen, ob etwas eingetragen ist
    if(ressource.innerHTML != "") {
        // Werte rauslösen durch splitten
        values = ressource.innerHTML.split("<br>");
        // Labels entfernen
        fach = values[0].replace(/Fach: /g, "");
        lehrer = values[1].replace(/Lehrer: /g, "");
        raum = values[2].replace(/Raum: /g, "");
    } else {
        // Wenn kein Inhalt da ist
        fach = "";
        lehrer = "";
        raum = "";
    }

    // Entweder Formular erzeugen und in einen Dialog setzen
    form = "<form><input type=\"text\" id=\"fach\" value=\""+fach+"\" placeholder=\"Fach\">";
    form += "<input type=\"text\" id=\"lehrer\" value=\""+lehrer+"\" placeholder=\"Lehrer\">";
    form += "<input type=\"text\" id=\"raum\" value=\""+raum+"\" placeholder=\"Raum\">";
    form += "<input type=\"hidden\" id=\"stunde\" value=\""+entry_id[0]+"\">";
    form += "<input type=\"hidden\" id=\"tag\" value=\""+entry_id[1]+"\"></form>";

    // Hier kann dann ein Dialog erzeugt werden ... Das fummelst du aber allein heraus ;)   
}
```
Damit solltest du die Einträge bearbeiten und auch direkt neue erzeugen können, wenn ein Eintrag im Stundenplan novh leer ist 
PS: Den Code passt du natürlich an deine Bedürfnisse genau an.


----------



## TessaKavanagh (25. August 2015)

Ap0ll0XT schrieb:


> Damit solltest du die Einträge bearbeiten und auch direkt neue erzeugen können, wenn ein Eintrag im Stundenplan novh leer ist
> PS: Den Code passt du natürlich an deine Bedürfnisse genau an.



Datensatz ändern oder hinzufügen kannst du dabei ruhig der Datenbank überlassen. Einfach mit https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html arbeiten. Dann entscheidet die Datenbank selbstständig ob sie einen neuen Datensatz anlegen oder einen alten editieren muss.


----------



## Ap0ll0XT (25. August 2015)

TessaKavanagh schrieb:


> Datensatz ändern oder hinzufügen kannst du dabei ruhig der Datenbank überlassen. Einfach mit https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html arbeiten. Dann entscheidet die Datenbank selbstständig ob sie einen neuen Datensatz anlegen oder einen alten editieren muss.


Das war eigentlich nur auf das Frontend bezogen und nicht auf die Verarbeitung im Backend, da sich bei leeren Einträgen ein leerer Dialog öffnen kann, mit dem man den Eintrag neu hinzufügen könnte


----------



## Georgler (25. August 2015)

Hi,

ich habe nun deinen Code genommen und noch versucht den Dialog dann auszugeben, aber so weit bin ich gar nicht gekommen.

Der Chrome gibt mit beim Klick auf a (bzw. die Zelle) folgenden Fehler: Uncaught ReferenceError: change_data is not defined
Ich habe deswegen schon versucht mit document ready das auszuhebeln, aber das hat auch nicht geholfen.

Javascript:

```
<script>
	$(document).ready(function(){
		$("#dialog").dialog({
			autoOpen : false,
			height: 300,
			width: 350,
			modal : true,
			open: function(){
				$(".ui-widget-overlay").bind("click",function(){
					$("#dialog").dialog("close");
				})
			}
		});
		change_data(ressource) {
			entry_id = ressource.id.split("_");
			if(ressource.innerHTML != "") {
				values = ressource.innerHTML.split("</div>");
				fach = values[0].replace(/<div class=\"sp_input\">/g, "");
				lehrer = values[1].replace(/<div class=\"sp_input\">/g, "");
				raum = values[2].replace(/<div class=\"sp_input\">/g, "");
			} else {
				fach = "";
				lehrer = "";
				raum = "";
			}

			// Entweder Formular erzeugen und in einen Dialog setzen
			form = "<form><input type=\"text\" id=\"fach\" value=\""+fach+"\" placeholder=\"Fach\">";
			form += "<input type=\"text\" id=\"lehrer\" value=\""+lehrer+"\" placeholder=\"Lehrer\">";
			form += "<input type=\"text\" id=\"raum\" value=\""+raum+"\" placeholder=\"Raum\">";
			form += "<input type=\"hidden\" id=\"stunde\" value=\""+entry_id[0]+"\">";
			form += "<input type=\"hidden\" id=\"tag\" value=\""+entry_id[1]+"\"></form>";
			
			var dialogDiv = $("#dialog");
			
			form.appendTo(dialogDiv);
			
			$("#dialog").dialog("open");
		}
	});
	</script>
```

Der Dialog-Div:

```
<div id="dialog" title="Bearbeiten"></div>
```

Code von einer Zelle:

```
echo'
<a class="stundenplan" onclick="change_data(this)" id="'.$tag.'_'.$stunde.'">
	<div class="sp_input">'.$record[$counter]['fach'].'</div>
	<div class="sp_input">'.$record[$counter]['lehrer'].'</div>
	<div class="sp_input">'.$record[$counter]['raum'].'</div>
</a>
';
```


----------



## Ap0ll0XT (25. August 2015)

Du hast das Schlüsselwort function vor change_data vergessen.

Ohhh ... sehe gerade das haste so von mir kopiert 

*TIPP:* Für die implementierung von Funktionen ist man nicht darauf angewiesen, auf das Dokument zu warten


----------



## Georgler (25. August 2015)

Das hatte ich auch schon probiert, habs nur vergessen zu schreiben :/

So hatte ich es versucht:

```
function change_data(ressource) {
```


----------



## Ap0ll0XT (25. August 2015)

Georgler schrieb:


> Das hatte ich auch schon probiert, habs nur vergessen zu schreiben :/
> 
> So hatte ich es versucht:
> 
> ...


Dann nimm mal den Code von der Funktion da aus dem dcument ready raus und schreib ihn mal nach ganz oben in die Datei.


----------



## Georgler (25. August 2015)

Ok, so funktioniert's!

Jetzt habe ich nur das Problem, das warum auch immer im Dialog ganz viele Leerzeichen im Input-Feld entstehen, vor dem eigentlichen Text.

*Beispiel:*
In der Tabelle steht "TEST".
Im Dialog, steht dann in etwa "_____________________TEST" ( _ ist hier das Leerzeichen).

*Javascript:*

```
function change_data(ressource) {
			entry_id = ressource.id.split("_");
			if(ressource.innerHTML != "") {
				values = ressource.innerHTML.split("</div>");
				fach = values[0].replace(/<div class=\"sp_input\">/g, "");
				lehrer = values[1].replace(/<div class=\"sp_input\">/g, "");
				raum = values[2].replace(/<div class=\"sp_input\">/g, "");
			} else {
				fach = "";
				lehrer = "";
				raum = "";
			}
			
			form = "<input class=\"inputfeld\" type=\"text\" id=\"fach\" value=\""+fach+"\" placeholder=\"Fach\">";
			
			$("#dialog").empty();
			$("#dialog").append(form);
			
			$("#dialog").dialog("open");
		}
		
		$("#dialog").dialog({
			autoOpen : false,
			height: 300,
			width: 350,
			modal : true,
			open: function(){
				$(".ui-widget-overlay").bind("click",function(){
					$("#dialog").dialog("close");
				})
			}
		});
```

*PHP-Code (das was aus der Datenbank genommen wird und ausgegeben wird)*

```
if($stunde == $record[$counter]['stunde'] && $tag == $record[$counter]['tag']) {
				echo'
				<a class="stundenplan" onclick="change_data(this)" id="'.$tag.'_'.$stunde.'">
					<div class="sp_input">'.$record[$counter]['fach'].'</div>
					<div class="sp_input">'.$record[$counter]['lehrer'].'</div>
					<div class="sp_input">'.$record[$counter]['raum'].'</div>
				</a>
				';
				$counter++;
			} else {
				echo'
				<a class="stundenplan" onclick="change_data(this)" id="'.$tag.'_'.$stunde.'">
					<div class="sp_input"></div>
					<div class="sp_input"></div>
					<div class="sp_input"></div>
				</a>
				';
			}
```


----------



## Ap0ll0XT (25. August 2015)

Keine Ahnung. Ich checke ja nicht einmal was du da jetzt wieder mit den komischen DIV's in den Zellen erreichen willst. Das musst du mir mal erklären. Die DIV's sind witzlos und blähen bei 165 Zellen den HTML-Code nur unnötig auf. Die brauchst du nicht. Es sei denn du willst für jede REihe eine andere Formatierung. Dies ist aber auf Grund der gleichen Klasse unwahrscheinlich. 

Dein Leerzeichenfehler kommt wohl vom Regulären Ausdruck. Das Problem bekommst du mit der Stringfunktion trim() in den Griff.


----------



## Georgler (25. August 2015)

Die divs habe ich genommen, damit um jede Info (Fach, Raum, Lehrer) ein Kästchen entsteht, sodass ich das mit CSS bearbeiten kann. Kann man das geschickter lösen?
Und das Problem mit den Leerzeichen habe ich lösen können, indem ich folgendes noch ergänzt habe:

```
replace(/\s/g, "");
```


----------



## Ap0ll0XT (25. August 2015)

Georgler schrieb:


> Die divs habe ich genommen, damit um jede Info (Fach, Raum, Lehrer) ein Kästchen entsteht, sodass ich das mit CSS bearbeiten kann. Kann man das geschickter lösen?
> Und das Problem mit den Leerzeichen habe ich lösen können, indem ich folgendes noch ergänzt habe:
> 
> ```
> ...


Der Trimbefehl macht das gleiche.


----------



## Georgler (25. August 2015)

So das Backend habe ich jetzt auch fertig, mir bleibt nur noch eine Frage.

Ich habe dies nun per Ajax gelöst, d.h. man klickt auf eine Zelle und dann öffnet sich der Dialog. Wenn man bei diesem die Felder alle ausfüllt wird alles via Ajax eingetragen (on duplicate key berücksichtigt). Wenn ein Fehler auftritt wird der Fehler per echo ausgegeben. Falls alles in Ordnung ist wird nichts zurückgegeben.

Sollte man hier bei jedem erfolgreichem Eintrag per Script die Seite neu laden, damit Änderungen direkt sichtbar werden oder sollte man das lieber lassen?

Edit:

Ein Problem ist mir noch aufgefallen:
Wenn man beim Raum-Inputfeld nichts eingibt wird in der Datenbank "0" eingetragen, ich würde da aber gerne nichts stehen haben. Wie muss dann da die Tabellenstruktur aussehen? Die Spalte raum ist bei mir gerade Integer unsigned. Und in dem Prepared Statement wird auch für den Wert des Raums ein Integer erwartet.
-> Ich habe jetzt einfach einen "Entfernen"-Button hinzugefügt


----------



## Ap0ll0XT (25. August 2015)

Neuladen wäre eine Möglichkeit. Du könntest aber auch, da du ja tag und stunde in der ID hast die Infos direkt in die Tabelle schreiben.


----------



## Georgler (25. August 2015)

Stimmt, das wäre eine Möglichkeit. Setze ich mich mal dran.

Aber vielen Dank für deine Hilfe!


----------



## Ap0ll0XT (26. August 2015)

Georgler schrieb:


> Stimmt, das wäre eine Möglichkeit. Setze ich mich mal dran.
> 
> Aber vielen Dank für deine Hilfe!


Jo kein Ding


----------

