Webprogrammør

Simon Jensen

Bloggen med evigt skiftende tema!


 4

Live Search med Prototype JS og PHP

9. Marts 2008, Kl. 13:03:41 af Simon Jensen

Update Update 28/04-08: Live-search understøtter nu ÆØÅ - download ny version i slutningen af denne post!

I forbindelse med det sidste nye redesign, har jeg oprettet en "Live search". Nåhhh ja, den er måske ikke så live som en definition vil have det - men det er da en fed feature - og funktionaliteten bag den, vil jeg da gerne dele med jer.

Live SearchDenne post består således af en gennemgang, af de vigtigste punkter i implementeringen, det være sig lidt XHTML, CSS, Javascript samt PHP.

I slutningen af posten, kan du desuden downloade en lille demo-version af funktionen.

For at benytte koden i denne post kræves det, at du har downloaded og inkluderet Javascript frameworket Prototype JS, samt effektbiblioteket script.aculo.us. Disse skal inkluderes i sidens <head>-sektion, som med et hvert andet Javascript.

XHTML

Jeg har gjort det til god skik, at oprette en "container"-div. Dette div er ikke nødvendig, men her er det taget med for at få bare en smule design med.

Inde i denne container findes et billede, som er stylet til at være skjuldt. Dette er hvad jeg bruger som loading animation - altså en animation der skal vise, at et script arbejder. Input feltet skulle gerne tale for sig selv. Straks herunder er der, i endnu et div, oprettet en ul/li-liste - det er denne vi vil fremvise resultater i. Resultaterne skal ligeledes fremkommet/tilføjes som li-elementer til listen.

<div id="container">
    <img src="loading.gif" id="lsloading" align="right" alt="" style="display:none;" />
    <input type="text" value="Type and you´ll find..." id="lsquery" />
    <br />
    <div id="lsresults" style="display:none;">
        <ul id="lsResList">
            <li><i>Type and you´ll find...</i></li>
        </ul>
    </div>
</div>

CSS

CSS delen af dette script, taler også lidt for sig selv. Det er muligt, at designer kan laves en hel del nemmere (læs: med mind css), men her er indsat hvad du finder i demoen.

Det vigtigste her, vil nok være at påpege, at resultatlisten er sat til absolut positionering. Dvs. vi kan vise den ovenpå andre elementer, hvorfor den ikke skal til at "skubbe" rundt på designet. Du har måske bemærket at resultatlisten er en smule gennemsigtigt - Dette ER en CSS feature, men den bliver udført gennem Javascript-delen.

body {
    font-family: "Trebuchet MS";
    font-size: 1em;
    background: #333;
}

#container {
    background: #fff;
    width: 400px;
    padding: 20px;
    margin: 0 auto;
}

#container #lsloading {
    position: relative;
    top: 5px;
}

#container input {
    font-family: "Trebuchet MS";
    font-size: 1em;
    width: 350px;
    margin-left: 20px;
}

#container #lsresults {
    position: absolute;
    background: #fff;
    color: #333;
    width: 354px;
    margin-left: 20px;
}

#container #lsresults ul {
    list-style: none;
    margin: 0px;
    padding: 0px;
}

#container #lsresults ul li {
    list-style: none;
    margin: 10px;
    padding: 0px;
}

Javascript

Javascriptet er den største del af denne "applikation". JS-delen består af et Live Search objekt (ls) med metoderne init(), search(), showResults() og hideResults(). Derudover bliver der, når en side er loaded,  initialiseret nogle observer eventhandlers på søgefelter.

Humlen ligger i init() og search() metoderne. init() bliver kaldt hver gang der tastes i søgefeltet, og denne kalder search() som udføre et AJAX-kald til serveren, som levere selve søgningen. For ikke at spamme serveren er der indbygget en timer i init() metoden som gør, at search() metoden kun bliver kaldt hvis der ikke er tastet noget i søgefeltet i 0.5 sekunder.

/**
 * Live search
 */
var ls = {
	queryField: "lsquery", //id name of queru input-field
	results: "lsresults", //id name of result-list
	loading: "lsloading", //id name for loading animation
	timer: null,
	
	/**
	 * Initialize a search:
	 * reset timer, and performe search
	 * if nothing has been typed in 0.5 sec.
	 */
	init: function(event) {
		var query = Event.element(event).value;
		ls.timer = clearTimeout(ls.timer);
		if(query != "" || query != "Type and you´ll find...") {
			ls.timer = setTimeout("ls.search('" query "');", 500);
		}
	},
	
	//start a search using AJAX
	search: function(query) {
		if(query != "") {
			$(ls.loading).show();
			var done = function(t) {
				$(ls.loading).hide();
			}
			var url = 'php-backend.php';
			var pars = 'action=search&query='   query;
			new Ajax.Updater('lsResList', url,
			{
				method: 'post',
				parameters: pars,
				onSuccess:done,
				onFailure:done,
				inserting:Insertion.Before
			});
		}
	},
	
	//show the result list
	showResults: function() {
		if($(ls.results).getStyle('opacity') != '0.9')
			new Effect.Appear(ls.results, {duration:0.2, from:0.0, to:0.9});
	},
	
	//hide the result list
	hideResults: function() {
		new Effect.Opacity(ls.results, {duration:0.2, from:0.9, to:0.0});
	}
}

