5a768ac3e29375e54bb9b05121e21f1d26ee87fe
chmalee
  Fri Sep 2 13:06:54 2022 -0700
Add a loading icon on hgGateway when a species is searched or a position is searched, refs #29765

diff --git src/hg/js/autocompleteCat.js src/hg/js/autocompleteCat.js
index f47c090..e1b04c3 100644
--- src/hg/js/autocompleteCat.js
+++ src/hg/js/autocompleteCat.js
@@ -30,56 +30,76 @@
                               }
                               that._renderItem( ul, item );
                           });
                },
                _renderItem: function(ul, item) {
                  // In order to use HTML markup in the autocomplete, one has to overwrite
                  // autocomplete's _renderItem method using .html instead of .text.
                  // http://forum.jquery.com/topic/using-html-in-autocomplete
                    return $("<li></li>")
                        .data("item.autocomplete", item)
                        .append($("<a></a>").html(item.label))
                        .appendTo(ul);
                }
              });
 
+    function toggleSpinner(add, options) {
+        if (options.baseUrl.startsWith("hgGateway")) {
+            // change the species select loading image
+            if (add)
+                $("#speciesSearch").after("<i id='speciesSpinner' class='fa fa-spin fa-spinner'></i>");
+            else
+                $("#speciesSpinner").remove();
+        } else if (options.baseUrl.startsWith("hgSuggest")) {
+            // change the position input loading spinner
+            if (add)
+                $("#positionInput").after("<i id='suggestSpinner' class='fa fa-spin fa-spinner'></i>");
+            else
+                $("#suggestSpinner").remove();
+        }
+    }
+
     function init($input, options) {
         // Set up an autocomplete and watermark for $input, with a callback options.onSelect
         // for when the user chooses a result.
         // If options.baseUrl is null, the autocomplete will not do anything, but we (re)initialize
         // it anyway in case the same input had a previous db's autocomplete in effect.
         // options.onServerReply (if given) is a function (Array, term) -> Array that
         // post-processes the list of items returned by the server before the list is
         // passed back to autocomplete for rendering.
         // The following two options apply only when using our locally modified jquery-ui:
         // If options.enterSelectsIdentical is true, then if the user hits Enter in the text input
         // and their term has an exact match in the autocomplete results, that result is selected.
         // options.onEnterTerm (if provided) is a callback function (jqEvent, jqUi) invoked
         // when the user hits Enter, after handling enterSelectsIdentical.
 
         // The function closure allows us to keep a private cache of past searches.
         var cache = {};
 
         var doSearch = function(term, acCallback) {
             // Look up term in searchObj and by sending an ajax request
             var timestamp = new Date().getTime();
             var url = options.baseUrl + encodeURIComponent(term) + '&_=' + timestamp;
+            // put up a loading icon so users know something is happening
+            toggleSpinner(true, options);
             $.getJSON(url)
                .done(function(results) {
                 if (_.isFunction(options.onServerReply)) {
                     results = options.onServerReply(results, term);
                 }
+                // remove the loading icon
+                toggleSpinner(false, options);
                 cache[term] = results;
                 acCallback(results);
             });
             // ignore errors to avoid spamming people on flaky network connections
             // with tons of error messages (#8816).
         };
 
         var autoCompleteSource = function(request, acCallback) {
             // This is a callback for jqueryui.autocomplete: when the user types
             // a character, this is called with the input value as request.term and an acCallback
             // for this to return the result to autocomplete.
             // See http://api.jqueryui.com/autocomplete/#option-source
             var results = cache[request.term];
             if (results) {
                 acCallback(results);