Ich benötige eine grundsätzliche Anleitung, wie ich Extbase,Fluid und AJAX sauber zum laufen bringe.
Aktuell stelle ich gerade eine alte Extension von mir auf das MVC und DDD Konzept um und sehe, dass mein Code schlanker und einfacher wartbar wird, ganz nebenbei auch sicherer. Allerdings ist die Anfangshürde gerade mit diesen Anzätzen auch um einiges höher.
Mein konketes Problem an einem einfachen Beispiel erkärt:
Ich habe ein FE Plugin, welches ein Grid rendert. In jeder Zeile gibt es einen Edit Button, welcher beim aktivieren unterhalb dieser Zeile eine Edit box aufklappt und dabei die nachkommenden Zeilen nach unter verschiebt. Der alte Code funktioniert noch nach dem Template Maker Concept.
<div id ="imagebox">
<!-- ###ROW### -->
<div class="imagebox">
<div class="statuspic"><img src="###STATUS###" alt="###STATUSDESC###"
<div class="titledesc">
<div class="title">###TITLE###</div>
<div class="desc">###DESC###</div>
</div>
<div class="edit"><a href="javascript:setEditDeleteRequest('edit','###IMAGEID###');"><img src="../edit0.png" alt="edit" border="0"/></a></div>
</div>
<!-- ###ROW### -->
...
Die Platzhalter werden mit Hilfe der alten php Klasse gefüllt:
...
$markerArray['###STATUS###']=$statusimage;
$markerArray['###STATUSDESC###']=$statusdesc;
$markerArray['###TITLE###']=$title;
$markerArray['###DESC###']=$description;
}
$subpartArray['###ROW###']=$liste;
return $this->cObj->substituteMarkerArrayCached($subpart,$markerArray,$subpartArray,array());
...
Mein Javascript habe ich ebenfalls im Template stehen.
Der Javascript Aufruf aus dem Template javascript:setEditDeleteRequest('edit','###IMAGEID###'); ruft diese Funktion auf:
// Request senden
function setEditDeleteRequest(usecase,xx) {
// Request erzeugen
if (window.XMLHttpRequest) {
request = new XMLHttpRequest(); // Mozilla, Safari, Opera
} else if (window.ActiveXObject) {
try {
request = new ActiveXObject('Msxml2.XMLHTTP'); // IE 5
} catch (e) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP'); // IE 6
} catch (e) { }
}
// ueberpruefen, ob Request erzeugt wurde
if (!request) {
alert("Kann keine XMLHTTP-Instanz erzeugen");
} else {
var url = "./typo3conf/ext/xxx/lib/ajax_xxx_functions.php";
// Request oeffnen
request.open('post', url, true);
// Requestheader senden
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var loginuid = parseInt(document.getElementById('loginuid').innerHTML);
var pages = parseInt(document.getElementById('pages').innerHTML);
var showpages = parseInt(document.getElementById('showpages').innerHTML);
value = document.getElementById('pages').innerHTML;
var value = parseInt(document.getElementById('page').innerHTML);
var pagesearch = document.getElementsByTagName("INPUT")["pagesearch_top"].value
// Request senden
switch (usecase) {
case "edit":
request.send('page=' + value + '&usecase=' + usecase + '&loginuid=' + loginuid + '&pages=' + pages + '&showpages=' + showpages + '&xxx=' + xxx+ '&search=' + pagesearch);
// Request auswerten
request.onreadystatechange = interpretEditRequest;
break;
case "delete":
var check = confirm("Do you want really delete your xxx dataset? You will loose all informations about this xxx.");
if (check == true) {
request.send('xxx=' + xxx+ '&usecase=' + usecase + '&loginuid=' + loginuid + '&pages=' + pages + '&showpages=' + showpages + '&page=' + value + '&search=' + pagesearch);
// Request auswerten
request.onreadystatechange = interpretDeleteRequest;
}
break;
default:
break;
}
}
// Request auswerten
function interpretEditRequest() {
switch (request.readyState) {
// wenn der readyState 4 und der request.status 200 ist, dann ist alles korrekt gelaufen
case 4:
if (request.status != 200) {
alert("Der Request wurde abgeschlossen, ist aber nicht OK\nFehler:" + request.status);
} else {
var content = request.responseText;
// den Inhalt des Requests in das <div> schreiben
document.getElementById('imagebox').innerHTML = content;
}
break;
default:
break;
}
}
...
Der Aufruf der url aus dem Javascript var url = "./typo3conf/ext/xxx/lib/ajax_xxx_functions.php"; hat eine andere php Datei aufgerufen und die Argumente mitgeliefert.
Diese Datei hat mir dann den HTML Code für den Edit Marker aus der ersten PHP Klasse erzeugt und zur Laufzeit nur diesen Bereich ausgetauscht, mit den entsprechenden Daten.
Mit diesem Konzept habe ich zwei Probleme, zum einen stört es mich den Javascript Code mit direkt im Template zu haben, das wird sehr schnell sehr unübersichtlich. Das zeite Problem habe ich mit der zeiten php Datei, welche den HTML Code für die Marker generiert. Das finde ich einfach nicht elegant genug.
Mit der Umstellung bin ich jetzt soweit:
Der erste Controller "EditController" soll die komplette Aussteuerung der actions übernehmen, darin sind bis jetzt enthalten die Action index, die das Grid erzeugt und edit, welche mein neues AJAX aussteuern soll, also das ausklappen der Edit box. Die gesamte BusinessLogic wird auf mein DomainModel übertragen.
Das Fluid Template sieht jetzt so aus:
<f:for each="{xxxs}" as="xxx">
<div id ="xxxbox">
<div class="xxxbox">
<div class="statuspic"><f:image src="{xxx.status}" width="16" alt="{xxx.statusdescription}" title="{image.statusdescription}" /></div>
</div>
<div class="titledesc">
<div class="title">{image.title}</div>
<div class="desc">{image.description}</div>
</div>
<div class="edit"><f:link.action action="edit">test</f:link.action><a href="javascript:setEditDeleteRequest('edit','{xxx.xxxid}');"><img src=".../edit0.png" alt="edit" border="0"/></a></div>
...
Und hier kommt jetzt auch endlich meine Frage: wie realisiere ich eine saubere Kommunikation mit AJAX an der Stelle "<f:link.action action="edit">test</f:link.action><a href="javascript:setEditDeleteRequest('edit','{xxx.xxxid}')"?
Das ist für mich absolutes Neuland. Ich will eigentlich ein JSON Object? an den EditConroller senden, mit allen benötigten Argumenten, dieser soll den Request aussteuern und weiter ans Domainmodel propagieren und die Response wieder zurück an das fluid Template liefern um den Code dynamisch austauschen.
Es ist auch möglich, dass ich mit meinem Vorhaben auf dem Holzweg bin, für mich klingt es aber logisch .-)
Mir würde auch schon ein ganz primitives Beispiel "Hello World" genügen, mit dem ganzen Zusammenspiel von Extbase, Fluid und AJAX um mir die Grundlagen zu verinnerlichen.
Sorry, für diese lange Geschichte!