php.de

Zurück   php.de > php.de Intern > Wiki Diskussionsforum > Tutorials

Tutorials Hier findest Du Tutorials, welche nach und nach ein fertiges Script ergeben. Sehen, lernen & verstehen!

Antwort
 
LinkBack (6) Themen-Optionen Thema bewerten
Alt 13.08.2007, 22:13  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard JavaScript/PHP: qooxdoo 0.7.1 - Teil 1 : Eine Einführung

qooxdoo 0.7.1 - Teil 1 : Eine Einführung

Hallo,
ich möchte euch anhand eines Beispiels qooxdoo näher bringen. Wer qooxdoo noch nicht kennt, kann sich unter
http://www.qooxdoo.org -> Demo -> Showcase, Demobrowser
einige Beispiele anschauen. Der API-Viewer (sozusagen das Handbuch) rundet die Sache ab.
Zusammengefasst ist qooxdoo ein JavaScript-Framework von 1und1, mit dem sich Webapplikationen anhand der zur Verfügung gestellten GUI-Klassen erstellen lassen. Mittels Ajax (JSON) und einer serverseitigen Skriptsprache (zB PHP) kann die Applikation dynamische Daten empfangen und in die Oberfläche laden.
qooxdoo ist also hauptsächlich für Formular-Datenbank-Interaktion geeignet. Anhand einer Dummy-Sportliga möchte ich eine Tabelle und Ergebnisliste anzeigen und administrierbar machen.

Voransicht
Ansicht, Download


Unterteilung
Tutorial 1
Beschreibung:
Erstellen der Benutzeroberfläche mit statischen Einträgen einer Dummyliga
Programmiersprachen:
HTML, CSS, JavaScript
Voraussetzungen:
Grundkenntnisse JavaScript

Tutorial 2
Beschreibung:
Umschreiben der Dummyliga in die Bundesliga, in dem echte Einträge dynamisch aus der Datenbank gelesen werden
Voraussetzungen:
Server mit PHP und MySQL, phpMyAdmin [1]
Programmiersprachen:
JavaScript, PHP, MySQL, JSON

Tutorial 3
Beschreibung:
Erzeugen eines Login-Bereichs, der das Eintragen der Spielergebnisse ermöglicht sowie eine Explorer-Ansicht zum Einsehen sämtlichen Quellcodes des Projektes
Programmiersprachen:
JavaScript, PHP, JSON-Framework
Voraussetzungen:
siehe Tutorial 2

Geschätzter Zeitaufwand jeweils:
~ 30 Minuten (falls ihr das Tutorial durcharbeitet und auf eine andere Zeitspanne kommt, informiert mich darüber)
Die Länge des Textes hier entspricht nicht dem Aufwand, da der Code ja per copy&paste übernommen werden kann und zunächst nur verstanden werden soll.


Start:
Legen wir los, in dem wir qooxdoo herunterladen. Das können wir entweder direkt aus dem Subversion-Repository ziehen oder aber – so mache ich es der Einfachheit halber – wir laden einfach das ZIP herunter:

Download:
http://www.qooxdoo.org -> Download -> qooxdoo-0.7.1-build.zip (Evaluate the Complete Framework without Installation)
die qooxdoo-*-build.zip ist auf Grund der vielen Iconsets sehr groß, wir benötigen später jedoch nur einige davon.

Installation:
Entpacken wir nun das Archiv in unseren Test-Ordner, so dass dieser den Ordner frontend enthält. Unser Arbeitsverzeichnis wird frontend/quickstart sein. Zum Testen rufen wir diese Seite nun einmal auf. In meinem Fall wieder
http://localhost/qooxdoo/1/frontend/...art/index.html
Wenn alles geklappt hat, sehen wir eine graue Seite mit einem First Button. Wenn nicht, hast du vermutlich falsche Pfade verwendet.


Qooxdoo ist übrigens ein Projekt, bei dem man sehr viel copy&paste verwenden kann. Das ist legitim, also keine Hemmungen! Dafür geeignet ist der schon erwähnte Demobrowser, der einen Tab Source anbietet. Hier kann man dann schön Abschnitte kopieren oder nachschlagen und den eigenen Bedürfnisse anpassen.


