dae1e675b0b01daeba5f781b4818ec5a9e372d04 jcasper Tue Nov 4 22:17:57 2025 -0800 Getting javascript for the new container type to pass jslint, refs #36320 diff --git src/hg/js/bigComposite.js src/hg/js/bigComposite.js index 2307f46afa9..2585e875abd 100644 --- src/hg/js/bigComposite.js +++ src/hg/js/bigComposite.js @@ -1,16 +1,17 @@ // SPDX-License-Identifier: MIT; (c) 2025 Andrew D Smith (author) +/* jshint esversion: 11 */ $(function() { /* ADS: Uncomment below to force confirm on unload/reload */ // window.addEventListener("beforeunload", function (e) { // e.preventDefault(); e.returnValue = ""; }); const DEFAULT_MAX_CHECKBOXES = 20; // ADS: without default, can get crazy // ADS: need "matching" versions for the plugins const DATATABLES_URL = "https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"; const DATATABLES_SELECT_URL = "https://cdn.datatables.net/select/1.7.0/js/dataTables.select.min.js"; const CSS_URLS = [ "https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css", // dataTables CSS "https://cdn.datatables.net/select/1.7.0/css/select.dataTables.min.css", // dataTables Select CSS "/style/bigComposite.css", // Local metadata table CSS ]; @@ -195,41 +196,46 @@ table.rows({ page: "current" }).select(); } else { table.rows({ page: "current" }).deselect(); } }); return table; } // end initTable function initFilters(table, allData) { const { metadata, colorMap, colNames } = allData; // iterate once over entire data not separately per attribute const possibleValues = {}; for (const entry of metadata) { for (const [key, val] of Object.entries(entry)) { - const map = possibleValues[key] ??= new Map(); + if (possibleValues[key] === null || possibleValues[key] === undefined) { + possibleValues[key] = new Map(); + } + const map = possibleValues[key]; map.set(val, (map.get(val) ?? 0) + 1); } } - const { maxCheckboxes, primaryKey } = embeddedData; - maxCheckboxes ??= DEFAULT_MAX_CHECKBOXES; - const excludeCheckboxes = [primaryKey] + let { maxCheckboxes, primaryKey } = embeddedData; + if (maxCheckboxes === null || maxCheckboxes === undefined) { + maxCheckboxes = DEFAULT_MAX_CHECKBOXES; + } + const excludeCheckboxes = [primaryKey]; const filtersDiv = document.getElementById("filters"); - colNames.forEach((key, colIdx) => { + colNames.forEach((key) => { // skip attributes if they should be excluded from checkbox sets if (excludeCheckboxes.includes(key)) { return; } const sortedPossibleVals = Array.from(possibleValues[key].entries()); sortedPossibleVals.sort((a, b) => b[1] - a[1]); // neg: less-than // Use 'maxCheckboxes' most frequent items (if they appear > 1 time) let topToShow = sortedPossibleVals .filter(([val, count]) => val.trim().toUpperCase() !== "NA" && count > 1) .slice(0, maxCheckboxes); // Any "other/Other/OTHER" entry will be put at the end @@ -320,31 +326,31 @@ selectedDataTypes.push(cb.value); } }); const uriForUpdate = new URLSearchParams({ mdid: mdid }); selectedRows.forEach(obj => // 'de' for data element uriForUpdate.append(`${mdid}_de`, obj[primaryKey])); selectedDataTypes.forEach(dat => // 'dt' for data type uriForUpdate.append(`${mdid}_dt`, dat)); updateVisibilities(uriForUpdate, submitBtnEvent); }); } // end initSubmit function initAll(dataForTable) { initDataTypeSelector(); const table = initTable(dataForTable); - initFilters(table, dataForTable) + initFilters(table, dataForTable); initSubmit(table); } function loadDataAndInit() { // load data and call init functions const { mdid, primaryKey, metadataUrl, colorSettingsUrl } = embeddedData; const CACHE_KEY = mdid; const CACHE_TIMESTAMP = `${CACHE_KEY}_time_stamp`; const CACHE_EXPIRY_MS = 24 * 60 * 60 * 1000; // 24 hours const now = Date.now(); const cachedTime = parseInt(localStorage.getItem(CACHE_TIMESTAMP), 10); let cachedData = null; let useCache = false; @@ -362,31 +368,31 @@ fetch(metadataUrl) .then(response => { if (!response.ok) { // a 404 will look like plain text throw new Error(`HTTP Status: ${response.status}`); } return response.text(); }) .then(tsvText => { // metadata table is a TSV file to parse loadOptional(colorSettingsUrl).then(colorMap => { const rows = tsvText.trim().split("\n"); const colNames = rows[0].split("\t"); const metadata = rows.slice(1).map(row => { const values = row.split("\t"); const obj = {}; - colNames.forEach((attrib, i) => { obj[attrib] = values[i] }); + colNames.forEach((attrib, i) => { obj[attrib] = values[i]; }); return obj; }); if (!metadata.length || !colNames.length) { localStorage.removeItem(CACHE_KEY); localStorage.removeItem(CACHE_TIMESTAMP); return; } const rowToIdx = Object.fromEntries( metadata.map((row, i) => [row[primaryKey], i]) ); colorMap = isValidColorMap(colorMap) ? colorMap : null; const freshData = { metadata, rowToIdx, colNames, colorMap }; // cache the data localStorage.setItem(CACHE_KEY, JSON.stringify(freshData)); localStorage.setItem(CACHE_TIMESTAMP, now.toString());