_binary From 4d14e10a698834e052df0ca71e0d0d333815f786 Mon Sep 17 00:00:00 2001
From: Sandhya Vissapragada <sandyvissa@gmail.com>
Date: Fri, 18 May 2012 09:42:10 -0700
Subject: [PATCH] Updated autosuggest feature - arrowkeys,scroll,multiword
 a=Sandhya

---
 css/search.css         |   53 ++++++++++-------
 scripts/autosuggest.js |  155 +++++++++++++++++++++++++++++++++++++++---------
 views/search_view.php  |    4 +-
 3 files changed, 160 insertions(+), 52 deletions(-)

diff --git a/css/search.css b/css/search.css
index 2e61ce3..507ba54 100755
--- a/css/search.css
+++ b/css/search.css
@@ -590,7 +590,7 @@ body.mobile
     font-size:16pt;
 }
 
-.searchbox input, .autoresult, .dropdown
+.searchbox input, .autoresult
 {
     width: 6.5in;
     font-size:16pt;
@@ -604,6 +604,28 @@ body.mobile
     margin:0;
 }
 
+.dropdown 
+{   
+    width: 6.55in;
+    margin-left:0.023in;    
+    height: 1.5in;
+    border-color: #AAA;
+    border-width: 0.05in;
+    border-top-style:none;
+    border-right-style:solid;
+    border-bottom-style:solid;
+    border-left-style:solid;
+    border-bottom-right-radius: 0.05in;
+    border-bottom-left-radius: 0.05in;
+    border-top-left-radius: 0.05in;
+    overflow-y: auto;
+    overflow-x: hidden;
+    padding-bottom:0in;
+    margin-bottom:0in;
+    margin-right:0;
+    padding-top: 0.01in;    
+}
+
 .mobile .searchbox input
 {
     width:180px;
@@ -616,47 +638,36 @@ body.mobile
     font-size:12pt;
 }
 
-
 #aslist li
 {
     position:relative;
     top:-0.015in;
     background:#DDF;
-    width: 6.6in;
+    width: 6.5in;
     font-size:16pt;
     margin-right:0in;
     margin-left:0in;
     padding-top:0;
-    padding-right:0;
+    padding-right:0in;
     padding-left:0.1in;
     cursor:pointer;
     list-style:none;
-    border-color: #AAA;
-    border-width: 0.05in;
-    border-top-style:none;
-    border-right-style:solid;
-    border-bottom-style:none;
-    border-left-style:solid;
-}
-
-#aslist li:last-child
-{
-    border-bottom-style:solid;
-    border-bottom-right-radius: 0.05in;
-    border-bottom-left-radius: 0.05in;
-    padding-bottom:0.1in;
 }
 
 #aslist li span
 {
-    background:white;
     width:6.5in;
     padding:0;
     margin:0;
-    display:block
+    display:block;
+}
+
+#aslist li span.unselected
+{
+    background:white;
 }
 
