c7221bad6eda31fe88c6f9880276d8f993ff876e
chmalee
Thu Mar 5 12:37:14 2026 -0800
Disable recent/popular species list selection in the hgConvert toDb dropdown if there are no chains available to them. Leave them in the list but unselectable, refs #36232
diff --git src/hg/hgConvert/hgConvert.c src/hg/hgConvert/hgConvert.c
index 2b3f701ba0c..2374737ac43 100644
--- src/hg/hgConvert/hgConvert.c
+++ src/hg/hgConvert/hgConvert.c
@@ -152,35 +152,42 @@
puts("
\n");
cgiMakeButton(HGLFT_DO_CONVERT, "Submit");
puts("
\n");
/* JavaScript initialization for autocomplete with liftOver filtering */
jsInlineF(
"let validTargets = new Set();\n"
"\n"
"fetch('../cgi-bin/hubApi/liftOver/listExisting?fromGenome=%s')\n"
" .then(response => response.json())\n"
" .then(data => {\n"
" if (data.existingLiftOvers) {\n"
" data.existingLiftOvers.forEach(chain => validTargets.add(chain.toDb));\n"
" }\n"
"\n"
- " // Filter popular genomes to only those with a liftOver from source\n"
- " let dataEl = document.getElementById('%sPopularData');\n"
- " if (dataEl) {\n"
- " let popular = JSON.parse(dataEl.textContent);\n"
- " dataEl.textContent = JSON.stringify(popular.filter(p => validTargets.has(p.db)));\n"
+ " // Mark recent/popular genomes that don't have a liftOver from source as disabled\n"
+ " function markInvalidTargets(items) {\n"
+ " let sourceDb = '%s';\n"
+ " return items.filter(function(item) {\n"
+ " return (item.db || item.genome) !== sourceDb;\n"
+ " }).map(function(item) {\n"
+ " if (!validTargets.has(item.db || item.genome)) {\n"
+ " item.disabled = true;\n"
+ " item.disabledReason = 'No liftOver available from source assembly';\n"
+ " }\n"
+ " return item;\n"
+ " });\n"
" }\n"
"\n"
" // Custom onServerReply that processes results and filters to valid targets\n"
" function processAndFilterResults(result, term) {\n"
" let processed = processFindGenome(result, term);\n"
" let filtered = processed.filter(item => validTargets.has(item.genome));\n"
" if (filtered.length === 0 && processed.length > 0) {\n"
" // Found genomes but none have liftOver from source\n"
" return [{label: 'No liftOver available for matching genomes', value: '', genome: '', disabled: true}];\n"
" } else if (filtered.length === 0) {\n"
" // No genomes matched the search at all\n"
" return [{label: 'No genomes found', value: '', genome: '', disabled: true}];\n"
" }\n"
" return filtered;\n"
" }\n"
@@ -190,62 +197,62 @@
" return [{label: 'No genomes found', value: '', genome: '', disabled: true}];\n"
" }\n"
"\n"
" function onGenomeSelect(selectEle, item) {\n"
" // Ignore disabled/placeholder items\n"
" if (item.disabled || !item.genome) {\n"
" return;\n"
" }\n"
" selectEle.textContent = item.label;\n"
" document.mainForm.%s.value = item.commonName.split('(')[0].trim();\n"
" document.mainForm.%s.value = item.genome;\n"
" document.mainForm.submit();\n"
" }\n"
"\n"
" let selectEle = document.getElementById('toGenomeLabel');\n"
- " initSpeciesAutoCompleteDropdown('%s', onGenomeSelect.bind(null, selectEle), null, null, processAndFilterResults, onSearchError);\n"
+ " initSpeciesAutoCompleteDropdown('%s', onGenomeSelect.bind(null, selectEle), null, null, processAndFilterResults, onSearchError, markInvalidTargets);\n"
" });\n"
"\n"
"document.addEventListener('DOMContentLoaded', () => {\n"
" let btn = document.getElementById('%sButton');\n"
" if (btn) {\n"
" btn.addEventListener('click', () => {\n"
" let val = document.getElementById('%s').value;\n"
" $('[id=\\x27%s\\x27]').autocompleteCat('search', val);\n"
" });\n"
" }\n"
" let toggle = document.getElementById('%sToggle');\n"
" if (toggle) {\n"
" let wasOpen = false;\n"
" toggle.addEventListener('mousedown', () => {\n"
" let $input = $('[id=\\x27%s\\x27]');\n"
" wasOpen = $input.autocompleteCat('widget').is(':visible');\n"
" });\n"
" toggle.addEventListener('click', () => {\n"
" let $input = $('[id=\\x27%s\\x27]');\n"
" if (wasOpen) {\n"
" $input.autocompleteCat('close');\n"
" } else {\n"
" $input.val('');\n"
" $input.autocompleteCat('search', '');\n"
" $input.focus();\n"
" }\n"
" });\n"
" }\n"
"});\n"
, liftOver->fromDb
- , searchBarId
+ , liftOver->fromDb
, HGLFT_TOORG_VAR
, HGLFT_TODB_VAR
, searchBarId, searchBarId, searchBarId, searchBarId
, searchBarId, searchBarId, searchBarId
);
puts("\n");
cartWebEnd();
}
static double scoreLiftOverChain(struct liftOverChain *chain,
char *fromOrg, char *fromDb, char *toOrg, char *toDb, struct hash *dbRank )
/* Score the chain in terms of best match for cart settings */
{