Schritt 1:
Weiter geht's! Wir kopieren die Dateien index.html und Application.js im frontend/quickstart und benennen diese in Dummyliga.html und Dummyliga.js.
Damit nicht wieder der First Button erscheint, bringen wir die Dummyliga.js auf folgendes Format:
Code:
qx.Class.define("Dummyliga",
{
  extend : qx.application.Gui,

  members :
  {
    main : function()
    {
      // Call super class
      this.base(arguments);
    }
  }
});
Beachte, dass die Klasse nicht nur geleert, sondern Application auch durch Dummyliga ersetzt wurde.

Unsere Dummyliga.html sieht so aus:
Code:
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Dummyliga</title>

    
    <script type="text/javascript">
      qxsettings = { "qx.application" : "Dummyliga" };
    </script>

    
    <script type="text/javascript" src="script/qx.js"></script>

    
    <script type="text/javascript" src="Dummyliga.js"></script>
  </head>
</html>
Unsere Applikation steht nun bereits, sie hat nur noch keinen Inhalt.
Jetzt werden wir zunächst fünf Registerkarten erstellen (genannt Page- bzw. Tabviews): Info, Tabelle, Ergebnisse, Administration, Quellcode.

Und das ist der JavaScript-Code dafür, der direkt hinter this.base(arguments) eingefügt wird:
Code:
      // Instanz des Dokumentes holen.
      var d = qx.ui.core.ClientDocument.getInstance();
      
      // Statt iconBasePath könnte man sicherlich auch Themes
      // verwenden, damit habe ich mich aber noch nicht beschäftigt.
      var iconBasePath = "../demobrowser/resource/qx/icon/CrystalClear/16/";
      
      // Tab-Set erstellen
      var tabset = new qx.ui.pageview.tabview.TabView;
      
      // Registerkarten erstellen. Das ist aufgeteilt in die Buttons und Seiten selbst.
      // Liste erstellen, in die wir die Buttons und Seiten legen.
      var tbuttons = new Array();
      var tpages   = new Array();
      // Zähler zum dynamischen Hinzuf�gen von Elementen, so k�nnen wir einfach
      // durch die Code-Reihenfolge auch die Reihenfolge in der Ansicht bestimmen.
      var tx = 0;
      
      // Info
      // Parameter = Button-Text, Button-Icon
      // null bedeutet, dass Text oder Icon nicht gesetzt ist
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Info", iconBasePath + "apps/accessories-tip.png");
      // Parameter = eben erstellter Button
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      ++tx; // nicht vergessen, sonst überschreibt uns der folgende Eintrag 
      
      // Tabelle
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Tabelle", iconBasePath + "actions/view-pane-text.png");
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      ++tx;
      
      // Ergebnisse
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Ergebnisse", iconBasePath + "actions/view-pane-icon.png");
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      ++tx;
      
      // Administration
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Administration", iconBasePath + "actions/encrypt.png");
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      ++tx;
      
      // Quellcode
      tbuttons[tx]  = new qx.ui.pageview.tabview.Button("Quellcode", iconBasePath + "mimetypes/text-x-generic.png");
      tbuttons[tx].setEnabled(false); // vorerst deaktivieren
      tpages[tx]    = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      ++tx;
      
      // Tab-Buttons und Seiten ins Tab-Set legen
      for (var i = 0, ix = Math.min(tbuttons.length, tpages.length); i < ix; ++i) {
        // es wird unterschieden zwischen Bar (Buttonleiste) und Pane (Seitenansicht)
        tabset.getBar().add(tbuttons[i]);
        tabset.getPane().add(tpages[i]);
      }
      // with () führt alle Operationen in der geschweiften Klammer auf das Objekt
      // in der Runden Klammer aus.
      with (tabset) {
        setEdge("20%"); // Außenabstand des Tabsets (padding zum <body>)
        // dem Dokument hinzufügen (ohne das, passiert garnichts)
        // alternativ zu tabset.addToDocument() ist auch d.add(tabset) m�glich
        addToDocument(); 
      }
      // das ist also gleichbedeutend mit tabset.setEdge(20); und tabset.addToDocument()
