<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>zeroseven labs &#187; JavaScript</title>
	<atom:link href="http://labs.zeroseven.de/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.zeroseven.de</link>
	<description></description>
	<lastBuildDate>Wed, 28 Jul 2010 07:43:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>JavaScript-Fehler bei TMENU_LAYERS</title>
		<link>http://labs.zeroseven.de/development/typo3/javascript-fehler-bei-tmenu_layers/</link>
		<comments>http://labs.zeroseven.de/development/typo3/javascript-fehler-bei-tmenu_layers/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 08:59:07 +0000</pubDate>
		<dc:creator>albrechtk</dc:creator>
				<category><![CDATA[TYPO3]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[TMENU_LAYERS]]></category>

		<guid isPermaLink="false">http://labs.zeroseven.de/?p=840</guid>
		<description><![CDATA[Bei der Entwicklung eines neuen Projekts in TYPO3, verwendeten wir für ein Layer-Menü die fertige Komponente TMENU_LAYERS. In willkürlichen Intervallen tauchten JavaScript-Fehler auf und die Navigation konnte nicht benutzt werden. Im Internet Explorer tauchte ein Alert-Fenster mit der Meldung &#8220;Stack overflow&#8221; auf, während der Firefox zwar nicht mit einer penetranten Meldung nervte, aber dennoch einen [...]]]></description>
			<content:encoded><![CDATA[<p>Bei der Entwicklung eines neuen Projekts in TYPO3, verwendeten wir für ein Layer-Menü die fertige Komponente TMENU_LAYERS. In willkürlichen Intervallen tauchten JavaScript-Fehler auf und die Navigation konnte nicht benutzt werden. Im Internet Explorer tauchte ein Alert-Fenster mit der Meldung &#8220;Stack overflow&#8221; auf, während der Firefox zwar nicht mit einer penetranten Meldung nervte, aber dennoch einen Fehler &#8220;too much recursion&#8221; in die Fehlerkonsole schrieb.</p>
<p><span id="more-840"></span></p>
<p><a rel="lightbox[recursion]" href="http://labs.zeroseven.de/wp-content/uploads/2009/04/recursion-ie.png"><img class="alignnone size-full wp-image-841" style="vertical-align: top; border: 1px solid #656565;" src="http://labs.zeroseven.de/wp-content/uploads/2009/04/recursion-ie.png" alt="Stack overflow" width="203" height="119" /></a> <a rel="lightbox[recursion]" href="http://labs.zeroseven.de/wp-content/uploads/2009/04/recursion-firefox.png"><img class="alignnone size-thumbnail wp-image-842" style="vertical-align: top; border: 1px solid #656565;" src="http://labs.zeroseven.de/wp-content/uploads/2009/04/recursion-firefox-150x150.png" alt="too much recursion" width="150" height="150" /></a></p>
<p>Wie bereits erwähnt, tauchte der Fehler völlig unregelmäßig auf und ließ sich nicht reproduzieren. In so einem Fall ist eine Fehlersuche nahezu unmöglich, da man den Code von Grund auf analysieren und überarbeiten müsste. Auch eine Suche über Google zu diesem Problem ergab keine hilfreichen Ergebnisse.</p>
<p>Nach mehreren gescheiterten Ansätzen, das Problem in der JavaScript-Datei zu suchen und zu beheben, stolperte ich auf die Vergabe der IDs, mit denen JavaScript die HTML-Objekte ansprechen und ein- und ausblenden kann. Diese Vergabe findet in der Datei <code>tmenu_layers.php.inc</code> statt und sieht (vereinfacht) so aus:</p>
<pre>$this-&gt;WMid = substr(md5(microtime()),0,6);</pre>
<p>Das bedeutet, dass für jedes Element eine ID aus der Micro-Time generiert wird und von dem Hash lediglich die ersten 6 Stellen als ID benutzt werden. Ich weiß nicht genau, ob es an der Kürze des Hashes oder an den Millisekunden als Grundlage lag, aber diese Vorgehensweise zur ID-Generierung erzeugte Kollisionen und vergab die IDs hin und wieder an mehrere HTML-Elemente gleichzeitig.</p>
<p>Um diese Kollisionen zu verhindern, änderte ich die ID-Vergabe um und nahm die PHP-Funktion <code>uniqid()</code> als Grundlage. Diese Funktion basiert zwar auch auf der aktuellen Micro-Time, lässt sich aber mit einen Parameter dazu bringen, die Rückgabe zusätzlich mit einem Zufallswert zu erweitern. Da dieser Zufallswert mit einem <code>.</code> angehängt wird, dies aber einen JavaScript-Fehler verursachen würde, habe ich anschließend noch alle Punkte aus der Rückgabe entfernt.</p>
<p>Die neue ID-Vergabe in der Datei <code>tmenu_layers.php.inc</code> sieht jetzt (vereinfacht) so aus:</p>
<pre>$this-&gt;WMid = str_replace('.','',uniqid('',true));</pre>
<p>Seit dieser Änderung ist der JavaScript-Fehler nicht mehr aufgetaucht. Ich gehe also davon aus, dass es die korrekte Lösung war.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.zeroseven.de/development/typo3/javascript-fehler-bei-tmenu_layers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CSS-Style für Select-Boxen</title>
		<link>http://labs.zeroseven.de/development/html-css/css-style-fur-select-boxen/</link>
		<comments>http://labs.zeroseven.de/development/html-css/css-style-fur-select-boxen/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 08:59:58 +0000</pubDate>
		<dc:creator>albrechtk</dc:creator>
				<category><![CDATA[HTML / CSS]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[Selectbox]]></category>

		<guid isPermaLink="false">http://labs.zeroseven.de/?p=735</guid>
		<description><![CDATA[Das HTML-Element &#60;select&#62; lässt sich kaum optisch anpassen. Primitivste Änderungen, wie z.B. die Breite oder der Border sind hier schon beinahe das höchste der Gefühle. Wenn man aber den Anspruch hat, wirklich optisch ansprechende Webauftritte zu erstellen, kann das nicht zufrieden stellen. Abhilfe schafft hier eine Lösung mit JavaScript.

Die Idee, die dahinter steckt ist folgende: [...]]]></description>
			<content:encoded><![CDATA[<p>Das HTML-Element <code>&lt;select&gt;</code> lässt sich kaum optisch anpassen. Primitivste Änderungen, wie z.B. die Breite oder der Border sind hier schon beinahe das höchste der Gefühle. Wenn man aber den Anspruch hat, wirklich optisch ansprechende Webauftritte zu erstellen, kann das nicht zufrieden stellen. Abhilfe schafft hier eine Lösung mit JavaScript.</p>
<p><span id="more-735"></span></p>
<p>Die Idee, die dahinter steckt ist folgende: Mit JavaScript wird das zu verändernde <code>&lt;select&gt;</code>-Element angesprochen. Dies kann entweder mit einer Schleife erfolgen, welche das ganze Dokument durchsucht oder selbstverständlich auch explizit für einzelne Elemente. Die entsprechenden Elemente werden anschließend durch einen neuen HTML-Code ersetzt, der ungefähr so aussehen könnte:</p>
<pre>&lt;div class="style-me"&gt;
	&lt;span class="show-text" id="show-text"&gt;&lt;/span&gt;
	&lt;img src="dropdown-arrow.gif" alt="" /&gt;
	&lt;select&gt;...&lt;/select&gt;
&lt;/div&gt;</pre>
<p>Das ursprüngliche <code>&lt;select&gt;</code>-Element wird hierbei nicht weg geworfen, sondern per CSS mit <code>position: absolute;</code> bzw. <code>position: relative;</code> über das neue <code>&lt;div&gt;</code> gelegt und anschließend kann die Opazität auf 0 gesetzt werden.</p>
<p>Hier ein kleines Beispiel zur Verdeutlichung. Links das fertige Element. Rechts zur Demonstration mit einem halbdurchsichtigen <code>&lt;select&gt;</code>-Element.</p>
<p><img class="alignnone size-full wp-image-742" src="http://labs.zeroseven.de/wp-content/uploads/2009/01/transselectbox.png" alt="Transparente Selectbox" width="459" height="187" /></p>
<p>Dadurch, dass die Selectbox noch existiert und oben liegt, kann der User ganz normal darauf klicken und in der Selectbox die gewünschte Option auswählen. Die Selectbox erhält dann den entsprechenden Wert, der beim Absenden des Formulars regulär mitgeschickt wird. Wir müssen lediglich mit einem <code>onchange</code>-Event den Text des gewählten Wertes auslesen und in unser neu erstelltes HTML-Element schreiben.</p>
<p>Wir können anschließend das neue <code>&lt;div&gt;</code>-Element beliebig mit CSS manipulieren, eine Hintergrundgrafik vergeben, die Schrift ändern. Außerdem habe ich im Beispiel-Code oben eine Grafik mit eingefügt. Diese kann beliebig gewählt werden, so dass die perfekte Illusion einer gestylten Selectbox entsteht.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.zeroseven.de/development/html-css/css-style-fur-select-boxen/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>HTML in Flex Applikationen einbinden</title>
		<link>http://labs.zeroseven.de/development/flex/html-in-flex-applikationen-einbinden/</link>
		<comments>http://labs.zeroseven.de/development/flex/html-in-flex-applikationen-einbinden/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 08:25:42 +0000</pubDate>
		<dc:creator>juergenm</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[ExternalInterface]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://labs.zeroseven.de/?p=380</guid>
		<description><![CDATA[Mithilfen der HTMLLoader Komponente kann man in Adobe AIR komplette HTML Seiten laden und anzeigen. So kann man einfach seinen eigenen Webrowser bauen. Die HTMLLoader Klasse gibt es aber leider nur für AIR und nicht in Flex, da eine Flex Applikation ja normalerweise in einem Webbrowser läuft. Doch es gibt eine Möglichkeit HTML Inhalt innerhalb [...]]]></description>
			<content:encoded><![CDATA[<p>Mithilfen der HTMLLoader Komponente kann man in Adobe AIR komplette HTML Seiten laden und anzeigen. So kann man einfach seinen eigenen Webrowser bauen. Die HTMLLoader Klasse gibt es aber leider nur für AIR und nicht in Flex, da eine Flex Applikation ja normalerweise in einem Webbrowser läuft. Doch es gibt eine Möglichkeit HTML Inhalt innerhalb einer Flex Applikation darzustellen. Das HTML Dokument das die Flex Applikation einbindet enthält einen IFrame der die HTML Seite lädt. Nun wird der IFrame über die Flex Applikation gelegt und per JavaScript positioniert. So entsteht der Eindruck die Flex Applikation enthält eine HTML Seite.</p>
<p><span id="more-380"></span></p>
<p><strong>HTML Dokument vorbereiten</strong></p>
<p>Das HTML Dokument in dem die Flex Applikation eingebunden wird muss einen absolut positionierten div Container enthalten in dem ein IFrame erzeugt wird der wiederum die HTML Seite anzeigt:</p>
<pre>&lt;div id="myFrame"
style="position:absolute; background-color:transparent; border:0px;
visibility:hidden;"&gt;&lt;/div&gt;</pre>
<p>Wichtig ist, dass dieser div Container ganz am Ende des HTML Dokuments steht um den Container über die Flex Applikation legen zu können.</p>
<p>Über die JavaScript Funktion loadIFrame wird innerhalb des div Containers ein IFrame erstellt und die von Flex übergebene url wird aufgerufen.</p>
<pre>function loadIFrame(url){
	document.getElementById("myFrame").innerHTML =
	"&lt;iframe id='myIFrame' src='" + url + "'frameborder='0'&gt;&lt;/iframe&gt;";
}
</pre>
<p>Danch wird von Flex aus die JavaScript Function moveIFrame aufgerufen um die Größe und die Position des IFrames einzustellen.</p>
<pre>function moveIFrame(x,y,w,h) {
    var frameRef=document.getElementById("myFrame");
    frameRef.style.left=x;
    frameRef.style.top=y;
    var iFrameRef=document.getElementById("myIFrame");
	iFrameRef.width=w;
	iFrameRef.height=h;
}
</pre>
<p>Nun kann von Flex aus die Sichtbarkeit des IFrames über die beiden Funktionen showIFrame und hideIFrame gesteuert werden.</p>
<pre>function showIFrame(){
    document.getElementById("myFrame").style.visibility="visible";
}

function hideIFrame(){
    document.getElementById("myFrame").style.visibility="hidden";
}
</pre>
<p>Damit ist das HTML Dokument fertig, jetzt müssen wir die IFrame Klasse in Flex einbinden.</p>
<p><strong>IFrame in Flex Applikation einfügen:</strong></p>
<p>Um die HTML Seite einbetten zu können wird die IFrame Klasse benötigt. Diese ruft über <a href="http://labs.zeroseven.de/2008/08/flash-externalinterface/">ExternalItnerface.call()</a> die JavaScript Funktionen in unserem HTML Dokument auf.</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
    resize="callLater(moveIFrame)"
    move="callLater(moveIFrame)"&gt;
    &lt;mx:Script&gt;
    &lt;![CDATA[
        import flash.external.ExternalInterface;
        import flash.geom.Point;
        import flash.net.navigateToURL;

        private var __source: String;

        /**
         * Move iframe through ExternalInterface.
         * The location is determined using localToGlobal()
         * on a Point in the Canvas.
         **/
        private function moveIFrame(): void {
            var localPt:Point = new Point(0, 0);
            var globalPt:Point = this.localToGlobal(localPt);
            ExternalInterface.call("moveIFrame", globalPt.x, globalPt.y,
                        this.width, this.height);
        }

        /**
         * The source URL for the IFrame.
         * When set, the URL is loaded through ExternalInterface.
         **/
        public function set source(source: String): void {
            if (source) {
				trace(source);
                if (! ExternalInterface.available) {
                    throw new Error("ExternalInterface is not available in
                    this container. Internet Explorer ActiveX, Firefox,
                    Mozilla 1.7.5 and greater, or other browsers that
                    support NPRuntime are required.");
                }
                __source = source;
                ExternalInterface.call("loadIFrame", source);
                moveIFrame();
            }
        }

        public function get source(): String {
            return __source;
        }

        /**
         * Whether the IFrame is visible.
         **/
        override public function set visible(visible: Boolean): void {
            super.visible=visible;
            if (visible) {
                ExternalInterface.call("showIFrame");
            } else {
                ExternalInterface.call("hideIFrame");
            }
        }

    ]]&gt;
    &lt;/mx:Script&gt;
&lt;/mx:Canvas&gt;
</pre>
<p>Wird nun über IFrame.source eine URL festgelegt wird der IFrame im HTML Dokument erzeugt und die Seite mit der angegebenen URL geladen. Dann wird sofort die Funktion moveIFrame() aufgerufen, die den HTML-IFrame anhand der größe des Flex-IFrames skaliert und positioniert. Wenn jetzt der IFrame auf visible = true gesetzt wird, wird dieser sichtbar und man hat den Eindruck der HTML Content sei direkt in der Flex Applikation eingebettet.</p>
<p><strong>Probleme dieser Lösung</strong></p>
<p>Schon in den ersten Tests ergaben sich folgende Probleme dieser Lösung mit dem IFrame:</p>
<ul>
<li>Da der IFrame über der Flex Applikation liegt werden eventuelle PopUps überlagert.<br />
Lösung:</p>
<ul>
<li>Wenn ein PopUp von Flex generiert wird muss der IFrame auf visible = false gesetzt werden.</li>
<li>- Das PopUp muss so positioniert werden, dass es vom IFrame nicht überlagert wird.</li>
</ul>
</li>
<li>Framesets werden nicht fehlerfrei dargestellt.</li>
<li></li>
<li>Drag&amp;Drop Ereignisse über dem IFrame werden von Flex nicht mehr erkannat.</li>
</ul>
<p>Aufgrund der oben angesprochenen Probleme ist die IFrame Lösung für größere Anwendungen wohl nicht die optimale Option. Dennnoch finde ich den Ansatz interessant und für nicht sehr aufwändige Applikationen auf jeden Fall empfehlenswert.</p>
<p><strong>Links</strong><br />
<a href="http://www.deitte.com/IFrameDemo3/IFrameDemo.html">http://www.deitte.com/IFrameDemo3/IFrameDemo.html</a><br />
<a href="http://www.judahfrangipane.com/blog/?p=137">http://www.judahfrangipane.com/blog/?p=137</a></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.zeroseven.de/development/flex/html-in-flex-applikationen-einbinden/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>User-Bestätigung bevor Dateien gelöscht werden</title>
		<link>http://labs.zeroseven.de/development/typo3/user-bestatigung-bevor-dateien-geloscht-werden/</link>
		<comments>http://labs.zeroseven.de/development/typo3/user-bestatigung-bevor-dateien-geloscht-werden/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 07:34:10 +0000</pubDate>
		<dc:creator>albrechtk</dc:creator>
				<category><![CDATA[TYPO3]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Extension]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jm_gallery]]></category>
		<category><![CDATA[Template]]></category>

		<guid isPermaLink="false">http://labs.zeroseven.de/?p=180</guid>
		<description><![CDATA[Die Typo3-Extension &#8220;jm_gallery&#8221; bietet eine umfangreiche Fotogalerie. Dazu gehört die Aufteilung in Kategorien, anlegen verschiedener Alben, eine Kommentarfunktion zu den Bildern und viele weitere tolle Features. Ein großer Vorteil dieser Extension ist, dass die Alben und Bilder mit einer AJAX-Oberfläche über das Frontend gepflegt werden können.

Somit kann ein Frontend-Login-Bereich eingerichtet werden, über den die Benutzer [...]]]></description>
			<content:encoded><![CDATA[<p>Die Typo3-Extension &#8220;<strong>jm_gallery</strong>&#8221; bietet eine umfangreiche Fotogalerie. Dazu gehört die Aufteilung in Kategorien, anlegen verschiedener Alben, eine Kommentarfunktion zu den Bildern und viele weitere tolle Features. Ein großer Vorteil dieser Extension ist, dass die Alben und Bilder mit einer AJAX-Oberfläche über das Frontend gepflegt werden können.</p>
<p><span id="more-180"></span></p>
<p>Somit kann ein Frontend-Login-Bereich eingerichtet werden, über den die Benutzer die Bilder komfortabel pflegen können und nicht den mühsamen (und bei dieser Extension etwas unübersichtlichen) Weg der Backend-Pflege gehen müssen. Die Benutzer können Kategorien anlegen, Bilder hinzufügen, Bilder löschen und auch ganze Kategorien wieder löschen. Und genau hier liegt ein kleines Problem: Löscht der Benutzer eine Kategorie, erscheint keine Sicherheitsabfrage und die Kategorie wird incl. aller Dateien sofort gelöscht. Dadurch kann durch einen einzigen unvorsichtigen Klick die vorherige mühsame Arbeit zunichte gemacht werden.</p>
<p>Mit folgender Anpassung am Template wird eine kurze und einfache JavaScript-Bestätigung vorgeschaltet, die den Benutzer noch einmal darauf hinweist, was geschieht und ob er das wirklich will.</p>
<p>Folgender Abschnitt im Template &#8230;</p>
<pre>href="javascript:GalleryAdmin.deleteAlbum(###CATEGORY_UID###,###ALBUM_UID###);"</pre>
<p>&#8230; muss durch diesen Code ersetzt werden:</p>
<pre>href="javascript:askToDelete(###CATEGORY_UID###,###ALBUM_UID###);"</pre>
<p>Und diese JavaScript-Funktion muss an geeigneter Position eingefügt werden:</p>
<pre>/**
 * Ask the user before the album is deleted.
 */
function askToDelete(catID, albumID) {

	var askText = 'Soll das Album wirklich endgültig vom Server gelöscht
	               werden?\n\nDieser Vorgang kann nicht rückgängig
	               gemacht werden.';

	if(confirm(askText)) {
		GalleryAdmin.deleteAlbum(catID, albumID);
	}
}</pre>
<p>Durch diese Änderung kann der Benutzer wie gewohnt die Bilder und Alben verwalten, wird aber vor dem Löschen eines Albums darauf hingewiesen, welche Folgen die Aktion haben wird und danach gefragt, ob er es wirklich tun will. Dieser eine Klick mehr stört wahrscheinlich niemanden wirklich, aber kann vor sehr viel Ärger, Problemen und Mehraufwand schützen.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.zeroseven.de/development/typo3/user-bestatigung-bevor-dateien-geloscht-werden/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
