7d149b1935f8a1e5f11f31f3cb8da99d31b3a8e6 jcasper Fri Apr 10 16:34:48 2026 -0700 Replaced handrolled JSON structure in faceted composite output from hgTrackUi with jsonWrite.h library-generated version, and added a defaultSortField trackDb setting to faceted composites to improve the subtrack presentation order, refs #36320 diff --git src/hg/js/facetedComposite.js src/hg/js/facetedComposite.js index b0818970768..052e352c952 100644 --- src/hg/js/facetedComposite.js +++ src/hg/js/facetedComposite.js @@ -137,43 +137,56 @@ data: null, orderable: false, defaultContent: "", title: ` `, // no render function needed }; const hasDataTypes = embeddedData.dataTypes && Object.keys(embeddedData.dataTypes).length > 0; const itemLabel = hasDataTypes ? "samples" : "tracks"; const singularLabel = itemLabel.slice(0, -1); const columns = [checkboxColumn, ...ordinaryColumns]; + + // Determine which column to sort by: use defaultSortField if it matches + // a metadata column (case-insensitive, ignoring leading underscores), + // otherwise fall back to the first data column. + let defaultSortCol = 1; // column 0 is checkboxes, 1 is first data col + if (embeddedData.defaultSortField) { + const target = embeddedData.defaultSortField.replace(/^_+/, "").toLowerCase(); + const idx = colNames.findIndex( + c => c.replace(/^_+/, "").toLowerCase() === target); + if (idx >= 0) + defaultSortCol = idx + 1; // +1 for the checkbox column + } + const table = $("#theMetaDataTable").DataTable({ data: metadata, deferRender: true, // seems faster columns: columns, columnDefs: [ { targets:0, render: DataTable.render.select() } ], responsive: true, layout: { topStart: 'pageLength', topEnd: null, // omit global search bottomStart: 'info', bottomEnd: 'paging' }, - order: [[1, "asc"]], // sort by the first data column, not checkbox + order: [[defaultSortCol, "asc"]], pageLength: 25, // show 25 rows per page by default lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]], language: { lengthMenu: `Show _MENU_ ${itemLabel}`, select: { rows: { 0: "", 1: `1 ${singularLabel} selected`, _: `%d ${itemLabel} selected` } }, info: `Showing _START_ to _END_ of _TOTAL_ ${itemLabel}`, infoFiltered: `(filtered from _MAX_ total ${itemLabel})`, }, select: { style: "multi", selector: "td:not(:has(a))" },