So nach einiger Ladezeit sollten sich uns nun auf
http://localhost/qooxdoo/1/frontend/...Dummyliga.html
unsere Registerkarten befinden. Sollte ein Fehler auftreten, schaut in der JavaScript-Konsole des Firefox nach oder benutzt gleich das Addon Firebug [3]. Dort wird der Fehler meist gut beschrieben (zB bei falschem Grafikpfad). Für den Fall der Fälle biete ich euch das Tutorial auch nocheinmal zum Download an.


Schritt 2:
Ich möchte euch hierüber zeigen, dass es verschiedene Möglichkeiten gibt, die Seiten des Registers zu füllen.


Schritt 2.1:
Fangen wir bei der Info-Registerseite mit der direktesten Art an:

Ändern wir die Dummyliga.html folgend um:
Code:
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Dummyliga</title>

    <script type="text/javascript">
      qxsettings = { "qx.application" : "Dummyliga" };
    </script>

    <script type="text/javascript" src="script/qx.js"></script>
    <script type="text/javascript" src="Dummyliga.js"></script>
    
    <style type="text/css">
      h1 {
        color           : #E20A17;
        font-size       : 11px;
        font-weight     : bold;
        text-decoration : underline;
      }
    </style>
  </head>
  <body>
    <div id="info" style="display:none">
     <h1>Info</h1>
     Auf dieser Seite kannst du die Tabelle und Ergebnisse der
     Dummyliga anschauen.
    </div>
  </body>
</html>
Der Sinn von display:none ist der, dass der Inhalt des Containers – wie du gleich sehen wirst – von qooxdoo geladen wird, welches dann selbst die Anzeige übernimmt. Daher benötigen wir das Element nur als Datencontainer, jedoch nicht zur direkten Ansicht.

Ändern wir den für die Info zuständigen Codeblock in folgenden ab:
Code:
      // Info
      // Parameter = Button-Text, Button-Icon
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Info", iconBasePath + "apps/accessories-tip.png");
      // Parameter = eben erstellter Button
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      // Element des <div> Containers "info" holen und der Seite hinzufügen
      var info     = new qx.ui.basic.Label(document.getElementById("info").innerHTML);
      tpages[tx].add(info);
      ++tx; // nicht vergessen, sonst überschreibt uns der folgende Eintrag
Speichern wir beide Dateien ab und laden die Seite neu.
Das Ergebnis sollte uns nicht überraschen, der Text den wir in den <div> Container geschrieben hatten, erscheint im Tab Info.


Schritt 2.2:
Fahren wir damit fort, eine Tabelle zu erstellen. Qooxdoo bietet hierfür ListViews an, die ihr bestimmt schon aus dem Explorer eures Betriebssystemes kennt.

Ändern wir den für den Register Tabelle zuständigen JavaScript-Block in folgenden ab:
Code:
      // Tabelle
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Tabelle", iconBasePath + "actions/view-pane-text.png");
      tbuttons[tx].setChecked(true); // automatisch diese Registerkarte anzeigen
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      // Spaltenkopf festlegen
      var ranksHead = {
        rank   : { label : "Platz",  width : 50,  type : "text", sortable : true, sortProp : "text", sortMethod : qx.util.Compare.byIntegerString },
        name   : { label : "Verein", width : 300, type : "text" },
        points : { label : "Punkte", width : 75,  type : "text", sortable : true, sortProp : "text", sortMethod : qx.util.Compare.byIntegerString }
      };
      // Spalteninhalt
      var ranks = new Array();
      ranks.push({ rank   : { text : "1" },
                   name   : { text : "1. FC Musterhausen" },
                   points : { text : "3" }});
      ranks.push({ rank   : { text : "2" },
                   name   : { text : "VfB Musterburg" },
                   points : { text : "1" }});
      ranks.push({ rank   : { text : "3" },
                   name   : { text : "Lokomotive Musteringen" },
                   points : { text : "1" }});
      ranks.push({ rank   : { text : "4" },
                   name   : { text : "Musterstädtchen SC" },
                   points : { text : "0" }});
      var chart = new qx.ui.listview.ListView(ranks, ranksHead);
      with (chart) {
        setTop(10);
        setRight(10);
        setBottom(10);
        setLeft(10);
      }
      tpages[tx].add(chart);
      ++tx;