-#aslist li:hover span
+#aslist li span.selected
 {
     background:#AAE;
     color:black;
diff --git a/scripts/autosuggest.js b/scripts/autosuggest.js
index e91548c..373a89c 100644
--- a/scripts/autosuggest.js
+++ b/scripts/autosuggest.js
@@ -32,52 +32,154 @@
 
 /**
  * Steps to follow every time a key is up from the user end
+ * Handles up/dowm arrow keys
+ *
+ * @param Event e current event 
+ * @return String text_field Current value from the search box
+ *
  */
-function askeyup(text_field) {
-    var input_term = text_field.value;
+function askeyup(e,text_field) {
+    var keynum;
+    var term_array;
+    var inputTerm = text_field.value;
     var results_dropdown = document.getElementById("aslist");
-    autosuggest(dictionary, input_term); 
-    results_dropdown.innerHTML = search_list; 
-    search_list = "";
+    var scrollpos = 0;
+    var astobj = document.getElementById("search-name"); 
+    concat_term = "";
+    if(window.event) { // IE8 and earlier
+        keynum = e.keyCode;
+    }
+    else if(e.which) { // IE9/Firefox/Chrome/Opera/Safari
+        keynum = e.which;
+    }
+    term_array = inputTerm.split(" ");
+    concat_array = inputTerm.split(" ",term_array.length-1);          
+    if (inputTerm != "") {
+        for(var i=0; i < concat_array.length ; i++) {
+            concat_term += concat_array[i] + " ";
+        }
+        concat_term = concat_term.trim();
+    }    
+    inputTerm = term_array[term_array.length-1];  
+
+    if (keynum != 40 && keynum != 38) {
+        search_list="";  
+        autosuggest(dictionary, inputTerm);
+        document.getElementById("asdropdown").style.visibility = "visible";
+        document.getElementById("asdropdown").scrollTop =  0;             
+        results_dropdown.innerHTML = search_list;
+        cursor_pos=-1; 
+        if (search_list != "") {
+            results_dropdown.style.visibility = "visible";
+        } 
+        else {  
+            results_dropdown.style.visibility = "hidden";        
+        }
+        items = results_dropdown.children.length;
+        if (items == 0) {
+            document.getElementById("asdropdown").className = "";
+        } else {
+            document.getElementById("asdropdown").className = "dropdown";
+            if (items < 6) {
+                document.getElementById("asdropdown").style.height = "" + items * 0.25 + "in";
+            } else {
+                document.getElementById("asdropdown").style.height = "1.5in";
+            } 
+        }
+    }
+    if (results_dropdown.style.visibility == "visible") {
+        if(keynum == 40) { 
+            if (cursor_pos == -1) { 
+                cursor_pos = 0;                
+                setDisplay(cursor_pos,"selected"); 
+            }
+            else {  
+                setDisplay(cursor_pos,"unselected");                                
+                cursor_pos++;
+                if (cursor_pos == items) {            
+                    cursor_pos=0;
+                }
+                setDisplay(cursor_pos,"selected");                                                       
+            }            
+            scrollpos = (cursor_pos > 2) ? (cursor_pos - 2) : 0;
+            document.getElementById("asdropdown").scrollTop = scrollpos * 26;
+        } else if(keynum == 38) {         
+            if (cursor_pos == -1)
+            {    
+                cursor_pos = items-1;
+                setDisplay(cursor_pos,"selected");                          
+            }
+            else {   
+                setDisplay(cursor_pos,"unselected");                    
+                cursor_pos--;                                      
+                if (cursor_pos == -1) {            
+                    cursor_pos=items-1;
+                }
+                setDisplay(cursor_pos,"selected");                                                         
+            }
+            scrollpos = (cursor_pos > 2) ? (cursor_pos - 2) : 0;
+            document.getElementById("asdropdown").scrollTop = scrollpos * 26;
+        }
+
+    }  
 }
 
 /**
- * To select a value from the dropdownlist and place in the search box 
+ * To select an autosuggest value while up/down arrow keys are being used
+ * and place in the search box
  */
-function aslitem_click(liObj)
-{
+function setDisplay(cursor_pos, class_name)  {
+    var astobj = document.getElementById("search-name");     
+    astobj.value = document.getElementById(cursor_pos).innerHTML;
+    document.getElementById(cursor_pos).className = class_name;
+}
+
+/**
+ * To select a value onclick from the dropdownlist and place in the search box 
+ */
+function aslitem_click(liObj) {
     var results_dropdown = document.getElementById("aslist");
-    var astobj = document.getElementById("search-name"); 
-    astobj.value = liObj.firstChild.innerHTML;
+    var astobj = document.getElementById("search-name");
+    astobj.value = liObj.innerHTML;
     results_dropdown.innerHTML = "";
+    document.getElementById("asdropdown").style.visibility = "hidden";        
 }
 
 /**
+ * To hanble the cursor hover
+ */
+function hover_display(liObj) {
+    if (cursor_pos > -1) { 
+        document.getElementById(cursor_pos).className = "unselected";
+    }
+    cursor_pos = liObj.id;                       
+    liObj.className = "selected";
+}
+    
+/**
  * Fetch words from the Trie and add to seachList with <li> </li> tags
  */
-function getValues(trie_array, parent_word, max_display)
-{
+function getValues(trie_array, parent_word, max_display) {
+    var list_string; 
     // Default to display top 6 words
     max_display = (typeof max_display == 'undefined') ?
         6 : max_display;
     // Default end_marker is ' '
-    if (trie_array != null && last_word == false ) {
+    if (trie_array != null) {
         for (key in trie_array) {
             if (key != end_marker ) {
                 getValues(trie_array[key], parent_word + key);
             } else {
-                search_list += "<li onclick='aslitem_click(this);'><span>"
-                    + decode(parent_word) + "</span></li>";
+                list_string = concat_term.trim() + " " + decode(parent_word);
+                list_string = list_string.trim();
+                search_list += "<li><span id=" + count + " class='unselected' onmouseover=hover_display(this) "; 
+                search_list += "onclick=aslitem_click(this)>" + list_string + "</span></li>";
                 count++;
-                if(count == max_display) {
-                    last_word = true;
-                }
             }
         }
     }
 }
 
-
 /**
  * Returns the sub trie_array under term in
  * trie_array. If term does not exist in the trie_array
@@ -86,8 +188,7 @@ function getValues(trie_array, parent_word, max_display)
  * @param String term  what to look up
  * @return Array trie_array sub trie_array under term
  */
-function exist(trie_array, term)
-{
+function exist(trie_array, term) {
     for(var i = 1; i< term.length; i++) {
         if(trie_array == null){
             return false;
@@ -117,11 +218,9 @@ function exist(trie_array, term)
  * @param String term - what to look up suggestions for
  * @sideeffect global Array search_list has list of first six entries
  */
-function autosuggest(trie_array, term)
-{
+function autosuggest(trie_array, term) {
     //default end_marker is space
-    end_marker = (typeof end_marker == 'undefined') ?
-        " " : end_marker;
+    end_marker = (typeof end_marker == 'undefined') ? " " : end_marker;
     last_word = false;
     count = 0;
     search_list = "";
@@ -166,8 +265,7 @@ function encode(str)
  * @param int i current offset into str
  * @return Array pair of Unicode character beginning at i and the next offset
  */
-function getUnicodeCharAndNextOffset(str, i) 
-{
+function getUnicodeCharAndNextOffset(str, i) {
     var code = str.charCodeAt(i);
     if (isNaN(code)) {
         return '';
@@ -199,8 +297,7 @@ function getUnicodeCharAndNextOffset(str, i)
  * Load the Trie(compressed with .gz extension) during the launch of website
  * Trie's are represented using nested arrays.
  */
-function loadTrie() 
-{
+function loadTrie() {
     var xmlhttp;
     if (window.XMLHttpRequest) {
         // code for IE7i+, Firefox, Chrome, Opera, Safari
diff --git a/views/search_view.php b/views/search_view.php
index c96f19d..6f031e8 100755
--- a/views/search_view.php
+++ b/views/search_view.php
@@ -103,7 +103,7 @@ class SearchView extends View implements CrawlConstants
             e($data['YIOOP_TOKEN']); ?>" />
         <input type="hidden" name="its" value="<?php e($data['its']); ?>" />
         <input type="text" <?php if(WORD_SUGGEST) { ?>
-            autocomplete="off"  onkeyup="askeyup(this)" 
+            autocomplete="off"  onkeyup="askeyup(event,this)" 
             <?php } ?>
             title="<?php e(tl('search_view_input_label')); ?>" 
             id="search-name" name="q" value="<?php if(isset($data['QUERY'])) {
@@ -116,7 +116,7 @@ class SearchView extends View implements CrawlConstants
         </p>
         </form>
             </div>
-        <div class="dropdown"> 
+        <div id="asdropdown"> 
             <ul id="aslist" class="autoresult">
             </ul>
         </div>
-- 
1.7.9.4

