Multiple Tag Typeahead

Autocomplete or Typeahead is one of the most common Ajax Patterns. For my example I am using the script aculo us libary respectively the ajax-autocomplete control. The goal of this small tutorial is to create an type ahead mechnism for multiple tags in one input field. The problem with the basic feature of the autocomplet controller of script aculo us is, that it only handles the value of an element as input string (not only a part of it as we need it for this solution). But we want the user to be able to enter several tags and use the autocomplete feature ONLY for the last entered tag. Here is a screen of what the final solution will look like:

tag_typeahead.JPG

First of all the we create an input field and the hidden div where the elements will apear (also see the above linked dokumentation on how to use the script aculo us libary):

<input autocomplete="off" id="tags" name="tags" type="text" size="70" />
<div id="autocomplete_choices" class="autocomplete"></div>

Then we create an instance of the autocompleter object:

<script type="text/javascript">
new Ajax.Autocompleter("tags", "autocomplete_choices","tags_auto.php", {
updateElement: function(selected)	{
		
  Element.cleanWhitespace(selected);
  dn = selected.childNodes;
  
  //the selected tag is the returned object of the updateElement function
  newtag= dn[0].nodeValue;

  //get the previous inserted tags an process them
  oldtags=document.getElementById("tags").value;
		
  var tags=oldtags.split(" ");
  var out="";
  
  //create output string - the last input 
  //the first chars of the current tag will be left out
  if (tags.length>1)	{
	for (var i = 0; i < tags.length-1; i++) {
		out=out+tags[i]+" ";
	}
	document.getElementById("tags").value=out+newtag+" ";
  }	else	{
	document.getElementById("tags").value=newtag+" ";
  }
} 
});
</script>

We are using here our own updateElement function that will process the tags again in the correct order.
On the server side we use a php script which performs a db lookup or whatever to gather the element fitting to the recieved input value and returns it as an unsorted list. Remeber: we recieve all tags in with the http post, so we have to extract only the last one and work with this value.

<?
if (isset($_POST['tags']) && !empty($_POST['tags']) && $_POST['tags']!=" "){

//if more than one tag are inside the value
if (strstr($_POST['tags']," "))	{
	
        //extract the tags and only work with the last element
	$tag=explode(" ",$_POST['tags']);
	$tags=end($tag);
		
}	else	{
	$tags=$_POST['tags'];
}
	
if ($tags)	{
	
        //look in db for matching values
	include('mysql_connect.php');
	$SqlSelect = "SELECT tag from tags WHERE tag LIKE '".$tags."%'";
	
	$result = mysql_query($SqlSelect);
	if (!$result)    {        die('Invalid query: ' . mysql_error());    }
	
	//return values as an unsorted list
	echo "<ul>";
	while ($row = mysql_fetch_assoc($result))    {
		 
	     echo "<li>".$row['tag']."</li>";
		 
	}
	echo "</ul>";
		 
	mysql_free_result($result);
	mysql_close($dbh);
	 
	}
}
?>
It's only fair to share...Share on Google+Share on LinkedInTweet about this on TwitterShare on FacebookEmail this to someonePrint this page

3 Gedanken zu “Multiple Tag Typeahead

  1. […] ich habe sowas mit scriptaculous realisiert und kurz beschrieben. vielleicht hilft es dir ja weiter: Multiple Tag Typeahead – erich’s blog […]

  2. Been looking for this for SOOO long, very nice, trying it now

  3. Thank you for that post!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.