Wir erstellen zunächst einen Array der die Überschriften für unsere Listenspalten deklariert.
Dessen Schlüssel können nur in der ersten Dimension frei gewählt werden (rank, name, points). Der Array im Array (2. Dimension also) hat feste Bezeichner. Wer englisch kann, sollte erahnen können wofür sie jeweils stehen.
Nachdem wir den Listenkopf erstellt haben, benötigen wir Dummy-Daten, um die Tabelle zu füllen. Dafür erzeugen wir einen Array und fügen dem weitere Arrays hinzu (für jede Zeile einen).
Als Schlüssel der ersten Dimension verwenden wir hier die selbst gewählten Namen aus ranksHead. Ich denke auch hier sind die Bezeichner selbsterklärend. Die Array-Schachtelung mag auf den ersten Sinn zu tief erscheinen, ergibt aber Sinn, da Datensätze weitere Eigenschaften annehmen können als nur Text.

Schauen wir uns das Ergebnis an. Platz und Punkte sind jetzt sogar sortierbar.


Schritt 2.3:
Die Auflistung der Ergebnisse des einzigen Spieltages dieser Dummy-Liga möchte ich nicht explizit erklären, da er praktisch genau wie die Tabelle aufgebaut ist. Wieder ist in der Dummyliga.js der Code-Block für die Ergebnisse durch folgenden zu ersetzen:
Code:
      // Ergebnisse
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Ergebnisse", iconBasePath + "actions/view-pane-icon.png");
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      // Liste der Ergebnisse des ersten Spieltages
      var matchesHead = {
        team_home   : { label : "Heim", width : 200, type : "text" },
        team_guest  : { label : "Gast", width : 200, type : "text" },
        goals_home  : { label : "",     width : 25,  type : "text" },
        goals_guest : { label : "",     width : 25,  type : "text" }
      };
      var matches = new Array();
      var rx      = 0;
      matches.push({ team_home   : { text : "Musterstädtchen SC" },
                     team_guest  : { text : "1. FC Musterhausen" },
                     goals_home  : { text : "2" },
                     goals_guest : { text : "0" }});
      matches.push({ team_home   : { text : "Lokomotive Musteringen" },
                     team_guest  : { text : "VfB Musterburg" },
                     goals_home  : { text : "1" },
                     goals_guest : { text : "1" }});
      var chart = new qx.ui.listview.ListView(matches, matchesHead);
      with (chart) {
        setTop(10);
        setRight(10);
        setBottom(10);
        setLeft(10);
      }
      tpages[tx].add(chart);
      ++tx;
Erinner dich, dass wir mit setChecked(true) die Registerkarte Tabelle als Standardansicht ausgewählt haben. Du kannst diese Einstellung natürlich auch anderen Registerkarten-Buttons zuweisen. Prinzipiell solltest du den anderen Registerkarten dann natürlich die Anweisung setChecked(true) wieder entziehen, denn wenn mehrere Registerkarten als angezeigt eingestellt werden, liegt es am System zu entscheiden, welche das ist. Vermutlich die erste, aber die qooxdoo-Entwickler könnten sich entscheiden, dies bei einem Release-Wechsel zu ändern.


Schritt 2.4:
Die Login-Seite enthält mehr als nur ein Element, nämlich eine Überschrift, einen Hinweistext sowie ein kleines Formular, das Benutzername und Passwort empfängt. Bei der Kombination dieser Elemente kann man das BoxLayout verwenden. Je nachdem ob vertical oder horizontal gewählt ist, werden die Elemente, die diesem Boxlayout hinzugefügt werden, nebeneinander oder untereinander angeordnet.
Ich kombiniere beide Boxlayouts, in dem ich zunächst das Formular (Benutzer-Label, Benutzer-Eingabefeld, Passwort-Label, Passwort-Eingabefeld, Abschicken-Button) in ein horizontales Boxlayout packe, und dieses danach mit vorangehender Überschrift und vorangehendem Hinweistext zusammen in ein vertikales Boxlayout stecke.

