Tag: prototype

Ein Select Auswahlfeld mit Prototype elegant filtern – ohne Ajax.Request

Geschrieben von – 23. Dezember 2011

Wer kennt das Problem als Programmierer nicht? Die User meckern, bei ewig vielen Optionen in einem Auswahlfeld – und das zurecht! Nun können die Optionen des Auswahlfelds mittels Ajax.Request und einem Suchfeld gefiltert werden, aber ein Request ist eben ein Request und ich habe mir deswegen etwas überlegt, was ohne Request auskommt. Dabei herausgekommen ist eine kleine JavaScript-Funktion, die ich gerne zur Verfügung stelle.

Aber zuerst eine kleines Beispiel, wie der HTML-Code dazu aussehen könnte:

<select name="auswahl" id="auswahl">
	<option value="">--Bitte wählen --</option>
	<option value="1">Eins</option>
	<option value="2">Eins</option>
	<option value="3">Eins</option>
	<option value="4">Eins</option>
	<option value="5">Eins</option>
	<option value="1000000">Einemiooooon!!!!</option>
</select>

Filtern:
<input type="text" size="12" value="" onkeyup="filterSelectField( 'auswahl', this.value )"/>

Die dazugehörige JavaScript-Funktion sieht dann so aus:

function filterSelectField( fieldid, s ) {
	var rex = new RegExp( '^' + s.replace( '\.', '\\.' ), "i" );
	$$('select#' + fieldid + ' option').each( function (ele) {
		if( ele.value != '' )
		{
			if( ele.innerHTML.search( rex ) == -1  )
				ele.hide();
			else
				ele.show();
		}
	} );
}

Die Funktionsweise ist schnell erklärt: Mittels einer RegEx wird die Bennenung des Werts der “option” durchsucht und bei einem Treffer angezeigt und bei keinem Treffer ausgeblendet. Einfacher und schneller geht’s nun wirklich nicht. :-)

Viel Spaß damit.

(298x gelesen)

Tab-Menüs mit Prototype generalisieren

Geschrieben von – 27. November 2009

Wer kennt es nicht: Mehrere Datentabellen oder -abschnitte auf einer Seite und der Benutzer verliert schnell den Überblick. Die Lösung: Ein wenig JavaScript, mit ein wenig CSS und ein paar DIVs garniert, das ganze kräftig durchkneten und fertig ist der Tabbed-Content für jeden Einsatzzweck. Mehr

(528x gelesen)

Parallax Scrolling Effekt mit Prototype/Scriptaculous JavaScript

Geschrieben von – 11. November 2009

Wer sich an Spiele wie “Shadow of the Beast” erinnert, der muss sich auch zwangsweise an diesen netten Pseudo-3D Effekt erinnern, mit dem diese Spiele ihren coolen Look erhielten. Parallax Scrolling nennt man diese Technik übrigens, bei der verschiedene Layer aus Grafiken übereinander gelegt und unterschiedlich schnell horizontal oder auch vertikal bewegt werden.

Weil mir gestern Abend langweilig war, habe ich mich damit beschäftigt den Parallax Effekt versuchsweise in JavaScript umzusetzen. Als Bibliotheken verwende ich dabei PrototypeJS und Scriptaculous. Nachdem ich mit einem Grafikprogramm meine 3 Layer gezeichnet und PNGs mit Transparenz exportiert hatte, ging es an die Umsetzung. Schnell wurde mir klar, wie simpel es im Grunde ist mit ein wenig CSS und JavaScript diesen Effekt zu erzeugen. Mehr

(562x gelesen)

AJAX loading Grafik neben dem Mauszeiger anzeigen

Geschrieben von – 27. Oktober 2009

Um dem Benutzer zu visualisieren, dass gerade ein asynchroner HTTP Request ausgeführt wird, hat die AJAX Welt das ajax-loading.gif erfunden. Diese kleine animierte Grafik gibt es in vielen Varianten und bittet den Benutzer optisch darum zu warten, bis der Inhalt geladen wurde. Sinnvolle Sache, sonst klickt er sich nämlich doof und dusselig, falls es doch mal ein wenig länger dauert. Kurzerhand habe ich das auch mal hier in Form des springenden Punktes im Blog eingebaut.

Zuerst habe ich meinen Body-Tag mit einer ID versehen, damit ich mit Prototype einfach auf das Body-Element zugreifen kann.

	<body id="body">

Dann habe ich ein kleines DIV samt Bild mit den CSS Eigenschaften “position:absolute” und “display:none” hinzugefügt. Das DIV kann mit Prototype so nämlich frei positioniert werden, wird aber vorerst nicht angezeigt.

	<!-- Create hidden bouncing ball layer (ajax-loading.gif or similar) -->
	<div id="bouncer" style="position:absolute;display:none"><img src="/images/ball.gif" alt=""/></div>

Als nächstes wird ein Event-Handler an den Event “onmousemove” des Body-Tags geklebt. Der Handler ermittelt die aktuellen Maus-Koordinaten und platziert das (noch immer versteckte) DIV versetzt neben der Maus.

	// Move the bouncing ball next to mouse cursor position
	$('body').onmousemove = function( e ) {
		mouseX = Event.pointerX( e );
		mouseY = Event.pointerY( e );
		$('bouncer').setStyle( { left: (mouseX+15) + 'px', top: (mouseY+15) + 'px' } );
     		return true;
	}

