added Thomas Niepraschk's tag autocomplete feature
authorBenjamin Mako Hill <mako@atdot.cc>
Mon, 7 Nov 2011 23:08:38 +0000 (18:08 -0500)
committerBenjamin Mako Hill <mako@atdot.cc>
Tue, 8 Nov 2011 00:52:23 +0000 (19:52 -0500)
The work in this patch is taken from the following GH repository:

  https://github.com/niepi/scuttle-autocomplete

The work is Copyright (c) Thomas Niepraschk 2011.

Niepraschk's work is not done as a branch to the scuttle git repository,
includes a series of unrelated changes, and involves a few mistakes. In
this branch, I've provided a clean-up of his work but very little of my
own.

I have made the following change over what Thomas did in his repository:

- Reverted the move of config.inc.php from config.inc.php.example
- Changed the script code to not include simple load JQuery from
  googleapis.com (introducing some privacy issues) but to load it from
  the copies that Thomas included in the repository instead.
- I have also removed from the history several extra files including the
  full dump of his database (!) which he them removed in a subsequent
  commit.

All credit goes to Thomas Niepraschk for his hard work to build the
functionality. I use it and love it!

jsScuttle.php
templates/editbookmark.tpl.php
templates/top.inc.php

index 93fa85bd7ab906982b7c13077237311e4cfa1050..60e403ac7db2d3af5e9571ecc31d81289d202a03 100644 (file)
@@ -3,6 +3,12 @@ header('Content-Type: text/javascript');
 require_once 'header.inc.php';
 require_once 'functions.inc.php';
 $player_root = $root .'includes/player/';
 require_once 'header.inc.php';
 require_once 'functions.inc.php';
 $player_root = $root .'includes/player/';
+
+$userservice     =& ServiceFactory::getServiceInstance('UserService');
+if ($userservice->isLoggedOn()) {
+    $currentUser = $userservice->getCurrentUser();
+    $currentUsername = $currentUser[$userservice->getFieldName('username')];
+}
 ?>
 
 var deleted = false;
 ?>
 
 var deleted = false;
@@ -49,8 +55,65 @@ function getTitle(input) {
   }
 }
 
   }
 }
 
+function autocomplete() {
+       $.ajax({
+               url: '<?php echo $root?>alltags/<?php echo $currentUsername?>',
+               success: function(data) {
+                       //console.log($(data));
+                       var availableTags = new Array();
+                       $(data).find('a').each(function() {
+                               availableTags.push($(this).html());
+                               //console.log($(this).html());
+                       });
+                       
+                       $( ".autocomplete" )
+                               // don't navigate away from the field on tab when selecting an item
+                               .bind( "keydown", function( event ) {
+                                       if ( event.keyCode === $.ui.keyCode.TAB &&
+                                                       $( this ).data( "autocomplete" ).menu.active ) {
+                                               event.preventDefault();
+                                       }
+                               })
+                               .autocomplete({
+                                       minLength: 0,
+                                       source: function( request, response ) {
+                                               // delegate back to autocomplete, but extract the last term
+                                               response( $.ui.autocomplete.filter(
+                                                       availableTags, extractLast( request.term ) ) );
+                                       },
+                                       focus: function() {
+                                               // prevent value inserted on focus
+                                               return false;
+                                       },
+                                       select: function( event, ui ) {
+                                               var terms = split( this.value );
+                                               // remove the current input
+                                               terms.pop();
+                                               // add the selected item
+                                               terms.push( ui.item.value );
+                                               // add placeholder to get the comma-and-space at the end
+                                               terms.push( "" );
+                                               this.value = terms.join( ", " );
+                                               return false;
+                                       }
+                               });
+               }
+       });
+       
+}
+
+function split( val ) {
+               return val.split( /,\s*/ );
+       }
+function extractLast( term ) {
+       return split( term ).pop();
+}
+
 /* Page load */
 $(function() {
 /* Page load */
 $(function() {
+       
+       autocomplete();
+       
   // Insert Flash player for MP3 links
   if ($("#bookmarks").length > 0) {
     $("a[href$=.mp3].taggedlink").each(function() {
   // Insert Flash player for MP3 links
   if ($("#bookmarks").length > 0) {
     $("a[href$=.mp3].taggedlink").each(function() {
index 16b56c7fd0ad47274ad852bcc850e50843ea47ec..e26c412d3777243638fdcf599c3275c79ba9f663 100644 (file)
@@ -36,7 +36,7 @@ switch ($row['bStatus']) {
 </tr>
 <tr>
     <th align="left"><?php echo T_('Tags'); ?></th>
 </tr>
 <tr>
     <th align="left"><?php echo T_('Tags'); ?></th>
-    <td><input type="text" id="tags" name="tags" size="75" value="<?php echo filter(implode(', ', $row['tags']), 'xml'); ?>" /></td>
+    <td><input class="autocomplete" type="text" id="tags" name="tags" size="75" value="<?php echo filter(implode(', ', $row['tags']), 'xml'); ?>" /></td>
     <td>&larr; <?php echo T_('Comma-separated'); ?></td>
 </tr>
 <tr>
     <td>&larr; <?php echo T_('Comma-separated'); ?></td>
 </tr>
 <tr>
index 85c965d6d37f5baf4e8499e71c49cd9ec2ac897f..68786224f881dcc5fcd2dabfc548ab1093187b9a 100644 (file)
@@ -5,7 +5,9 @@
     <title><?php echo filter($GLOBALS['sitename'] . (isset($pagetitle) ? ': ' . $pagetitle : '')); ?></title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <link rel="icon" type="image/png" href="<?php echo $GLOBALS['root']; ?>icon.png" />
     <title><?php echo filter($GLOBALS['sitename'] . (isset($pagetitle) ? ': ' . $pagetitle : '')); ?></title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <link rel="icon" type="image/png" href="<?php echo $GLOBALS['root']; ?>icon.png" />
+    <link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['root']; ?>includes/smoothness/jquery-ui-1.8.9.custom.css" />
     <link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['root']; ?>scuttle.css" />
     <link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['root']; ?>scuttle.css" />
+
     <?php
     $size = count($rsschannels);
     for ($i = 0; $i < $size; $i++) {
     <?php
     $size = count($rsschannels);
     for ($i = 0; $i < $size; $i++) {
     }
     ?>
     <?php if ($loadjs): ?>
     }
     ?>
     <?php if ($loadjs): ?>
-      <script type="text/javascript" src="<?php echo $GLOBALS['root']; ?>includes/jquery-1.4.4.min.js"></script>
-      <script type="text/javascript" src="<?php echo $GLOBALS['root']; ?>jsScuttle.php"></script>
+        <script type="text/javascript" src="<?php echo $GLOBALS['root']; ?>includes/jquery-1.5.min.js"></script>
+        <script type="text/javascript" src="<?php echo $GLOBALS['root']; ?>includes/jquery-ui-1.8.9.min.js"></script>
+       <script type="text/javascript" src="<?php echo $GLOBALS['root']; ?>jsScuttle.php"></script>
+
     <?php endif; ?>
 </head>
 <body>
     <?php endif; ?>
 </head>
 <body>

Benjamin Mako Hill || Want to submit a patch?