Schaut es euch selbst an und ersetzt in der Dummyliga.js wieder den Administrations-Block durch folgenden:
Code:
      // Administration
      tbuttons[tx] = new qx.ui.pageview.tabview.Button("Administration", iconBasePath + "actions/encrypt.png");
      tpages[tx]   = new qx.ui.pageview.tabview.Page(tbuttons[tx]);
      // einen Randtyp (border) für Textfelder (f = feld, field)
      var fBorder   = new qx.ui.core.Border(1, "inset"); 
      // einen Randtyp (border) für Buttons (b = button)
      var bBorder   = new qx.ui.core.Border(1, "outset"); 
      var title     = new qx.ui.basic.Label("<h1>Login</h1>");
      // Subtext
      var text      = new qx.ui.basic.Label("Bitte gib hier Deinen Benutzernamen sowie das Dir "
                                          + "zugewiesene Passwort ein.");
      // Boxlayouts sind Ansammlungen von Elementen in vertikaler oder horizontaler
      // Anordnung
      var login     = new qx.ui.layout.BoxLayout("vertical");
      var loginForm = new qx.ui.layout.BoxLayout("horizontal");
      // Ein Atom ist ein Text mit Icon
      var userAtom  = new qx.ui.basic.Atom("Benutzername", iconBasePath + "apps/system-users.png");
      with (userAtom) {
        setIconPosition("left");
        setPadding(3, 10, 0, 0);
      }
      var userField = new qx.ui.form.TextField();
      with (userField) {
        setPaddingLeft(10);
        setBorder(fBorder);
      }
      var pwAtom = new qx.ui.basic.Atom("Passwort", iconBasePath + "status/dialog-password.png");
      with (pwAtom) {
        setIconPosition("left");
        setPadding(3, 10, 0, 25);
      }
      // Statt TextField jetzt ein PasswordField
      var pwField   = new qx.ui.form.PasswordField();
      with (pwField) {
        setPaddingLeft(10);
        setBorder(fBorder);
      }
      // Der Abschicken-Button
      var loginButton = new qx.ui.form.Button("einloggen", iconBasePath + "actions/decrypt.png");
      with (loginButton) {
        setBorder(bBorder);
        setMarginLeft(25);
        // dies fügt dem Button beim anklicken einen Funktionsaufruf hinzu
        // noch ein simples alert(1)
        addEventListener("execute", function (e) {
          alert(1);  
        });
      }
      // fügen wir das ganze unsere horizontalen Boxlayout hinzu
      with (loginForm) {
        add(userAtom, userField, pwAtom, pwField, loginButton);
        setHeight(50); // die Höhe müssen wir leider explizit angeben
        setPadding(10, 0);
      }
      // und fügen wir Überschrift, Subtext und das Formular (unser
      // horizontales Boxlayout) zu einem vertikalen Boxlayout hinzu
      with (login) {
        add(title, text, loginForm);
      }
      // das kombinierte Boxlayout fügen wir jetzt unserer Login-Page hinzu
      tpages[tx].add(login);
      ++tx;
Der Code ist etwas knifflig, weil er so verschachtelt ist, aber wenn ihr aufmerksam mitgelesen habt, solltet ihr den Code nun verstehen. Zumindest strukturell.

Fazit:
Der grafische Teil dieser Liga-Applikation wurde nun praktisch abgeschlossen. Mit relativ wenig Aufwand wurde eine ansehnliche Applikation geschaffen, die bekannte Window-Manager Funktionen des Betriebssystems simuliert.
Nachfolgen wird bald der zweite Teil, in dem aus der Dummy-Liga eine Bundesliga wird, die Ihre Daten mittels MySQL, PHP und JSON geliefert bekommt.
Keine Angst, JSON kommt nur kurz als Funktionsaufruf vor, wie JSON JavaScript per Ajax an PHP vermittelt, bekommen wir garnicht mit.

Viel Spass und Erfolg mit diesem Tutorial und dem Einstieg in qooxdoo.


