Das ist auch ein wenig älter, fiel mir letzens ein. Ich hatte mal aus Spaß eine Seite machen wollen, die aussieht wie ein Browser und sich teilweise auch so verhält. Damals war Firefox 1 noch aktuell, also habe ich den nachgebaut. Exakt wie in einer 1024×768 Darstellung. Die Lesezeichen sind das Menü, die Icons sind nur Deko, die Adresszeile könnte ein Rootline-Menü sein und als Highlight – der Loader dreht sich beim Rollover. Ich finds schick und ein wenig nostalgisch (wo Firefox 3 als Beta schon da ist).
Beiträge der Kategorie default
Fileupload Progress mit PHP und AJAX
Die Grundlagen dazu finden sich in dem Post davor, wo der Super-Simpel-Fileupload mit PHP erklärt worden ist. Das ist die Erweiterung des Beispiels, um den Fileupload auch ohne Reload üebrwachen zu können. Wie gesagt, die Beispiele, die ich gefunden habe, sind eigentlich ganz nett, aber haben meistens zu viel Code oder brauchen bestehende AJAX-Klassen, ich wollte ein Beispiel, das ohne weitere Dateien funktioniert. Ich habe es übrigends auch in eine Typo3-Extension gegossen.
Die Dateien im Beispiel davor habe ich alle mit dem Suffix _ajax versehen und bearbeitet. Das Formular bliebt, wie es ist, es kommt nur der Event-Handler onSubmit dazu, der nach dem Beginn des Uploads den Status abfragt. Das zweite iFrame, das sich ständig neugeladen hat, kommt auch raus, stattdessen werden hinter das Formular zwei divs gesetzt: response und response_counter. Im ersten wird der Ladebalken angezeigt und im zweiten will ich die Request zählen (einfach so), kann man nachher ausblenden. Das ist der Teil zwischen body-Start und -Ende.
$uid = rand(1000000,9999999);
?>
Dann braucht man noch einen AjaxRequest, den hab ich mir hier abgeschaut: http://www.w3schools.com/AJAX/ajax_server.asp. Beim Absenden des Formulars wird die Funktion upm_start mit er generierten Id aufgerufen (upm = upload progress manager), da werden alle Werte gespeichert und die Update-Funktion aufgerufen. Innerhalb der Update-Funktion wird progress_ajax mit der Upload-Id und einem zufälligen Wert aufgerufen (damit das Caching umgangen wird). Wenn die Antwort von progress_ajax in XML-Form zurückkommt, wird diese verarbeitet und es wird ein Ladebalken generiert. Danach wird mit einem Timeout die Funktion zur Fortschrittsabfrage erneut aufgerufen. Wenn der Upload fertig ist, wird aus dem iFrame heraus die Funktion upm_end aufgerufen, die die Request stoppt.
Zu beachten sind folgende Sachen:
Der IE mag es nicht, wenn man einen Request ein weiteres Mal verwendet, damit es keine Probleme gibt, muss die Callback-Funktion erneut bei onReadyStateChange hinzugefügt werden und zwar nach der Open-Anweisung.
Dann habe ich eine zusätzliche Abfrage eingebaut, um eventuelle Endlos-Schleifen zu vermeiden, es wird bei jedem leeren Request ein Zähler gesetzt und wenn dieser 100 erreicht, wird die Schleife gestoppt.
Wichtig bei der Rückgabe (progress_ajax.php) ist, dass man den Content-Type auf xml setzt, ansonsten steht die Eigenschaft responseXML nach der Rückgabe nicht zur Verfügung.
Man könnte auch setInterval verwendet, das hat aber den Nachteil, das die Requests gesendet werden unabhängig davon, ob der letzte zurückgekommen ist. Und so könnten mehrere Requests parallel unterwegs sein, was den Server auf Dauer und bei mehreren Benutzern verlangsamt.
function initAjax() {
if(window.ActiveXObject) {
try {
xmlHttp = new ActiveXObject(„Msxml2.XMLHTTP“);
} catch(e) {
try {
xmlHttp = new ActiveXObject(„Microsoft.XMLHTTP“);
} catch(e) {
return false;
}
}
} else if(window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
function upm_start(upload_id) {
upm_counter = 0;
upm_upload_id = upload_id;
upm_started = 1;
total_negative = 0;
document.getElementById(„response“).innerHTML = „“;
document.getElementById(„response_counter“).innerHTML = „“;
upm_update();
}
function upm_update() {
upm_counter++;
if(upm_started == 1 && total_negative < 100) {
document.getElementById("xajax_response_counter").innerHTML+= upm_counter;
var randNum = Math.ceil(Math.random()*1000);
xmlHttp.open("GET","progress_ajax.php?uid="+upm_upload_id+"&r="+randNum,false);
// set the readystatechange again for IE to reuse the object
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState==4 && xmlHttp.status == 200) {
displayProgress();
}
}
xmlHttp.send(null);
}
}
function displayProgress() {
document.getElementById("response_counter").innerHTML+= "| ";
response = xmlHttp.responseXML.documentElement;
var loaded = 0;
var total = -1;
var time = 0;
var speed = 0;
var est_sec = 0;
// Bytes loaded
try {
loaded = response.getElementsByTagName("loaded")[0].firstChild.data;
} catch(e) {}
// Bytes total
try {
total = response.getElementsByTagName("total")[0].firstChild.data;
} catch(e) {}
// PHP time() function value -> to check how often the request are send
try {
time = response.getElementsByTagName(„time“)[0].firstChild.data;
} catch(e) {}
// speed
try {
speed = response.getElementsByTagName(„speed“)[0].firstChild.data;
} catch(e) {}
// est_sec
try {
est_sec = response.getElementsByTagName(„est_sec“)[0].firstChild.data;
} catch(e) {}
//
if(total == -1) total_negative++;
var percent = Number(loaded/total*100).toFixed(2);
var width = Math.round(percent * 2.5);
var progress = „
progress+= „
„;
progress+= „
„;
document.getElementById(„xajax_response“).innerHTML = progress;
window.setTimeout(„upm_update()“,500);
}
function upm_end() {
document.getElementById(„response“).innerHTML = „“;
upm_started = 0;
}
function formatSeconds(sec) {
var min = Math.floor(sec/60);
var hour = Math.floor(min/60);
if(hour > 1) {
return hour+“ h „+min+“ m“;
} else if(min > 1) {
return min+“ m „+sec+“ s“;
} else {
return sec+“ s“;
}
}
function formatBytes(b) {
var kb = Number(b / 1024);
var mb = Number(kb / 1024);
var gb = Number(mb / 1024);
if(gb > 1) {
return gb.toFixed(2)+“ GB“;
} else if(mb > 1) {
return mb.toFixed(2)+“ MB“;
} else if(kb > 1) {
return kb.toFixed(2)+“ KB“;
} else {
return b.toFixed(2)+“ B“;
}
}
initAjax();
Das in den Header der result_ajax.php
window.parent.upm_end();
header('Content-Type: text/xml');
echo '‚;
$upload_id = $_GET[‚uid‘];
$xml = ‚‚;
echo $xml;
?>
UPDATE 26.August 2008: Hatte mit diesem Stückchen Code in den letzen Tagen tierische Probleme in den letzen Monaten. Zunächst mal funktionierte es nicht auf dem Mac – weder unter Firefox, noch unter Safari, nix. Hat mich wahnsinnig gemacht. Die Lösung war sehr dirty und nicht quick – ich musste den kompletten Upload Bar (in HTML) generieren und zurückgeben lassen, weil das Auswerten des XML-Objektes irgendwie nicht wollte. Soll auch ein bekanntes Problem sein, hab ich gehört.
Nun die nächste Problem: Unter Firefox 3 tats nicht. Also recherchiert – Firebug Bugs, Caching Probleme etc. Zum Glück gabs diesmal eine schöne Lösung, anstatt GET einfach POST zu verwenden:
xmlHttp.open(„POST“,“progress_ajax.php?uid=“+upm_upload_id+“&r=“+randNum,true);
Fileupload Progress mit PHP (simpel)
Manchmal wünscht man sich, man könnte den Upload von Dateien überwachen. Normalerweise ist das so: man wählt im Formular eine Datei aus und wartet, bis sie irgendwann hochgeladen ist. Es wäre natürlich schön, wenn man während des Uploads ein Feedback hätte – wie viel bereits hochgeladen wurde, wie schnell etc.
PHP kann das von sich aus nicht, aber nach einiger Recherche bin ich auf diese Seite gestoßen: http://php5.bluga.net/UploadProgressMeter/demo.php. Dort wird ein PECL Package benutzt, das eine Funktion zur Verfügung stellt, um den Uploadvorgang zu überwachen. Das Package gibt es hier: http://pecl.php.net/package/uploadprogress.
Das Beispiel funktioniert auf der Seite wunderbar, man kann sich es zwar herunterladen, aber da fehlt der komplette AJAX-Server und zur Verdeutlichung ist es ein wenig wie mit Kanonen auf Spatzen schießen. Daher habe ich ein eigenes kleines Beispiel gebaut, das alle nötigen Elemente enthält und erstmal ohne AJAX funktioniert. Vielleicht kommt ein AJAX-Bespiel mal dazu.
Aufbau: upload.php enthält ein Formular und zwei iFrames – in das obere wird die Datei geladen, im unteren zeigt man den Status an. Das Zielframe ist sinnvoll, damit die Seite sich nicht aufhängt und nicht neugeladen werden muss. Im Progressframe ist eine Datei, die den Status abfragt und sich jede Minute aktualisiert. Wichtig im Formular folgende Felder: UPLOAD_IDENTIFIER ist eine Id, über die der Upload abgefragt werden kann, ein Input-Feld vom Type file (logisch) und ein Button. Nicht vergessen im Formular method und enctype zu setzen, target ist das iFrame.
// upload.php Auszug <body> <iframe src="" name="upload_target"></iframe> <br /> <iframe src="progress.php" name="upload_progress"></iframe> <br /> <form action="result.php" method="post" method="post" enctype="multipart/form-data" target="upload_target"> <input type="hidden" name="UPLOAD_IDENTIFIER" value="123456789" /> <input type="file" name="upload_file" /> <input type="submit" name="submit_file" value="upload file" /> </form> </body>
// progress.php Auszug <meta http-equiv="refresh" content="1; URL=progress.php"> // ... $uid = '123456789'; if(function_exists('uploadprogress_get_info')) { $progress = uploadprogress_get_info($uid); print_r($progress); }
// result.php Auszug $uid = '123456789'; print_r($_POST); print_r($_FILES);
Den Krams drumrum selber denken (html, head, body, php Einleitungstags etc.) Beispiel hier mach ich nicht – mein Speicherplatz ist begrenzt 😉
Frohe Weihnachten und einen Guten Start ins neue Jahr 2008
Ich wollte meinen Lesern (falls es welche gibt außer mir) ein geruhsames und frohes Weihnachtsfest wünschen. Ich hoffe, ihr habt auch frei, so wie ich und könnt erholt und voller Tatendrang ins neue Jahr starten.
Neuer Job
Ich wohne und arbeite am jetzt in Köln. Grad mal seit einer Woche am Arbeiten und schon zwei Typo3-Extensions entwickelt, geht gleich richtig zur Sache hier. Netterweise hat mein Foto und eine Begrüßung gleich auf der Firmenseite einen Platz gefunden, wo auch ein Link zu diesem Blog zu finden ist.
Neue Mitarbeiterin
Noch zwei witzige Sachen über das Unternehmen: die Initialien stimmen überein. Es macht echt Spaß Extensions zu entwickeln, die mit np_ beginnen. Dann scheinen die Jungs hier auch grün zu mögen (die Frösche kann ich ja nach und nach einschmuggeln).
Sinnvolle Software
Innerhalb von zwei Jahren habe ich auf meinem Rechner so viel installiert, daher dachte ich mir, ich stelle eine kleine Liste zusammen mit sinnvoller Software, damit ich dann nicht lange suchen muss. Alle hier aufgelisteten Programme sind entweder frei verfügbar der Open Source.
Das erste was man braucht, ist ein Antivirus-Programm. Da gibt es einige, für die man bezahlen muß, gibt aber auch sehr gute, die für Privatanwender umsonst sind. Da gibt es z.B. BitDefender oder Antivir von Avira.
Dann gibt es noch ein Tool zum Entfernen von Spyware: Ad-Aware von Lavasoft.
Ein nettes Soundbearbeitungsprogramm ist Audacity – die Oberfläche sieht billig aus, aber man kann damit Sounddateien bearbeiten, abspeichern, in diverse Formate exportieren, mischen etc.
Auch sehr cool ist CDex, damit kann man seine CDs für Backupzwecke rippen oder in mp3 umwandeln.
Sehr schön ist auch ein PDF-Drucker wie CutePDF. Damit kann man (fast) alle Dateien in ein PDF Drucken. Funktioniert sogar besser als der PDF-Export in Open Office.
Sehr geiler und schlanker Musikplayer ist Foobar2000. Damit kann man verschiedene Formate und Streams abspielen und es ist viel handlicher als das mittlerweile bloatige WinAmp.
Zum Abspielen von Videos gibt es zwei sehr gute Player – VLC ist sehr klein, gut zu bedienen und kann die meisten Formate ohne Probleme abspielen, mplayer bringt so viele Codecs mit, dass man damit wirklich jedes Format abspielen kann.
Mit TrueCrypt kann man seine Festplatte oder auch nur Dateien verschlüsseln.
POV-Ray ist ein 3D-Renderer. Die Szene und Animationen werden mit einer Skriptsprache definiert und dann vom Renderer zu einem Bild gerendert. Die Beispiele finde ich sehr beeindruckend.
Auch ganz schick zum Gestalten ist Processing. Das ist eine Programmiersprache auf Javabasis, die es ermöglicht, Animationen und Vektorgrafiken zu zeichnen. Contra: Java, daher langsam.
Firefox Add-ons
Es gibt viele Listen mit Firefox Add-Ons: für Security, für Webentwickler, zum Bilder gucken etc. Das ist eine Liste mit denen, die ich gerne nutze, hab ich zusammengestellt, damit ich die schnell auf einem anderen Browser installieren kann.
Web Developer – CSS ein- und ausschalten, Bereiche ein- und ausblenden, Quelltext
https://addons.mozilla.org/de/firefox/addon/60
Firebug – Quelltext optionen, Ladegeschwindigkeiten, Styleeigenschaften etc.
https://addons.mozilla.org/de/firefox/addon/1843
MeasureIt – ein Lineal, mit dem man Abstände abmessen kann
https://addons.mozilla.org/de/firefox/addon/539
ColorZilla – Color picker für die Seite, Zoom-Funktionalität
https://addons.mozilla.org/de/firefox/addon/271
Cache Status – Cache-Anzeige und -Verwaltung in der Statusleiste, Cache löschen mit 2 Klicks
https://addons.mozilla.org/de/firefox/addon/1881
Extended Cookie Manager – Cookieregeln für alle Webseiten schnell einzeln festlegen
https://addons.mozilla.org/de/firefox/addon/1243
Die folgenden Add-ons sind nicht unbedingt notwendig, aber trotzdem sehr praktisch.
del.icio.us – falls man ein del.icio.us Account hat, kann man seine Bookmarks schnell verwalten. Es gibt einige Extensions mit diesem Namen, zwei sind ganz gut.
del.icio.us Bookmarks – überschreibt leider die lokalen Bookmarks und fügt eine Sidebar hinzu, die das Durchsuchen einfacher macht.
https://addons.mozilla.org/de/firefox/addon/3615
del.icio.us Buttons – einfach und schön, fügt zwei Buttons: Tag und MyBookmarks hinzu, völlig ausreichend
https://addons.mozilla.org/de/firefox/addon/1532
(gibt auch für Mr.Wong https://addons.mozilla.org/de/firefox/addon/2136)
Down Them All! – komplexer Downloadmanager
https://addons.mozilla.org/de/firefox/addon/201
IE Tab – ermöglicht das Anschauen von Webseiten mit der IE Engine (wenn da bloss die Developer-Extensions funktionieren würden)
https://addons.mozilla.org/de/firefox/addon/1419
NoScript – erlaubt das Ausführen von JavaScript nur von bestimmten Seiten, am Anfang etwas nervig, aber auch sehr nützlich, denn man bekommt weniger Werbung
https://addons.mozilla.org/de/firefox/addon/722
SeoQuake – zweigt PageRank der Seite, Keywords an, ich empfehle aber das Seitenparsen auszustellen
https://addons.mozilla.org/de/firefox/addon/3036
YSlow – analysiert die Webseite und gibt Ratschläge, wie man die Performance verbessern kann
https://addons.mozilla.org/de/firefox/addon/5369
On-the-fly Suche mit JavaScript
Es war mal eine Textdatei. Da haben unterschiedliche Leute etwas reingeschrieben, z.B. Kochrezepte. Da Textdateien nicht strukturiert sind, wurde es immer schwieriger, in der Datei etwas zu finden (ok, von der Benutzung von Strg+F mal abgesehen). Da entstand die Idee aus der Textdatei eine HTML-Datei zu machen und mit einer Suche zu versehen, die sucht während man tippt. Am besten sollten die Inhalte immernoch für alle pflegbar sein und trotzdem strukturiert.
Ich hab rausgefunden, dann man in HTML auch auf XML-Daten zurückgreifen kann, wenn man sie per JavaScript lädt. Zunächst erstellt man eine XML-Datei. Da legt man in dem Dokumentelement viele Knoten an, in denen jeweils Texte drinstehen. In diesem Fall heißen die Knoten entry und haben drei Unterknoten: title, desc (für description) und tags. Diese Datei speichert man als food.xml ab.
Dann erstellt man eine HTML-Datei. Diese hat erstmal das Grundgerüst, also head und body. In den Head kann man ein wenig Style-Eigenschaften einfügen. Im Body erstellt man ein Element mit der Id „page“ – da kommen dann die Ergenbisse rein und die Suchbox. Die Suchbox ist ein input-Feld, der Korrektheit halber packt man noch ein Form drumrum und fügt hinter das Eingabefeld ein Div ein, wo das getippte angezeigt wird (nur zur Kontrolle). Das Eingabefeld wird mit einem Event-Listener, nämlich on KeyUp versehen. Warum nicht onChange? Weil onChange erst ausgelöst wird, wenn man das Feld verläßt und wir wollen ja währenddessen suchen und onKeyUp meldet nach jeder Tasteneingabe. Die Suchbox hat eine Id (damit man darauf zugreifen kann) und von mir aus eine Klasse.
Was will man eigentlich durchsuchen? Die Daten stehen ja in der XML-Datei. Zunächst soll die Datei eingelesen und der Inhalt dargestellt werden. Beim Suchen werden die relevanten Teile ein- und ausgeblendet. Und um rauszufinden, welche Teile relevant sind, sollten die Inhalte vorher indiziert werden. Also: einlesen, darstellen, indizieren.
Das Einlesen sollte beim Aufruf der Seite stattfinden, also im body onLoad. Da wird die Funktion importXML aufgerufen. Nach einigem Suchen habe ich ein Skript gefunden, das meinen Vorstellungen entspricht und die XML-Datei „importiert“ abhängig vom Browser. Wenn der Import beendet ist, werden die Inhalte dargestellt. Dazu holt man sich alle Elemente mit dem Tag entry. Den Inhalt von title fügt man in ein h1 ein, den Inhalt in ein p, aber erst nachdem man alle Zeilenumbrüche in br umgewandelt hat. Und die Tags kommen in eine Liste.
Wenn man mit dem Darstellen fertig ist, dann muss nur noch indiziert werden. Dazu läuft man alle entry-Elemente wieder durch und speichert die Daten in einem assoziativen Array. Die Indizes sind die Id des div-Elementes, in dem der Inhalt drin steht.
Die Funktion search ist daher ganz einfach: man läuft das assoziative Array ab und erfragt die Position des gesuchten Begriffes. Falls der Begriff vorkommt, setzt man die Sichtbarkeit des dazugehörigen div-Elementes auf true, ansonsten auf false (oder in diesem Fall display auf block bzw. none).
Zu beachten ist: es sollten keine Umlaute verwendet werden, weil dann der IE die Datei nicht lädt und nur meldet „Object erwartet“ (die Fehlermeldung, die nur vor Aussagekraft strotz) und die Tags sollten richtig verschachtelt werden.
Und hier das Ergebnis:
XML-Datei als Vorlage
Suche mit JavaScript
PS: Vielen Dank an Maryna Hetsyuk für die wertvolle Hilfe, ist immer wieder sehr lustig 🙂
PayPal in Seite einbauen
Das ist eine einfach Möglichkeit, eine Abwicklung der Bezahlung über PayPal in eine Seite einzubauen. Da ich nichts dazu gefunden habe, wie man es macht, hier eine kleine Anleitung, für die die gar keine Ahnung davon hatten, so wie ich.
Bei PayPal gibt es zum Testen eine Developer Umgebung und eine Sandbox, in der man Testaccounts anlegen kann. Die Developer Umgebung findet man hier https://developer.paypal.com/. Da kann man sich ein Testaccount als Entwickler anlegen, z.B. als test@test.de.
Dann legt man sich zwei Testaccounts an, einen Verkäufer und einen Käufer. Dabei gibt man als Zugangsdaten eine leicht Abweichende E-Mail-Adresse ein, aus dieser wird PayPal sowieso eine Test-E-Mail-Adresse generieren, das könnte z.B. testseller@test.de sein. Die E-Mail Adresse wird gekürzt und um eine zufällige Zahl ergänzt.
Wenn man zwei Test-Accounts hat, kann man sich in der Sandbox einloggen. Dazu wählt man einen Account aus und drückt auf den Button „Enter Sandbox Test Site“. Das ist aber nur so zum Spaß.
Auf der Integration Center Seite findet man eine Anleitung dazu, wie man PayPal in die eigene Seite einbauen kann. Ich habe mich für die Website Payments Standard Methode entschieden. Das Bestellformular ist sehr einfach und soll erstmal nur die Artikel anzeigen mit einem Eingabe bzw. Auswahlfeld für die Menge. Das ist ein Einspiel-PHP-Code:
while ( $row = mysql_fetch_array( $aQResult ) ) {
$i++;
echo ‚
echo ‚
‚;
echo ‚
‚;
echo ‚
‚;
if($row[„link“]!=““) {
echo ‚
‚;
} else {
echo ‚
echo ‚
‚;
}
echo ‚
‚;
}
Das Formular wird an die Seite selbst gesendet. Dort werden die Artikel ausgewertet. Falls die Summe 0 ist, dann eine Fehlermeldung anzeigen. Ansonsten werden die bestellten Artikel angezeigt und die Summe berechnet. PHP-Code-Schnipsel dafür:
$sum = 0;
$paypal = “;
while ( $row = mysql_fetch_array( $aQResult ) ) {
if($_POST[‚amounts_‘.$row[„Nr“]] > 0) {
$amount = $_POST[‚amounts_‘.$row[„Nr“]];
$price = $row[„VK“]*$amount;
$sum+= $price;
echo ‚
for($i=0;$i<$amount;$i++) { $paypal.= '‚;
$paypal.= ‚‚;
$paypal_counter++;
}
echo ‚
‚.$row[„Bez“].‘
‚;
echo ‚
‚;
echo ‚
‚;
echo ‚
‚;
}
echo ‚
‚;
}
echo ‚
‚;
if($sum > 0) {
echo ‚
‚;
} else {
echo ‚
‚;
}
Der PayPal Counter ist extra notwenig, weil in der Anleitung steht, dass die Artikel durchnummeriert sein müssen und keine Zahl ausgelassen werden darf. Falls von zwei Artikeln mehrere bestellt worden sind, wird die Bestellung wieder in Einzelteile aufgeteilt.
Damit das Formular richtig verarbeitet werden kann, fehlen noch einige Daten, nämlich der Formularbeginn:
Quellcode Formatierung in WordPress
Ich hab ein Plugin installiert zur Quellcode-Formatierung, funktioniert super! (bis jetzt)
Nennt sich Coolcode, hier der Link http://cnwper.cn/category/plugins/coolcode
Neueste Kommentare