e2c6af507b9d46c00083b9d560f643ee5f74e688
max
  Fri Sep 25 13:11:31 2026 -0700
hgSearch: fix JS error clicking MANE search result links, refs #38285

diff --git src/hg/js/hgSearch.js src/hg/js/hgSearch.js
index c775ea590b9..0405e8629f7 100644
--- src/hg/js/hgSearch.js
+++ src/hg/js/hgSearch.js
@@ -883,31 +883,34 @@
         // reload the page to attach curated hub (if any)
         re = /db=[\w,\.]*/;
         window.location = window.location.href.replace(re,"db="+newDb);
     }
 
     function saveLinkClicks() {
         // attach the link handlers to save search history
         document.querySelectorAll(".searchResult>a").forEach(function(i,j,k) {
             i.addEventListener("click", function(e) {
                 // i is the <a> element, use parent elements and the href
                 // to construct a fake autocomplete option and save it
                 e.preventDefault(); // stops the page from redirecting until this function finishes
                 let callbackData = {};
                 let trackName = i.parentNode.parentNode.parentNode.id.replace(/Results$/,"");
                 let matchList = uiState.positionMatches.find((matches) => matches.name === trackName);
-                let id, match, matchStr = i.childNodes[0].textContent;
+                // use the full link text, not just the first child node: a MANE
+                // transcript link has a "MANE Select: " text node before the
+                // bolded accession, so childNodes[0] alone would miss the accession
+                let id, match, matchStr = i.textContent;
                 // switch lookup depending on the different search categories:
                 let decoder = function(str) {
                     // helper decoder to change the html encoded entities in
                     // uiState.positionMatches.posName to what is actually rendered
                     // in matchStr
                     return $("<textarea/>").html(str).text();
                 };
                 let geneSymbol; // a potentially fake geneSymbol for the autoComplete
                 if (trackName === "trackDb") {
                     match = matchList.matches.find((elem) => {
                         let posSplit = elem.posName.split(":");
                         geneSymbol = decoder(posSplit[1] + " - " + posSplit[2]);
                         id = "hgTrackUi?db=" + uiState.db + "&g=" + posSplit[0];
                         return geneSymbol === matchStr;
                     });
@@ -929,32 +932,39 @@
                     callbackData.geneSymbol = geneSymbol;
                     callbackData.internalId = "";
                 } else if (trackName === "helpDocs") {
                     match = matchList.matches.find((elem) => {
                         let posSplit = elem.posName.split(":");
                         geneSymbol = decoder(posSplit[1].replaceAll("_", " "));
                         return geneSymbol === matchStr;
                     });
                     callbackData.label = geneSymbol;
                     callbackData.value = geneSymbol;
                     callbackData.id = match.position.split(":")[0];
                     callbackData.geneSymbol = geneSymbol;
                     callbackData.internalId = "";
                 } else { // regular track item  search result click
                     match = matchList.matches.find((elem) => {
+                        // mirror the title construction in printMatches(): a MANE
+                        // transcript is displayed as its protein accession (optionally
+                        // prefixed with the MANE status), not the raw posName
+                        let title = elem.maneProtAcc ? elem.maneProtAcc : elem.posName;
+                        if (elem.maneStatus) {
+                            title = elem.maneStatus + ": " + title;
+                        }
                         geneSymbol = elem.posName.replace(/ .*$/,"");
-                        return decoder(elem.posName) === matchStr;
+                        return decoder(title) === matchStr;
                     });
                     callbackData.label = geneSymbol;
                     callbackData.value = geneSymbol;
                     // special case the genbank searches that are supposed to go to hgc
                     // and not hgTracks
                     let parentTitle = i.parentNode.parentNode.parentNode.childNodes[2];
                     if (["all_mrna", "all_est", "xenoMrna", "xenoEst", "intronEst"].includes(trackName) && parentTitle.textContent.includes("Unaligned")) {
                         id = "hgc?db=" + db + "&g=" + trackName+ "&i=" + match.position + "&c=0&o=0&l=0&r=0" ;
                     } else {
                         id = match.position;
                     }
                     callbackData.id = id;
                     callbackData.geneSymbol = geneSymbol;
                     callbackData.internalId = match.hgFindMatches;
                 }