[1] http://www.phpmyadmin.net
[2] http://www.apachefriends.org
[3] https://addons.mozilla.org/de/firefox/addon/1843
Zergling-new ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 14.08.2007, 17:12  
Erfahrener Benutzer
 
Benutzerbild von phpdummi
 
Registriert seit: 06.06.2008
Beiträge: 1.631
PHP-Kenntnisse:
Anfänger
phpdummi ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Schönes Tutorial, bin schon auf Teil 2 gespannt.
Vor allem die Live Demo gefällt mir, so kann jeder direkt mal "anfassen" bevor er bastelt.

PS: Der Link zum GUI Artikel auf Wikipedia "funktioniert nicht".
__________________
"Nobody is as smart as everybody" - Kevin Kelly
— The best things in life aren't things
phpdummi ist offline   Mit Zitat antworten
Alt 14.08.2007, 22:14  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Danke für das Feedback und den Hinweis! URL ist jetzt korrekt.

Leider ist im Skript auch immernoch ein Grafikpfadfehler, das wird auch bald gefixt. Möglicherweise ergänze ich Teil 2 noch um einen Teil 2B, der die Implementierung in Java aufzeigt.
Zergling-new ist offline   Mit Zitat antworten
Alt 17.08.2007, 21:49  
Neuer Benutzer
 
Registriert seit: 03.02.2006
Beiträge: 24
Spiff
Standard

Auch von mir ein dickes Lob für diesen wirklich anschaulichen Artikel.
Ich bin schon auf den nächsten Teil gespannt.

mfg
Spiff
Spiff ist offline   Mit Zitat antworten
Alt 19.08.2007, 11:02  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Danke schön.
Ich lerne grad selber jeden Tag mehr dazu und schon jetzt kommt mir der Code des Tutorials anfängerhaft vor, deshalb plane ich ihn Mitte September noch einmal zu überarbeiten. Die folgenden Tutorials verzögern sich deshalb dementsprechend
Zergling-new ist offline   Mit Zitat antworten
Alt 25.08.2007, 11:54  
Neuer Benutzer
 
Registriert seit: 21.08.2007
Beiträge: 1
salsamartin
Standard Sehr schoen!

Bin sehr gespannt auf die Ueberarbeitung von Teil 1 bzw. Teil2!
salsamartin ist offline   Mit Zitat antworten
Alt 25.01.2008, 10:41  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Als Nachtrag: Hatte leider keine Lust und Zeit mehr für Tutorial 2 und 3
Zergling-new ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

LinkBacks (?)
LinkBack to this Thread: http://www.php.de/tutorials/44583-javascript-php-qooxdoo-0-7-1-teil-1-eine-einfuehrung.html
Erstellt von For Type Datum
Gehörlose CafeForum &bull; Thema anzeigen - Eigene geile Komponente von Java Frameworks Qooxdoo This thread Refback 30.07.2010 13:46
Gehörlose CafeForum &bull; Thema anzeigen - Eigene geile Komponente von Java Frameworks Qooxdoo This thread Refback 26.02.2010 17:20
Gehörlose CafeForum &bull; Thema anzeigen - Eigene geile Komponente von Java Frameworks Qooxdoo This thread Refback 17.10.2009 16:09
Gehörlose CafeForum &bull; Thema anzeigen - Eigene geile Komponente von Java Frameworks Qooxdoo This thread Refback 17.09.2009 10:47
framework | qooxdoo | javascript | Mister Wong This thread Refback 17.07.2009 14:01
qooxdoo | domi27 | Favoriten | Mister Wong This thread Refback 23.05.2009 12:13

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
qooxdoo tutorial, qooxdoo, qooxdoo php, qooxdoo tutorial deutsch, qooxdoo mysql, qooxdoo deutsch, qooxdoo anleitung, qooxdoo beispiele, php qooxdoo, qooxdoo datenbank, qooxdoo php mysql, qooxdoo login, tutorial qooxdoo, qooxdoo php tutorial, qooxdoo einführung, qooxdoo deutsch tutorial, qooxdoo tutorials, qooxdoo php5 einführung, qooxdoo tabelle, qooxdoo mysql php

Alle Zeitangaben in WEZ +1. Es ist jetzt 21:25 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.