Danach habe ich meine AJAX-Load Funktion noch so abgeändert, dass mit Beginn des Requests das DIV mit der Grafik angezeigt wird und bei Erfolg oder Fehler wieder versteckt wird. Anbei eine kleine Beispiel-Funktion.

	// Example function to use the bouncer
	function ajax_load( uri )
	{
		$('bouncer').show();
		new Ajax.Request( uri, {
					onSuccess: function( r ) {
						$('bouncer').hide();
					},
					onFailure: function( r ) {
						$('bouncer').hide();
					}
		});
	}

Wirklich einfach, aber ein toller und ausnahmsweise auch mal sinnvoller Effekt. ;-)

(270x gelesen)

WordPress dazu bringen Seiten per AJAX zu laden

Geschrieben von – 23. Oktober 2009

Wer im Browser sein Javascript aktiviert hat, der wird sicherlich sehen, dass beim Klicken eines Links der Content hier dynamisch geladen wird. Um das in meinem WordPress Theme zu realisieren, habe ich zwei einfache JavaScript Funktionen geschrieben. Als JS Bibliotheken nutze ich dafür Prototype und Scriptaculous, es ginge aber auch sicherlich mit JQuery.

Vorteil der Lösung: Wenn ein Fehler auftritt, oder im Browser kein JavaScript aktiviert ist, dann funktioniert die Seite ganz normal, was nebenbei auch sehr Suchmaschinen freundlich ist.

Die erste Funktion “fixLinks” die ich nutze, hat den Zweck an alle Links, die nicht bestimmten Kriterien entsprechen – z.B. Links auf Bilder, externe Links oder aber Links in WordPress Backend – eine “onclick” Aktion anzufügen. Die neue “onclick” Aktion des Links ruft dann die zweite Funktion “get_page” auf, welche die Seite läd und mit einem netten Effekt dann anzeigt.

function fixLinks()
{
	var myLinks = document.links;
	var myBrowserType = (window.attachEvent ? 1 : (window.addEventListener ? 2 : 0));
	var myDomain = 'thegeek.de';
	for( var i = 0; i < myLinks.length; i++ )
	{
		// Get the href
		myHref = myLinks[i].href.toString();
		// Get the onclick action
		myOnClick = myLinks[i].onclick ? myLinks[i].onclick : '';
		// Only attack onclick action, if not jscript links, images, wp-admin features and internal link
		if( 	myOnClick == ''
			&& myHref.indexOf( "#" ) != (myHref.length - 1)
			&& myHref.indexOf( "javascript:" ) == -1
			&& myHref.indexOf( "wp-admin" ) == -1
			&& myHref.indexOf( "#respond" ) == -1
			&& myHref.indexOf( "/trackback" ) == -1
			&& myHref.indexOf( "/feed" ) == -1
			&& myHref.indexOf( "/wp-login" ) == -1
			&& myHref.indexOf( ".jpg" ) == -1
			&& myHref.indexOf( ".gif" ) == -1
			&& myHref.indexOf( ".png" ) == -1
			&& myHref.indexOf( myDomain) != -1
		)
		{
			switch( myBrowserType )
			{
				case 1:
					Event.observe( myLinks[i], 'click', function( e ) { if( !get_page( this.href ) ) e.stop(); } );
					break;
				case 2:
					myLinks[i].setAttribute( "onclick", "return get_page( this.href );" );
					break;
				default:
					// Do nothing
			}
		}
	}
}
// body onload="fixLinks()" und die Sache läuft. :-)

Die zweite Funktion bewegt zuerst den Inhalt an die beim Init ermittelt Position außerhalb des Bildschirms und läd dann per asynchronem HTTP Request die neue Seite. Der Inhalt der Seite ist im Theme mit einem HTML Kommentar gekennzeichnet und wird mittels Regular Expression ermittelt, dann in den Layer eingefügt, um die Seite danach wieder an die ursprüngliche Position zu bewegen. Keine Ahnung, ob's im IE klappt, ist mir allerdings auch ziemlich egal. :-)

Sollte etwas schief gehen, dann gibt die Funktion "true" zurück, womit der Klick auf den Link ganz normal ausgewertet wird. Hat alles geklappt, liefert die Funktion "false" zurück und der Browser folgt dem angeklicktem Link dann nicht. So ist auf jeden Fall gewährleistet, dass die neue Seite angezeigt wird - auf die synchrone oder asynchrone Art.

	var	c_w = $('content').getWidth();
	var	c_x = $('content').viewportOffset()[0];
	var	c_leave = (c_x + c_w) * -1;
	var	c_come = c_leave * -1;
	var	c_search = /()((?:.|[\r\n])*?)()/mgi;
	var	get_page_return_code = false;
	var	effect_running = false;
	function get_page( uri )
	{
		get_page_return_code = false;
		if( effect_running == false )
		{
			effect_running = true;
			new Effect.Move( 'content', { x: c_leave, y: 0, mode: 'relative', duration:0.5,
				afterFinish:function() {
					new Ajax.Request(	uri, {
									method:'get',
									onSuccess: function( r ) {
											$('content').update( '' );
											SearchResult = c_search.exec( r.responseText );
											while( SearchResult != null )
											{
												if( SearchResult[ 2 ] )
													$('content').update( SearchResult[ 2 ] );
												SearchResult = c_search.exec( r.responseText );
											}
											new Effect.Move( 'content', { x: c_come, y: 0, mode: 'relative', duration:0.5, afterFinish:function () {effect_running = false;} } );
											fixLinks();
									},
									onFailure: function( r ) {
										get_page_return_code = true;
										effect_running = false;
									}
					});
				}
			});
		}
		return get_page_return_code;
	}

Klar handelt es sich hier um ziemliches sinnfreies Eyecandy. Ich mag Eyecandy.

(612x gelesen)