8928abf68fefbf2d30087af20d96dc29a4ff9620
larrym
  Fri Jun 22 14:50:06 2012 -0700
refactor suggestBox code into autocomplete.js so it can be re-used in hgGateway
diff --git src/hg/js/autocomplete.js src/hg/js/autocomplete.js
index a1f99f1..fafe9d3 100644
--- src/hg/js/autocomplete.js
+++ src/hg/js/autocomplete.js
@@ -1,35 +1,35 @@
 // support stuff for auto-complete using jquery.autocomplete.js
 //
 // requires ajax.js
 // requires utils.js
 
 var suggestCache;
 
-function ajaxGet(getDb, cache)
+function ajaxGet(db, cache)
 {
 // Returns jquery.autocomplete.js ajax_get function object
-// getDb should be a function which returns the relevant assembly (e.g. "hg18")
+// db is the relevant assembly (e.g. "hg18")
 // cache is an optional object used as a hash to cache responses from the server.
     suggestCache = cache;
     return function (request, callback) {
         var key = request.term;
         if(suggestCache == null || suggestCache[key] == null)
         {
             $.ajax({
                        url: "../cgi-bin/hgSuggest",
-                       data: "db=" + getDb() + "&prefix=" + key,
+                       data: "db=" + db + "&prefix=" + key,
                        // dataType: "json",  // XXXX this doesn't work under IE, so we retrieve as text and do an eval to force to an object.
                        trueSuccess: handleSuggest,
                        success: catchErrorOrDispatch,
                        error: function (request, status, errorThrown) {
                            if (typeof console != "undefined") {
                                console.dir(request);
                                console.log(status);
                            }
                            var msg = "ajax call failed";
                            if(status != "error")
                                msg = msg + "; error: " + status;
                            warn(msg + "; statusText: " + request.statusText + "; responseText: " + request.responseText);
                        },
                        key: key,
                        cont: callback
@@ -65,15 +65,76 @@
     }
     // synchronously get match from the server
     var str = $.ajax({
                      url: "../cgi-bin/hgSuggest",
                      data: "exact=1&db=" + db + "&prefix=" + gene,
                      async: false
                  }).responseText;
     if(str) {
         var obj = eval(str);
         if(obj.length == 1) {
             return obj[0].id;
         }
     }
     return null;
 }
+
+/* suggest (aka gene search)
+   Requires three elements on page: positionDisplay (static display), positionInput (input textbox) and position (hidden).
+*/
+
+var suggestBox = {
+    init: function (db, assemblySupportsGeneSuggest, selectCallback, clickCallback)
+    {
+    // selectCallback: called when the user selects a new genomic position from the list
+    // clickCallback: called when the user clicks on positionDisplay
+        var lastEntered = null;    // this is the last value entered by the user via a suggestion (used to distinguish manual entry in the same field)
+        var str;
+        if(assemblySupportsGeneSuggest) {
+            str = "enter new position, gene symbol or annotation search terms";
+        } else {
+            str = "enter new position or annotation search terms";
+        }
+        $('#positionInput').Watermark(str, '#686868');
+        if(assemblySupportsGeneSuggest) {
+            $('#positionInput').autocomplete({
+                delay: 500,
+                minLength: 2,
+                source: ajaxGet(db, new Object),
+                open: function(event, ui) {
+                    var pos = $(this).offset().top + $(this).height();
+                    if (!isNaN(pos)) {
+                        var maxHeight = $(window).height() - pos - 30;  // take off a little more because IE needs it
+                        var auto = $('.ui-autocomplete');
+                        var curHeight = $(auto).children().length * 21;
+                        if (curHeight > maxHeight)
+                            $(auto).css({maxHeight: maxHeight+'px', overflow:'scroll'});
+                        else
+                            $(auto).css({maxHeight: 'none', overflow:'hidden'});
+                    }
+                },
+                select: function (event, ui) {
+                        selectCallback(ui.item.id);
+                        lastEntered = ui.item.value;
+                        // jQuery('body').css('cursor', 'wait');
+                        // document.TrackHeaderForm.submit();
+                    }
+            });
+        }
+        // I want to set focus to the suggest element, but unforunately that prevents PgUp/PgDn from
+        // working, which is a major annoyance.
+        // $('#positionInput').focus();
+
+        $("#positionInput").change(function(event) {
+                                       if(!lastEntered || lastEntered != $('#positionInput').val()) {
+                                           // This handles case where user typed or edited something rather than choosing from a suggest list;
+                                           // in this case, we only change the position hidden; we do NOT update the displayed coordinates.
+                                           $('#position').val($('#positionInput').val());
+                                       }
+                                   });
+        $("#positionDisplay").click(function(event) {
+                                        // this let's the user click on the genomic position (e.g. if they want to edit it)
+                                        clickCallback($(this).text());
+                                        $('#positionInput').val($(this).text());
+                                    });
+    }
+}