e782dd6b9d73b9e138d57e3ad213bb6402b3802d max Wed Aug 26 02:52:41 2026 -0700 hgTracks: deleting a custom track now clears it from the Visible Tracks list too A visible custom track is listed twice under the image, once in its own group and once in the Visible Tracks group. Both the right-click Delete Custom Track item and the trash icon left the other copy behind until the page was reloaded. Remove every track-list cell that carries the track's delete icon, in deleteCustomTrack() so both paths get it. refs #38087 diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index a45463f4d1d..57c021b4b6b 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -5555,56 +5555,68 @@ imageV2.drawHighlights(); } } function deleteCustomTrack (trackName) { /* Tell hgCustom to delete the given custom track. Shared by the trash icon * and the right-click context menu so there is only one deletion code path. */ // https://genome.ucsc.edu/cgi-bin/hgCustom?hgsid=1645697744_i0Yp2Di71NytSDdb6r0vUbupIvKO&hgct_do_delete=delete&hgct_del_ct_UserTrack_3545=on var hgsid = getHgsid(); var url = 'hgCustom?hgsid='+hgsid+'&hgct_do_delete=delete&hgct_del_'+trackName+'=on'; var xhttp = new XMLHttpRequest(); // this cannot be asyncronous, as users can click quickly here and the hgCustom calls above cannot run in parallel // since we store custom tracks as a text file, not mysql tables xhttp.open("GET", url, false); xhttp.send(); + removeCustomTrackCells(trackName); +} + +function removeCustomTrackCells (trackName) { + /* Remove this custom track from the track list under the image. A visible track is + * listed twice, once in its own group and once in the Visible Tracks group, so drop + * every cell that carries its delete icon, not just the one that was clicked. */ + var selector = 'div.trackDeleteIcon[data-track="' + trackName + '"]'; + document.querySelectorAll(selector).forEach(function(d) { + var td = d.closest("td"); + if (td) + td.remove(); + }); } function deleteAllBlatTracks () { /* Tell hgCustom to delete every BLAT result custom track at once (those tagged blatResult=on), * then reload so the BLAT Results group updates. Triggered by the group's "Delete all" button. */ var hgsid = getHgsid(); var url = 'hgCustom?hgsid='+hgsid+'&hgct_do_delete_blat=1'; var xhttp = new XMLHttpRequest(); // synchronous, for the same reason as deleteCustomTrack: custom tracks live in a text file, not // in parallel-safe mysql rows xhttp.open("GET", url, false); xhttp.send(); window.location.reload(); } function onTrackDelIconClick (ev) { /* delete custom track if user clicks its trash icon */ var divEl = ev.target.closest("div"); // must use .closest(), as user can click on either the SVG or the DIV space. var trackName = divEl.getAttribute("data-track"); deleteCustomTrack(trackName); // if the track is currently drawn, also remove it from the image and update // hgTracks.trackDb/cart, the same cleanup the right-click delete does. hideTracks() // assumes the track is in hgTracks.trackDb, so only call it when it is. if (hgTracks.trackDb && hgTracks.trackDb[trackName]) rightClick.hideTracks([trackName]); - divEl.closest("td").remove(); } function onQuickLiftDelIconClick (ev) { /* Remove this track's stanza from the quickLift hub in trash, and * remove all rows referencing it from the page (it can appear both in * its hub group and in the Visible Tracks group). */ var divEl = ev.target.closest("div"); var trackName = divEl.getAttribute("data-track"); var sourceDb = divEl.getAttribute("data-sourcedb"); var hgsid = getHgsid(); var url = 'hgTrackUi?hgsid=' + hgsid + '&hgTrackUi_op=quickLiftRemove' + '&g=' + encodeURIComponent(trackName) + '&qlSourceDb=' + encodeURIComponent(sourceDb); var xhttp = new XMLHttpRequest();