import { SmartTables } from '../optional/smartTables/smartTables.bundle.js'; // Wait for the DOM to load before initializing document.addEventListener('DOMContentLoaded', () => { // DOM elements const tableContainer = document.getElementById('tableContainer'); const thresholdSlider = document.getElementById('threshold'); const thresholdValue = document.getElementById('thresholdValue'); const minMatchLengthSlider = document.getElementById('minMatchLength'); const minMatchLengthValue = document.getElementById('minMatchLengthValue'); const multiWordThresholdSlider = document.getElementById('multiWordThreshold'); const multiWordThresholdValue = document.getElementById('multiWordThresholdValue'); const maxDistanceSlider = document.getElementById('maxDistance'); const maxDistanceValue = document.getElementById('maxDistanceValue'); const descriptionEl = document.getElementById('description'); const buildTableBtn = document.getElementById('buildTable'); const destroyTableBtn = document.getElementById('destroyTable'); const searchExample = document.getElementById('searchExample'); const resetBtn = document.getElementById('resetSettings'); // Table instance let table = null; // Initialize sliders with default values and ranges thresholdSlider.min = 0; thresholdSlider.max = 1; thresholdSlider.step = 0.1; thresholdSlider.value = 0; minMatchLengthSlider.min = 1; minMatchLengthSlider.max = 5; minMatchLengthSlider.step = 1; minMatchLengthSlider.value = 1; multiWordThresholdSlider.min = 0; multiWordThresholdSlider.max = 1; multiWordThresholdSlider.step = 0.1; multiWordThresholdSlider.value = 1; maxDistanceSlider.min = 0; maxDistanceSlider.max = 10; maxDistanceSlider.step = 1; maxDistanceSlider.value = 0; // Function to toggle controls state function toggleControlsState(disabled) { // Disable/enable all sliders thresholdSlider.disabled = disabled; minMatchLengthSlider.disabled = disabled; multiWordThresholdSlider.disabled = disabled; maxDistanceSlider.disabled = disabled; resetBtn.disabled = disabled; } // Update slider display values function updateSliderValues() { thresholdValue.textContent = thresholdSlider.value; minMatchLengthValue.textContent = minMatchLengthSlider.value; multiWordThresholdValue.textContent = multiWordThresholdSlider.value; maxDistanceValue.textContent = maxDistanceSlider.value; updateDescription(); } // Provide an explanation based on current settings function updateDescription() { const threshold = parseFloat(thresholdSlider.value); const minMatchLength = parseInt(minMatchLengthSlider.value); const multiWordThreshold = parseFloat(multiWordThresholdSlider.value); const maxDistance = parseInt(maxDistanceSlider.value); let desc = ""; // Threshold description if (threshold === 0) { desc += "• Exact matching only - No partial matches
"; } else if (threshold < 0.3) { desc += "• Minor fuzzy matching - Requires high similarity
"; } else if (threshold < 0.6) { desc += "• Moderate fuzzy matching - Allows reasonable variations
"; } else if (threshold < 1) { desc += "• High fuzzy matching - Will find loosely related terms
"; } else { desc += "• Maximum fuzzy matching - Will track down distant relatives like an overenthusiastic family reunion
"; } // Min Match Length description if (minMatchLength === 1) { desc += "• Will match even with a single character
"; } else { desc += "• Requires at least " + minMatchLength + " characters to match
"; } // Multi Word Threshold description if (multiWordThreshold === 1) { desc += "• All words in a multi-word search must match
"; } else if (multiWordThreshold > 0.5) { desc += "• Most words in a multi-word search must match
"; } else if (multiWordThreshold > 0) { desc += "• Some words in a multi-word search must match
"; } else { desc += "• Any word in a multi-word search can match
"; } // Max Distance description if (maxDistance === 0) { desc += "• No typo tolerance - Characters must match exactly
"; } else if (maxDistance === 1) { desc += "• Single typo tolerance - Allows 1 character mismatch
"; } else if (maxDistance < 5) { desc += "• Moderate typo tolerance - Allows " + maxDistance + " character mismatches
"; } else { desc += "• High typo tolerance - Allows many character mismatches
"; } // Example let example = ""; if (threshold === 0 && maxDistance === 0) { example = "Try searching for exact terms like 'John' or 'Do'"; } else if (threshold > 0 || maxDistance > 0) { if (maxDistance > 0) { example = "Try searches with typos like 'Jhon' instead of 'John' or 'Subrey' instead of 'Surgery'"; } else { example = "Try partial searches like 'Jo' for 'John' or 'Surg' for 'Surgery'"; } } searchExample.textContent = example; descriptionEl.innerHTML = desc; } // Add event listeners to sliders thresholdSlider.addEventListener('input', updateSliderValues); minMatchLengthSlider.addEventListener('input', updateSliderValues); multiWordThresholdSlider.addEventListener('input', updateSliderValues); maxDistanceSlider.addEventListener('input', updateSliderValues); // Reset settings to default values resetBtn.addEventListener('click', () => { thresholdSlider.value = 0.7; minMatchLengthSlider.value = 2; multiWordThresholdSlider.value = 0.5; maxDistanceSlider.value = 2; updateSliderValues(); }); // Build table with current settings buildTableBtn.addEventListener('click', () => { // If table already exists, destroy it first if (table) { table.destroy(); table = null; } // Get current slider values const fuzzySettings = { threshold: parseFloat(thresholdSlider.value), minMatchLength: parseInt(minMatchLengthSlider.value), multiWordThreshold: parseFloat(multiWordThresholdSlider.value), maxDistance: parseInt(maxDistanceSlider.value) }; // Log settings to confirm values console.log('Building table with fuzzy search settings:', fuzzySettings); // Show table container tableContainer.classList.remove('d-none'); // Initialize SmartTables with the table ID and fuzzy settings table = new SmartTables('myTable', { data: { type: "json", source: "json/MOCK_DATA_HOSPITAL.json", columns: [ { data: "PatientID", title: "ID" }, { data: "PatientName", title: "First Name" }, { data: "Phone", title: "Phone" }, { data: "DOB", title: "DOB" }, { data: "Service", title: "Service" }, { data: "ServiceDate", title: "Service Date" }, { data: "Severity", title: "Severity", render: function(value) { let severityClass = { "Mild": "badge bg-success", "Moderate": "badge bg-warning text-dark", "Severe": "badge bg-danger" }[value] || "badge bg-dark"; return '' + value + ''; } }, { data: "BillPaid", title: "Bill Paid" }, { data: "BillDue", title: "Bill Due" }, { data: "Department", title: "Department" }, { data: "Staff", title: "Doctor" }, { data: "Nurse", title: "Nurse" }, ] }, fuzzyMatch: fuzzySettings, perPage: 6, search: true, sort: true, pagination: true, debug: false, loading: { enabled: true, duration: 800 }, responsive: { enabled: true, breakpoint: 768, columnPriorities: { 0: 1, // ID - highest priority (never hide) 1: 2, // First Name - second highest priority 2: 3, // Last Name - third priority 3: 4, // Gender - fourth priority 4: 5, // Phone - fifth priority 5: 6, // DOB - sixth priority 6: 7, // Service - seventh priority 7: 8, // Service Date - eighth priority 8: 9, // Severity - ninth priority 9: 10, // Bill Paid - tenth priority 10: 11, // Bill Due - eleventh priority 11: 12 // Department - twelfth priority } } }); // Update button states buildTableBtn.disabled = true; destroyTableBtn.disabled = false; // Disable all fuzzy settings controls toggleControlsState(true); // Log the actual fuzzy settings used by the table console.log('Table created with actual fuzzy settings:', table.options.fuzzyMatch); // Add additional verification for search functionality // setTimeout(() => { // console.log('Verifying table search functionality:'); // console.log('- Search method type:', typeof table.handleSearch); // console.log('- Fuzzy match method type:', typeof table.fuzzyMatch); // console.log('- Is server-side:', table.options.data.serverSide); // // Log detailed fuzzy search settings // console.log('DETAILED FUZZY SEARCH SETTINGS:'); // console.log('- Threshold:', table.options.fuzzyMatch.threshold, '(0-1, higher = more fuzzy)'); // console.log('- Min Match Length:', table.options.fuzzyMatch.minMatchLength, '(min characters to match)'); // console.log('- Multi-word Threshold:', table.options.fuzzyMatch.multiWordThreshold, '(0-1, lower = more lenient)'); // console.log('- Max Distance:', table.options.fuzzyMatch.maxDistance, '(max character mismatches allowed)'); // // Add a test search to demonstrate fuzzy matching // const testSearchTerms = ["john", "jon", "medical", "surgery", "surgry"]; // console.log('FUZZY SEARCH TEST EXAMPLES:'); // testSearchTerms.forEach(term => { // console.log(`Testing search term: "${term}"`); // // Create a temp input to simulate search // const tempInput = document.createElement('input'); // tempInput.value = term; // // Call the search method directly // const searchFunction = table.handleSearch.bind(table); // searchFunction(term); // console.log(`Results found: ${table.filteredRows.length} rows`); // }); // }, 1000); }); // Destroy table destroyTableBtn.addEventListener('click', () => { if (table) { table.destroy(); table = null; } tableContainer.classList.add('d-none'); // Update button states buildTableBtn.disabled = false; destroyTableBtn.disabled = true; // Re-enable all fuzzy settings controls toggleControlsState(false); }); // Initialize slider values and description updateSliderValues(); // Disable destroy button initially since no table exists destroyTableBtn.disabled = true; });