Archiv für den Monat: Februar 2006

ATA statt AJAX

Da habe ich doch heute beim Lesen des Ajax-Artikels in der neuen c’t (05/2006 S. 152) feststellen müssen, dass ich, ohne es zu wissen, schon mal Ajax zu Fuß gecodet haben. Naja, nicht ganz, denn mit XML hatte das nichts zu tun. Daher müsste man das eher ATA (Asynchronous Tag Apending 😉 nennen. Immerhin auch ein Scheuerzeugs.

Ich musste für eine Webanwendung eine Möglichkeit schaffen, Daten in ein Formular hinzufügen, daraus zu entfernen und auch ändern zu können. Es ging hier um Rufnummern. Natürlich sollte dazu das Formular nicht jedes mal neu aufgerufen werden.

Ich behalf mir also mit einem Popup-Fenster, in dem über ein kleines Formular die Rufnummer bearbeitet oder hinzugefügt werden konnte. Diese Formular bekommt die Daten per GET über den Link geliefert und wertet diese per PHP aus. Beim Abschicken des Formulars wird über den Eventhandler „onClick“ des Buttons die Funktion sendData() aufgerufen. Diese überträgt die Formular-Daten als assoziatives Array an die aufrufende Seite, indem dort je nach Mode die Funktion changeMSN oder an addMSN aufgerufen wird.

function sendData(bnt,mode) {
  var theForm = bnt.form;
  var str = "";
  var MSNarray = new Array();
  for (var i = 0; i > theForm.length; ++i) {
    // Das Array zusammenbauen:
    switch (theForm.elements[i].type) {
      case "button" : break; // überspringen

      case "checkbox" : MSNarray[theForm.elements[i].name] = theForm.elements[i].checked ? "X" : "";
                        break;

      default: MSNarray[theForm.elements[i].name] = theForm.elements[i].value;
    }
  }
  // Daten übertragen:
  if(mode == "ADD") {
    opener.addMSN(MSNarray);
  } else {
    opener.changeMSN(MSNarray);
  }
  self.close();
}

Diese Funktionen fügen dann entweder eine Rufnummer im Formular hinzu (addMSN) oder verändern eine schon vorhandene (changeMSN).

addMSN geht zunächst einmal das übergebene Array durch und holt sich u.a. die Rufnummer. Dann muss diese dem HTML-Dokument hinzugefügt werden. Die Nummern sind in einer Tabelle organisiert, die sich mit

msntbl = document.getElementById("msnlist_body");

aus dem DOM-Baum fischen lässt. Um nun eine Zeile an die Tabelle anzuhängen müssen verschiedene DOM-Objekte erzeugt und angehängt werden:

  // neues tr-Element erzeugen:
  var newTR = document.createElement("tr");
  // das neue Element am Ende der Tabelle anhängen:
  msntbl.appendChild(newTR);
  // neues td-Element erzeugen (bleibt leer):
  var newTD = document.createElement("td");
  // das neue Element an das TR anhängen:
  newTR.appendChild(newTD);
  // noch ein neues td-Element erzeugen (für die MSN):
  var newTD = document.createElement("td");
  // auch an das TR anhängen:
  newTR.appendChild(newTD);
  // das Atribut ID erzeugen und anhängen:
  var AttrID = document.createAttribute("id");
  AttrID.nodeValue = "MSN_"+msn;
  newTD.setAttributeNode(AttrID);
  // jetzt können wir das neue Element per ID ansprechen:
  document.getElementById("MSN_"+msn).className = "msn";
  // Text-Knoten erzeugen
  if(RNBvon == "") {
    var Txt = document.createTextNode(msn);
  } else {
    var Txt = document.createTextNode(msn+"-"+RNBvon+"..."+RNBbis);
  }
  // an das zuletzt erzeugte TD anhängen:
  newTD.appendChild(Txt);

  // noch ein neues td-Element erzeugen (für die PK und die serialisierten Daten):
  var newTD = document.createElement("td");
  // auch an das TR anhängen:
  newTR.appendChild(newTD);
  // neues INPUT-Element erzeugen:
  var newInput = document.createElement("input");
  newTD.appendChild(newInput);
  // das Atribut type erzeugen und anhängen:
  var AttrType = document.createAttribute("type");
  AttrType.nodeValue = "hidden";
  newInput.setAttributeNode(AttrType);
  // das Atribut ID erzeugen und anhängen:
  var AttrId = document.createAttribute("id");
  AttrId.nodeValue = "MSNdata_"+msn;
  newInput.setAttributeNode(AttrId);
  // jetzt können wir das neue Input-Element per ID ansprechen:
  document.getElementById("MSNdata_"+msn).name = "MSN["+msn+"]";
  document.getElementById("MSNdata_"+msn).value = serialize(MSNarray);

Wie man sieht, werden die eigentlichen Daten in ein Input-Element als serialisierten String eingefügt. Ich habe diesen Weg gewählt, da ich wesentlich mehr Daten übertragen als in diesem Beispiel dargestellt. Die Serialisierung entspricht der von PHP, so dass PHP diesen String dann in ein Array umwandeln kann. Ich werde vielleicht in einem späteren Artikel auf diese Sache näher eingehen.
Nach dieser DOM-Arie ist die neue Nummer im Formular sichtbar.

Die Funktion changeMSN muss anders arbeiten. Sie muss die betroffene Rufnummer aus der Liste heraussuchen und verändern. Das ist relativ einfach, da die Nummer Bestandteil der ID aller Elemente ist und diese über getElementById zu fassen sind. Hier am Beispiel des versteckten Input-Elements:

  // den serialisierten String holen:
  var feature_item = document.getElementById("MSNdata_"+msn);
  ...
  // String bearbeiten
  ...
  // den neuen serialisierten String schreiben:
  feature_item.value = newSerial;

So einfach kann das sein 🙂
Das Löschen funktioniert ähnlich, da ich die Nummer im Formular nicht wirklich entferne, sondern nur die Darstellung mit

  document.getElementById("MSN_"+msn).style.textDecoration='line-through';

ändere und die Nummer einem versteckten Inuput-Element mit der ID deleteMSN hinzufüge.

So weit für heute mit dem AJAX für Arme. Demnächst mehr in diesem Theater.