14dbfe57d9b670fa554c64cd4604e37fdefe037d chmalee Fri Jan 5 15:33:17 2024 -0800 Working version of saving last five user entered terms in the search bar, refs #29611 diff --git src/hg/js/autocompleteCat.js src/hg/js/autocompleteCat.js index e1b04c3..5c993fb 100644 --- src/hg/js/autocompleteCat.js +++ src/hg/js/autocompleteCat.js @@ -1,55 +1,61 @@ // autocompleteCat: customized JQuery autocomplete plugin that includes watermark and // can display results broken down by category (for example, genomes from various // assembly hubs and native genomes). // Copyright (C) 2018 The Regents of the University of California ///////////////////////////// Module: autocompleteCat ///////////////////////////// +/* jshint esnext: true */ + var autocompleteCat = (function() { // Customize jQuery UI autocomplete to show item categories and support html markup in labels. // Adapted from https://jqueryui.com/autocomplete/#categories and // http://forum.jquery.com/topic/using-html-in-autocomplete // Also adds watermark to input. $.widget("custom.autocompleteCat", $.ui.autocomplete, { _renderMenu: function(ul, items) { var that = this; var currentCategory = ""; // There's no this._super as shown in the doc, so I can't override // _create as shown in the doc -- just do this every time we render... this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)"); $.each(items, function(index, item) { // Add a heading each time we see a new category: if (item.category && item.category !== currentCategory) { ul.append("
  • " + item.category + "
  • " ); currentCategory = item.category; } 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 + let clockIcon = ''; + if ($("#positionInput").val().length < 2) { + clockIcon = ' '; + } return $("
  • ") .data("item.autocomplete", item) - .append($("").html(item.label)) + .append($("").html(clockIcon + item.label)) .appendTo(ul); } }); function toggleSpinner(add, options) { if (options.baseUrl.startsWith("hgGateway")) { // change the species select loading image if (add) $("#speciesSearch").after(""); else $("#speciesSpinner").remove(); } else if (options.baseUrl.startsWith("hgSuggest")) { // change the position input loading spinner if (add) $("#positionInput").after(""); @@ -88,51 +94,75 @@ } // 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 (this.element[0].id === "positionInput" && request.term.length < 2) { + let searchStack = window.localStorage.getItem("searchStack"); + if (request.term.length === 0 && searchStack) { + let searchObj = JSON.parse(searchStack); + let currDb = getDb(); + if (currDb in searchObj) { + // sort the results list according to the stack order: + let entries = Object.entries(searchObj[currDb].results); + let stack = searchObj[currDb].stack; + let callbackData = []; + for (let s of stack) { + callbackData.push(searchObj[currDb].results[s]); + } + acCallback(callbackData); + } + return; + } + } else if (request.term.length >=2) { + let results = cache[request.term]; if (results) { acCallback(results); } else if (options.baseUrl) { doSearch(request.term, acCallback); } + } }; var autoCompleteSelect = function(event, ui) { // This is a callback for autocomplete to let us know that the user selected // a term from the list. See http://api.jqueryui.com/autocomplete/#event-select + // since we are in an autocomplete don't bother saving the + // prefix the user typed in, just keep the geneSymbol itself + if (this.id === "positionInput") { + addRecentSearch(getDb(), ui.item.geneSymbol, ui.item); + } options.onSelect(ui.item); $input.blur(); }; // Provide default values where necessary: options.onSelect = options.onSelect || console.log; options.enterSelectsIdentical = options.enterSelectsIdentical || false; $input.autocompleteCat({ delay: 500, - minLength: 2, + minLength: 0, source: autoCompleteSource, select: autoCompleteSelect, enterSelectsIdentical: options.enterSelectsIdentical, enterTerm: options.onEnterTerm }); if (options.watermark) { $input.css('color', 'black'); $input.Watermark(options.watermark, '#686868'); } } return { init: init }; }()); // autocompleteCat