/**
 * Initialize key-observers for search input field.
 */
Event.observe(window, 'load', function() {
	$(ls.queryField).observe('keyup', ls.init);
	$(ls.queryField).observe('keydown', ls.init);
	
	//remove input field value when first focused
  	$(ls.queryField).onfocus = function() {
  		if($(ls.queryField).value == "Type and you´ll find...")
			$(ls.queryField).value = "";
		ls.showResults();
	}
	
	//reset input field when not focused and value is ""
  	$(ls.queryField).onblur = function() {
  		if($(ls.queryField).value == "")
  			$(ls.queryField).value = "Type and you´ll find...";
  		ls.hideResults();
  	}
});

PHP

PHP delen, er hvad jeg ovenfor har kaldt "serveren". Hvordan du vil udføre selve søgningen er mere eller mindre op til dig selv. Vælger du at benytte dette script, skal resultaterne dog returneres som én streng. Hvert resultat skal, for at designet holder stik, leveres som et <li>-element.

Bare for at give en ide, leveres scriptet med følgende PHP backend.

<?php
/************************************************************************
 * Here you would probably perform som DB-search.
 * In this example, you will only find a hit, when typing a string that -
 * is in the array $results.
 ************************************************************************/
if($_POST["action"] == "search") :
	$query = utf8_decode(urldecode($_POST["query"]));
	$results = array("","webprogrammering","blog","ajax","javascript","php","css");
	$key = array_search($query, $results);
	if($key) :
		echo "<li><a href=\"#\">\"".utf8_encode($results[$key])."\" found with key: ".$key."</a></li>";	
	else :
		echo "<li><i>Intet resultat</i></li>";
	endif;
endif;
?>

Som beskrevet i kommentaren, vil man selvfølgelig lave en reel database søgning eller lignende, hvilket lige nøjagtig er hvad jeg gør her på sitet.

Sååå - uden yderligere forklaringer skal du være velkommen til at downloade, modificere osv. følgende version af Live Search. Skulle der opstå problemer, eller mangler du yderligere forklaring, skal du endelig kommentere nedenfor.

Download

Live Search med Prototype JS og PHP (.zip)

Live Search med Prototype JS og PHP (Æ,Ø,Å understøttet) (.zip)


Hej. Nice artikel, jeg har leget lidt med den, så den søger i en database. Men alle resultaterne indeholdene æ,ø eller å bliver returneret som spørgsmålstegn. Og hvis man prøver at søge på noget med æ, ø eller å står gif filen bare og snurrer rundt for evigt. Jeg har prøvet at bruge utf8_decode($_POST["query"])); uden held. Der er naturligvis <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> i <head>. Jeg kan se at din egen "live-søger" heller ikke kan søge på æ,ø eller å.. what to do? :)

 

Få dit eget gravatar hos www.gravatar.com Aske

Hej Aske,

Jeps, det er ikke så fedt ... og jeg er detsvære også godt klar over det - jeg har bare ikke fået taget mig sammen til at få set på det.

Jeg vil poste her, lige så snart jeg finder en løsning - og du skal selvfølgelig være velkommen til at gøre det samme :) 


Du har ikke fundet en løsning? Jeg har selv ikke.

Få dit eget gravatar hos www.gravatar.com Aske

Hej igen Aske - Godt du kan holde gang i mig! Jeg var faktisk kommet væk fra det igen, men så kom du lige igen.

Jeg har set lidt mere på problemet, og nu lader det til at lykkedes! Jeg har sørget for ikke at pille ved "prototype.js", men der er ændret i selve "javascript.js" og "php-backend.php".

Ændringer i javascript.js (linie 32):

var pars = 'action=search&query='   query;

Ændringer i php-backend.php (linierne 8 og 13) :

$query = utf8_decode(urldecode($_POST["query"]));
...
utf8_encode($results[$key])

Download den nye version - og kom endelig igen med feedback.


Skriv en kommentar






AddThis Social Bookmark Button


aalborg add on ajax akismet algoritme analyse apache arbejde automatix backup bad gastein beryl billeder blog bot brows browser business buzz cache chat cloaking cms color schemer colorpix compiz fusion crazy eggs css css zengarden design desktop applet deviantart editor error facebook falken productions farver fckeditor feed feedburner ferie firebug firefox flash flickr fokus foto gadget galleri gettext gnome gnu goat google google maps gps gracefull degredation grafik gravatar hijax hotel htaccess html ie IM install instereo intaller internet explorer internet explorer 6.0 investering ipod it itunes java javascript karneval kunst linux live search livecd meta microsoft mobil mod_rewrite mootools mozbackup mozilla msn musik mysql news omgivelser one.com ooxml opera os php pidgin ping pipes png podcast printer programmering projekt prototype qfilm reklame reklamebureau rss screenshot script script.aculo.us seo skole songbird spam sponser standard standarder statistik strand svn test thunderbird tillykke tivoli top 10 twitter ubuntu udvikling validering video vinter vista w3c wallpaper web 2.0 web design web programmering webcrawler webserver windows wordpress xhtml xml xmlrpc xp yahoo youtube