let callBookProcessingDialog = null; let inCallbookProcessing = false; let inCallbookItemProcessing = false; let stateFixingDialog = null; let inStateFixing = false; let stateFixStats = {fixed: 0, skipped: 0, fixedDxcc: new Set(), skippedDxcc: new Set(), skipReasons: new Set(), skippedDetails: []}; let lastChecked = null; let silentReset = false; const filterDefaults = {}; document.addEventListener("DOMContentLoaded", function() { document.querySelectorAll('.dropdown').forEach(dd => { dd.addEventListener('hide.bs.dropdown', function (e) { if (e.clickEvent && e.clickEvent.target.closest('.dropdown-menu')) { e.preventDefault(); } }); dd.querySelectorAll('.dropdown-action').forEach(btn => { btn.addEventListener('click', function() { const dropdown = bootstrap.Dropdown.getInstance(dd.querySelector('[data-bs-toggle="dropdown"]')); if (dropdown) dropdown.hide(); }); }); }); }); $('#band').change(function () { var band = $("#band option:selected").text(); if (band != "SAT") { $(".sats_dropdown").attr("hidden", true); $(".orbits_dropdown").attr("hidden", true); } else { $(".sats_dropdown").removeAttr("hidden"); $(".orbits_dropdown").removeAttr("hidden"); } }); $('#selectPropagation').change(function () { var prop_mode = $("#selectPropagation option:selected").text(); if (prop_mode != "Satellite") { $(".sats_dropdown").attr("hidden", true); $(".orbits_dropdown").attr("hidden", true); } else { $(".sats_dropdown").removeAttr("hidden"); $(".orbits_dropdown").removeAttr("hidden"); } }); function getSelectedIds() { let id_list = []; $('#qsoList tbody input:checked').each(function () { let id = $(this).closest('tr').attr('id')?.replace(/\D/g, ''); id_list.push(id); }); return id_list; } function updateRow(qso) { let row = $('#qsoID-' + qso.qsoID); let cells = row.find('td'); let c = 1; if ((user_options.datetime.show ?? 'true') == "true"){ cells.eq(c++).text(qso.qsoDateTime); } if ((user_options.duration.show ?? 'true') == "true"){ cells.eq(c++).text(qso.duration); } if ((user_options.last_modification.show ?? 'true') == "true"){ cells.eq(c++).text(qso.last_modified); } if ((user_options.de.show ?? 'true') == "true"){ cells.eq(c++).text(qso.de); } if ((user_options.dx.show ?? 'true') == "true"){ cells.eq(c++).html(''+qso.dx.replaceAll('0', 'Ø')+'' + (qso.callsign == '' ? '' : ' L') + ' Lookup ' + qso.dx.replaceAll('0', 'Ø') + ' on QRZ.com Lookup ' + qso.dx.replaceAll('0', 'Ø') + ' on HamQTH Clublog Log Search'); } if ((user_options.mode.show ?? 'true') == "true"){ cells.eq(c++).text(qso.mode); } if ((user_options.rsts.show ?? 'true') == "true"){ cells.eq(c++).html(qso.rstS); } if ((user_options.rstr.show ?? 'true') == "true"){ cells.eq(c++).html(qso.rstR); } if ((user_options.band.show ?? 'true') == "true"){ cells.eq(c++).text(qso.band); } if ((user_options.frequency.show ?? 'true') == "true"){ cells.eq(c++).text(qso.frequency); } if ( (user_options.gridsquare) && ((user_options.gridsquare.show ?? 'true') == "true")){ cells.eq(c++).html(qso.gridsquare); } if ((user_options.name.show ?? 'true') == "true"){ cells.eq(c++).text(qso.name); } if ((user_options.qth.show ?? 'true') == "true"){ cells.eq(c++).text(qso.qth); } if ((user_options.qslvia.show ?? 'true') == "true"){ cells.eq(c++).text(qso.qslVia); } if ((user_options.clublog.show ?? 'true') == "true"){ cells.eq(c++).html(qso.clublog); } if ((user_options.qsl.show ?? 'true') == "true"){ cells.eq(c++).html(qso.qsl); } if ($(".eqslconfirmation")[0] && ((user_options.eqsl.show ?? 'true') == "true")){ cells.eq(c++).html(qso.eqsl); } if ($(".lotwconfirmation")[0] && ((user_options.lotw.show ?? 'true') == "true")){ cells.eq(c++).html(qso.lotw); } if ((user_options.qrz.show ?? 'true') == "true"){ cells.eq(c++).html(qso.qrz); } if ((user_options.dcl.show ?? 'true') == "true"){ cells.eq(c++).html(qso.dcl); } if ((user_options.qslmsgs.show ?? 'true') == "true"){ cells.eq(c++).text(qso.qslMessage); } if ((user_options.qslmsgr.show ?? 'true') == "true"){ cells.eq(c++).text(qso.qslMessageR); } if ((user_options.dxcc.show ?? 'true') == "true"){ cells.eq(c++).html(qso.dxcc+qso.flag); } if ((user_options.state.show ?? 'true') == "true"){ cells.eq(c++).html(qso.state); } if ((user_options.county.show ?? 'true') == "true"){ cells.eq(c++).html(qso.county); } if ((user_options.cqzone.show ?? 'true') == "true"){ cells.eq(c++).html(qso.cqzone); } if ((user_options.ituzone.show ?? 'true') == "true"){ cells.eq(c++).html(qso.ituzone); } if ((user_options.iota.show ?? 'true') == "true"){ cells.eq(c++).html(qso.iota); } if ((user_options.pota.show ?? 'true') == "true"){ cells.eq(c++).html(qso.pota); } if ((user_options.sota) && ((user_options.sota.show ?? 'true') == "true")){ cells.eq(c++).html(qso.sota); } if ((user_options.dok) && ((user_options.dok.show ?? 'true') == "true")){ cells.eq(c++).html(qso.dok); } if ((user_options.wwff) && ((user_options.wwff.show ?? 'true') == "true")){ cells.eq(c++).html(qso.wwff); } if ((user_options.sig) && ((user_options.sig.show ?? 'true') == "true")){ cells.eq(c++).html(qso.sig); } if ((user_options.region) && ((user_options.region.show ?? 'true') == "true")){ cells.eq(c++).html(qso.region); } if ((user_options.operator) && ((user_options.operator.show ?? 'true') == "true")){ cells.eq(c++).html(qso.operator); } if ((user_options.comment) && ((user_options.comment.show ?? 'true') == "true")){ cells.eq(c++).html(qso.comment); } if ((user_options.propagation) && ((user_options.propagation.show ?? 'true') == "true")){ cells.eq(c++).html(qso.propagation); } if ((user_options.contest) && ((user_options.contest.show ?? 'true') == "true")){ cells.eq(c++).html(qso.contest); } if ((user_options.myrefs.show ?? 'true') == "true"){ cells.eq(c++).text(qso.deRefs); } if ((user_options.continent.show ?? 'true') == "true"){ cells.eq(c++).html(qso.continent); } if ((user_options.distance.show ?? 'true') == "true"){ cells.eq(c++).text(qso.distance); } if ((user_options.antennaazimuth.show ?? 'true') == "true"){ cells.eq(c++).text(qso.antennaazimuth); } if ((user_options.antennaelevation.show ?? 'true') == "true"){ cells.eq(c++).text(qso.antennaelevation); } if ((user_options.profilename.show ?? 'true') == "true"){ cells.eq(c++).text(qso.profilename); } if ((user_options.stationpower.show ?? 'true') == "true"){ cells.eq(c++).text(qso.stationpower); } $('[data-bs-toggle="tooltip"]').tooltip(); return row; } function loadQSOTable(rows) { const $table = $('#qsoList'); // Prevent initializing if already a DataTable if ($.fn.DataTable.isDataTable($table)) { $table.DataTable().clear().destroy(); } const langUrl = getDataTablesLanguageUrl(); const initTable = function(language) { $.fn.dataTable.moment(custom_date_format + ' HH:mm'); const table = $table.DataTable({ searching: false, responsive: false, ordering: true, scrollY: window.innerHeight - $('#searchForm').innerHeight() - 250, scrollCollapse: true, paging: false, language: language, createdRow: function (row, data, dataIndex) { $(row).attr('id', data.id); }, columnDefs: [ { orderable: false, targets: 0 }, { targets: $(".distance-column-sort").index(), type: "numbersort" }, { targets: $(".antennaazimuth-column-sort").index(), type: "numbersort" }, { targets: $(".antennaelevation-column-sort").index(), type: "numbersort" }, { targets: $(".stationpower-column-sort").index(), type: "numbersort" }, ], dom: 'Bfrtip', buttons: [ { extend: 'csv', className: 'mb-1 btn btn-sm btn-primary', // Bootstrap classes init: function(api, node, config) { $(node).removeClass('dt-button').addClass('btn btn-primary'); // Ensure Bootstrap class applies }, exportOptions: { columns: ':visible:not(:eq(0))', // export all visible except column 4 format: { body: function (data, row, column, node) { // strip HTML tags first (like DataTables does by default) if (typeof data === 'string' && data.includes('
')) { data = data.replace(/
/g, ''); } if (typeof data === 'string') { data = data.replace(/<[^>]*>/g, ''); } // then replace Ø with 0 in specific columns if (column === 1 || column === 2 || column === 3) { // remove a trailing "L" and trim whitespaces data = data.replace(/\s*L\s*$/, '').trim(); if (typeof data === 'string' && data.includes('Ø')) { data = data.replace(/Ø/g, '0'); } } if (typeof data === 'string' && data.includes('▲')) { data = data.replace(/▲/g, ''); } if (typeof data === 'string' && data.includes('▼')) { data = data.replace(/▼/g, ''); } data = data.replace(/ data-bs-toggle="tooltip" data-bs-html="true" class="[^"]*">/g, ''); return data; } } } } ] }); for (i = 0; i < rows.length; i++) { let qso = rows[i]; var data = []; data.push('
'); if ((user_options.datetime.show ?? 'true') == "true"){ if (qso.datetime === '') { data.push('Missing date'); } else { data.push(qso.qsoDateTime); } } if ((user_options.duration.show ?? 'true') == "true"){ data.push(qso.duration); } if ((user_options.last_modification.show ?? 'true') == "true"){ data.push(qso.last_modified); } if ((user_options.de.show ?? 'true') == "true"){ data.push(qso.de.replaceAll('0', 'Ø')); } if ((user_options.dx.show ?? 'true') == "true"){ if (qso.dx === '') { data.push('Missing callsign'); } else { data.push(''+qso.dx.replaceAll('0', 'Ø')+'' + (qso.callsign == '' ? '' : ' L') + ' Lookup ' + qso.dx.replaceAll('0', 'Ø') + ' on QRZ.com Lookup ' + qso.dx.replaceAll('0', 'Ø') + ' on HamQTH Clublog Log Search'); } } if ((user_options.mode.show ?? 'true') == "true"){ if (qso.mode === '') { data.push('Missing mode'); } else { data.push(qso.mode); } } if ((user_options.rsts.show ?? 'true') == "true"){ data.push(qso.rstS); } if ((user_options.rstr.show ?? 'true') == "true"){ data.push(qso.rstR); } if ((user_options.band.show ?? 'true') == "true"){ if (qso.band === '') { data.push('Missing band'); } else { data.push(qso.band); } } if ((user_options.frequency.show ?? 'true') == "true"){ data.push(qso.frequency); } if ((user_options.gridsquare.show ?? 'true') == "true"){ data.push(qso.gridsquare); } if ((user_options.name.show ?? 'true') == "true"){ data.push(qso.name); } if ((user_options.qth.show ?? 'true') == "true"){ data.push(qso.qth); } if ((user_options.qslvia.show ?? 'true') == "true"){ data.push(qso.qslVia); } if ((user_options.clublog.show ?? 'true') == "true"){ data.push(qso.clublog); } if ((user_options.qsl.show ?? 'true') == "true"){ data.push(qso.qsl); } if ($(".eqslconfirmation")[0] && (user_options.eqsl.show ?? 'true') == "true"){ data.push(qso.eqsl); } if ($(".lotwconfirmation")[0] && (user_options.lotw.show ?? 'true') == "true"){ data.push(qso.lotw); } if ((user_options.qrz.show ?? 'true') == "true"){ data.push(qso.qrz); } if ((user_options.dcl.show ?? 'true') == "true"){ data.push(qso.dcl); } if ((user_options.qslmsgs.show ?? 'true') == "true"){ data.push(qso.qslMessage); } if ((user_options.qslmsgr.show ?? 'true') == "true"){ data.push(qso.qslMessageR); } if ((user_options.dxcc.show ?? 'true') == "true"){ data.push(qso.dxcc+qso.flag+(qso.end == null ? '' : ' Deleted DXCC')); } if ((user_options.state.show ?? 'true') == "true"){ data.push(qso.state); } if ((user_options.county.show ?? 'true') == "true"){ data.push(qso.county); } if ((user_options.cqzone.show ?? 'true') == "true"){ data.push(qso.cqzone); } if ((user_options.ituzone.show ?? 'true') == "true"){ data.push(qso.ituzone); } if ((user_options.iota.show ?? 'true') == "true"){ data.push(qso.iota); } if ((user_options.pota.show ?? 'true') == "true"){ data.push(qso.pota); } if ((user_options.sota.show ?? 'true') == "true"){ data.push(qso.sota); } if ((user_options.dok.show ?? 'true') == "true"){ data.push(qso.dok); } if ((user_options.wwff.show ?? 'true') == "true"){ data.push(qso.wwff); } if ((user_options.sig.show ?? 'true') == "true"){ data.push(qso.sig); } if ((user_options.region.show ?? 'true') == "true"){ data.push(qso.region); } if ((user_options.operator.show ?? 'true') == "true"){ data.push(qso.operator); } if ((user_options.comment.show ?? 'true') == "true"){ data.push(qso.comment); } if ((user_options.propagation.show ?? 'true') == "true"){ data.push(qso.propagation); } if ((user_options.contest.show ?? 'true') == "true"){ data.push(qso.contest); } if ((user_options.myrefs.show ?? 'true') == "true"){ data.push(qso.deRefs); } if ((user_options.continent.show ?? 'true') == "true"){ data.push(qso.continent); } if ((user_options.distance.show ?? 'true') == "true"){ data.push(qso.distance); } if ((user_options.antennaazimuth.show ?? 'true') == "true"){ data.push(qso.antennaazimuth); } if ((user_options.antennaelevation.show ?? 'true') == "true"){ data.push(qso.antennaelevation); } if ((user_options.profilename.show ?? 'true') == "true"){ data.push(qso.profilename); } if ((user_options.stationpower.show ?? 'true') == "true"){ data.push(qso.stationpower); } data.id='qsoID-' + qso.qsoID; let createdRow = table.row.add(data).index(); table.rows(createdRow).nodes().to$().data('qsoID', qso.qsoID); // table.row(createdRow).node().to$().attr("id", 'qsoID-' + qso.qsoID); } try { table.columns.adjust().draw(true); } catch (e) { table.draw(true); } rebind_checkbox_trigger(); $('[data-bs-toggle="tooltip"]').tooltip(); document.querySelectorAll('.row-check').forEach(checkbox => { checkbox.addEventListener('click', function (e) { const checkboxes = Array.from(document.querySelectorAll('.row-check')); if (e.shiftKey && lastChecked) { let start = checkboxes.indexOf(this); let end = checkboxes.indexOf(lastChecked); [start, end] = [Math.min(start, end), Math.max(start, end)]; for (let i = start; i <= end; i++) { checkboxes[i].checked = lastChecked.checked; $(checkboxes[i]).closest('tr').toggleClass('activeRow', lastChecked.checked); } } lastChecked = this; }); }); }; if (langUrl) { // Load language file first $.getJSON(langUrl) .done(function(language) { initTable(language); }) .fail(function() { console.error("Failed to load DataTables language file at " + langUrl); initTable({}); // fallback to default English }); } else { // No language file needed (English) initTable({}); } } $.fn.dataTable.ext.type.order['numbersort-pre'] = function(data) { var num = parseFloat(data); return isNaN(num) ? 0 : num; }; function processNextCallbookItem(gridsquareAccuracyCheck) { if (!inCallbookProcessing) return; var elements = $('#qsoList tbody input:checked'); var nElements = elements.length; if (nElements == 0) { inCallbookProcessing = false; callBookProcessingDialog.close(); let table = $('#qsoList').DataTable(); table.draw(false); return; } let id = elements.first().closest('tr').attr('id')?.replace(/\D/g, ''); // Removes non-numeric characters callBookProcessingDialog.setMessage("Retrieving callbook data : " + nElements + " remaining"); $.ajax({ url: site_url + '/logbookadvanced/updateFromCallbook', type: 'post', data: { qsoID: id, gridsquareAccuracyCheck: gridsquareAccuracyCheck ? 1 : 0 }, dataType: 'json', success: function (data) { if (data && data.dx) { updateRow(data); } unselectQsoID(id); setTimeout(function() { processNextCallbookItem(gridsquareAccuracyCheck); }, 50); }, error: function (data) { unselectQsoID(id); setTimeout(function() { processNextCallbookItem(gridsquareAccuracyCheck); }, 50); }, }); } function processNextStateFixItem() { if (!inStateFixing) return; var elements = $('#qsoList tbody input:checked'); var nElements = elements.length; if (nElements == 0) { inStateFixing = false; stateFixingDialog.close(); // Show summary let message = ''; message += lang_gen_advanced_logbook_fixed_with_count.replace('%s', stateFixStats.fixed); message += '
'; message += lang_gen_advanced_logbook_skipped_with_count.replace('%s', stateFixStats.skipped); if (stateFixStats.skippedDetails.length > 0) { message += '
'; message += ''; stateFixStats.skippedDetails.forEach(function(detail, index) { if (index > 0) message += '
'; message += detail; }); message += '
'; message += '
'; } if (stateFixStats.skipped > 0) { message += '
'; message += '' + lang_gen_advanced_logbook_state_not_supported.replace('%s', lang_gen_advanced_logbook_github_link); message += ''; message += '
'; } BootstrapDialog.alert({ title: lang_gen_advanced_logbook_state_fix_complete, message: function(dialog) { return message; }, type: stateFixStats.fixed > 0 ? BootstrapDialog.TYPE_SUCCESS : BootstrapDialog.TYPE_INFO, nl2br: false }); let table = $('#qsoList').DataTable(); table.draw(false); return; } let id = elements.first().closest('tr').attr('id')?.replace(/\D/g, ''); stateFixingDialog.setMessage(lang_gen_advanced_logbook_fixing_state_remaining.replace('%s', nElements)); $.ajax({ url: site_url + '/logbookadvanced/fixStateProgress', type: 'post', data: { qsoID: id }, dataType: 'json', success: function (data) { if (data.success && data.qso) { updateRow(data.qso); stateFixStats.fixed++; if (data.dxcc_name) { stateFixStats.fixedDxcc.add(data.dxcc_name); } } else if (data.skipped) { stateFixStats.skipped++; if (data.dxcc_name) { stateFixStats.skippedDxcc.add(data.dxcc_name); } if (data.reason) { stateFixStats.skipReasons.add(data.reason); // Build detailed skip entry: CALLSIGN - DXCC - reason let skipDetail = (data.callsign || 'Unknown') + ' - ' + (data.dxcc_name || 'Unknown DXCC') + ' - ' + data.reason; stateFixStats.skippedDetails.push(skipDetail); } } unselectQsoID(id); setTimeout("processNextStateFixItem()", 50); }, error: function (data) { stateFixStats.skipped++; unselectQsoID(id); setTimeout("processNextStateFixItem()", 50); }, }); } function selectQsoID(qsoID) { var element = $("#qsoID-" + qsoID); element.find("input[type=checkbox]").prop("checked", true); element.addClass('activeRow'); } function unselectQsoID(qsoID) { var element = $("#qsoID-" + qsoID); element.find("input[type=checkbox]").prop("checked", false); element.removeClass('activeRow'); $('#checkBoxAll').prop("checked", false); } // Capture default values for all filter fields on page load function captureFilterDefaults() { $('.filter-field').each(function() { const $el = $(this); const id = $el.attr('id'); const name = $el.attr('name'); // Use id as key if available, otherwise use name const key = id ? '#' + id : '[name="' + name + '"]'; filterDefaults[key] = $el.val(); }); } $(document).ready(function () { // Capture default filter values BEFORE any other initialization captureFilterDefaults(); // initialize multiselect dropdown for locations // Documentation: https://davidstutz.github.io/bootstrap-multiselect/index.html $('#de').multiselect({ // template is needed for bs5 support enableFiltering: true, enableCaseInsensitiveFiltering: true, filterPlaceholder: lang_general_word_search, templates: { button: '', }, numberDisplayed: 1, inheritClass: true, includeSelectAllOption: true }); $('#dxcc').multiselect({ // template is needed for bs5 support templates: { button: '', }, enableFiltering: true, enableFullValueFiltering: false, enableCaseInsensitiveFiltering: true, filterPlaceholder: lang_general_word_search, numberDisplayed: 1, inheritClass: true, buttonWidth: '100%', maxHeight: 600 }); $('.multiselect-container .multiselect-filter', $('#dxcc').parent()).css({ 'position': 'sticky', 'top': '0px', 'z-index': 1, 'background-color':'inherit', 'width':'100%', 'height':'37px' }) /*Pull from localStorage to set form input value*/ if (localStorage.hasOwnProperty(`user_${user_id}_qsoresults`)) { document.getElementById('qsoResults').value = localStorage.getItem(`user_${user_id}_qsoresults`); } if (localStorage.hasOwnProperty(`user_${user_id}_selectedlocations`)) { const selectedLocations = localStorage.getItem(`user_${user_id}_selectedlocations`); const locationsArray = selectedLocations ? selectedLocations.split(',') : []; // First, deselect all options $('#de').multiselect('deselectAll', false); // Then, select the stored locations $('#de').multiselect('select', locationsArray); } $('#searchForm').submit(function (e) { let container = L.DomUtil.get('advancedmap'); let selectedlocations = $('#de').val(); let qsoids = ''; if (Array.isArray(selectedlocations) && selectedlocations.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_location, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return false; } if(container != null){ container._leaflet_id = null; container.remove(); $(".coordinates").remove(); } $("#qsoList").attr("Hidden", false); $("#qsoList_wrapper").attr("Hidden", false); $("#qsoList_info").attr("Hidden", false); localStorage.setItem(`user_${user_id}_qsoresults`, this.qsoresults.value); localStorage.setItem(`user_${user_id}_selectedlocations`, $('#de').val()); $('#searchButton').prop("disabled", true).addClass("running"); let qsoresults = this.qsoresults.value; if (localStorage.hasOwnProperty(`user_${user_id}_qsoids`)) { qsoids = localStorage.getItem(`user_${user_id}_qsoids`); qsoresults = qsoids .split(',') .filter(i => i.trim() !== '').length; localStorage.removeItem(`user_${user_id}_qsoids`); } $.ajax({ url: this.action, type: 'post', data: { dateFrom: this.dateFrom.value, dateTo: this.dateTo.value, de: selectedlocations, dx: this.dx.value, mode: this.mode.value, band: this.band.value, qslSent: this.qslSent.value, qslReceived: this.qslReceived.value, qslSentMethod: this.qslSentMethod.value, qslReceivedMethod: this.qslReceivedMethod.value, iota: this.iota.value, operator: this.operator.value, dxcc: this.dxcc.value, propmode: this.propmode.value, gridsquare: this.gridsquare.value, state: this.state.value, county: this.county.value, qsoresults: qsoresults, sats: this.sats.value, orbits: this.orbits.value, cqzone: this.cqzone.value, ituzone: this.ituzone.value, lotwSent: this.lotwSent.value, lotwReceived: this.lotwReceived.value, clublogSent: this.clublogSent.value, clublogReceived: this.clublogReceived.value, eqslSent: this.eqslSent.value, eqslReceived: this.eqslReceived.value, dclSent: this.dclSent.value, dclReceived: this.dclReceived.value, qslvia: $('[name="qslvia"]').val(), sota: this.sota.value, pota: this.pota.value, wwff: this.wwff.value, qslimages: this.qslimages.value, dupes: this.dupes.value, dupedate: this.dupedate.value, dupemode: this.dupemode.value, dupeband: this.dupeband.value, dupesat: this.dupesat.value, contest: this.contest.value, invalid: this.invalid.value, continent: this.continent.value, comment: this.comment.value, qsoids: qsoids, dok: this.dok.value, qrzSent: this.qrzSent.value, qrzReceived: this.qrzReceived.value, distance: this.distance.value, sortcolumn: this.sortcolumn.value, sortdirection: this.sortdirection.value, duration: this.duration.value, }, dataType: 'json', success: function (data) { $('#searchButton').prop("disabled", false).removeClass("running"); loadQSOTable(data); if (qsoids !== '') { $('#checkBoxAll').prop("checked", true); $('#checkBoxAll').trigger('change'); } $('#checkBoxAll').prop("checked", false); }, error: function (data) { $('#searchButton').prop("disabled", false).removeClass("running"); BootstrapDialog.alert({ title: lang_gen_advanced_logbook_error, message: lang_gen_advanced_logbook_an_error_ocurred_while_making_request, type: BootstrapDialog.TYPE_DANGER, closable: false, draggable: false, callback: function (result) { } }); }, }); $("#dupes").val(""); $("#invalid").val(""); return false; }); $('#qsoList').on('click', 'input[type="checkbox"]', function() { if ($(this).is(":checked")) { $(this).closest('tr').addClass('activeRow'); } else { $(this).closest('tr').removeClass('activeRow'); } }); $('#btnUpdateFromCallbook').click(function (event) { let elements = $('#qsoList tbody input:checked'); let nElements = elements.length; if (nElements == 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row_callbook, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $.ajax({ url: base_url + 'index.php/logbookadvanced/callbookDialog', type: 'post', success: function (html) { BootstrapDialog.show({ title: 'Callbook options', size: BootstrapDialog.SIZE_NORMAL, cssClass: 'options', nl2br: false, message: html, buttons: [ { label: lang_admin_close, cssClass: 'btn btn-sm btn-secondary', id: 'closeButton', action: function (dialogItself) { dialogItself.close(); } }, { label: 'Update', cssClass: 'btn btn-sm btn-primary', id: 'updateButton', action: function (dialogItself) { startProcessingCallbook(nElements, $('[name="gridsquareaccuracycheck"]').is(":checked")); dialogItself.close(); } }], onhide: function(dialogRef){ return; }, }); } }); }); function startProcessingCallbook(nElements, gridsquareAccuracyCheck) { inCallbookProcessing = true; callBookProcessingDialog = BootstrapDialog.show({ title: "Retrieving callbook data for " + nElements + " QSOs", message: "Retrieving callbook data for " + nElements + " QSOs", type: BootstrapDialog.TYPE_DANGER, closable: false, draggable: false, buttons: [{ label: 'Cancel', action: function(dialog) { inCallbookProcessing = false; dialog.close(); } }] }); processNextCallbookItem(gridsquareAccuracyCheck); } $('#helpButton').click(function (event) { $.ajax({ url: base_url + 'index.php/logbookadvanced/helpDialog', type: 'post', success: function (html) { BootstrapDialog.show({ title: lang_gen_advanced_logbook_help, size: BootstrapDialog.SIZE_NORMAL, cssClass: 'options', nl2br: false, message: html, buttons: [ { label: lang_admin_close, cssClass: 'btn-sm btn-secondary', id: 'closeButton', action: function (dialogItself) { $('#optionButton').prop("disabled", false); dialogItself.close(); } }], onhide: function(dialogRef){ $('#optionButton').prop("disabled", false); }, }); } }); }); $('#deleteQsos').click(function (event) { const id_list = getSelectedIds(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row_delete, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $('#deleteQsos').prop("disabled", true); var table = $('#qsoList').DataTable(); BootstrapDialog.confirm({ title: lang_general_word_danger, message: lang_filter_actions_delete_warning+'
'+id_list.length+lang_filter_actions_delete_warning_details, type: BootstrapDialog.TYPE_DANGER, closable: true, draggable: true, btnOKClass: 'btn-danger', callback: function(result) { if(result) { $.ajax({ url: base_url + 'index.php/logbookadvanced/batchDeleteQsos', type: 'post', data: { 'ids': JSON.stringify(id_list, null, 2) }, success: function(data) { id_list.forEach(function(id) { let row = $("#qsoID-" + id); table.row(row).remove(); }); $('#deleteQsos').prop("disabled", false); table.draw(false); $('#checkBoxAll').prop("checked", false); } }) } }, onhide: function(dialogRef){ $('#deleteQsos').prop("disabled", false); }, }); }); $('#exportAdif').click(function (event) { $('#exportAdif').prop("disabled", true); const id_list = getSelectedIdsForMap(); xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { var a; if (xhttp.readyState === 4 && xhttp.status === 200) { // Trick for making downloadable link a = document.createElement('a'); a.href = window.URL.createObjectURL(xhttp.response); // Give filename you wish to download a.download = "logbook_export.adi"; a.style.display = 'none'; document.body.appendChild(a); a.click(); } }; if (id_list.length > 0) { // Post data to URL which handles post request xhttp.open("POST", site_url+'/logbookadvanced/export_to_adif', true); xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // You should set responseType as blob for binary responses xhttp.responseType = 'blob'; xhttp.send("id=" + JSON.stringify(id_list, null, 2)+"&sortcolumn=" +$('#sortcolumn').val()+"&sortdirection=" +$('#sortdirection').val()); } else { // Post data to URL which handles post request xhttp.open("POST", site_url+'/logbookadvanced/export_to_adif_params', true); xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); // You should set responseType as blob for binary responses xhttp.responseType = 'blob'; xhttp.send($('#searchForm').serialize()+"&de=" +$("#de").val()); } $('#exportAdif').prop("disabled", false); }); $('#queueBureau').click(function (event) { handleQsl('Q','B', 'queueBureau'); }); $('#queueDirect').click(function (event) { handleQsl('Q','D', 'queueDirect'); }); $('#queueElectronic').click(function (event) { handleQsl('Q','E', 'queueElectronic'); }); $('#sentBureau').click(function (event) { handleQsl('Y','B', 'sentBureau'); }); $('#sentDirect').click(function (event) { handleQsl('Y','D', 'sentDirect'); }); $('#sentElectronic').click(function (event) { handleQsl('Y','E', 'sentElectronic'); }); $('#dontSend').click(function (event) { handleQsl('N','', 'dontSend'); }); $('#notRequired').click(function (event) { handleQsl('I','', 'notRequired'); }); $('#notReceived').click(function (event) { handleQslReceived('N','', 'notReceived'); }); $('#receivedBureau').click(function (event) { handleQslReceived('Y','B', 'receivedBureau'); }); $('#receivedDirect').click(function (event) { handleQslReceived('Y','D', 'receivedDirect'); }); $('#receivedElectronic').click(function (event) { handleQslReceived('Y','E', 'receivedElectronic'); }); $('#searchGridsquare').click(function (event) { quickSearch('gridsquare'); }); $('#searchState').click(function (event) { quickSearch('state'); }); $('#searchIota').click(function (event) { quickSearch('iota'); }); $('#searchDxcc').click(function (event) { quickSearch('dxcc'); }); $('#searchCallsign').click(function (event) { quickSearch('dx'); }); $('#searchDate').click(function (event) { quickSearch('date'); }); $('#searchCqZone').click(function (event) { quickSearch('cqzone'); }); $('#searchItuZone').click(function (event) { quickSearch('ituzone'); }); $('#searchMode').click(function (event) { quickSearch('mode'); }); $('#searchBand').click(function (event) { quickSearch('band'); }); $('#searchSota').click(function (event) { quickSearch('sota'); }); $('#searchWwff').click(function (event) { quickSearch('wwff'); }); $('#searchPota').click(function (event) { quickSearch('pota'); }); $('#searchOperator').click(function (event) { quickSearch('operator'); }); $('#dupeButton').click(function (event) { dupeSearchDialog(); }); $('#invalidButton').click(function (event) { invalidSearch(); }); $('#editButton').click(function (event) { editQsos(); }); $('#optionButton').click(function (event) { $('#optionButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/userOptions', type: 'post', success: function (html) { BootstrapDialog.show({ title: lang_gen_advanced_logbook_options, size: BootstrapDialog.SIZE_NORMAL, cssClass: 'options', nl2br: false, message: html, onshown: function(dialog) { }, buttons: [{ label: lang_gen_advanced_logbook_save, cssClass: 'btn-primary btn-sm', id: 'saveButton', action: function (dialogItself) { $('#optionButton').prop("disabled", false); $('#closeButton').prop("disabled", true); saveOptions().then(() => { dialogItself.close(); location.reload(); }).catch(error => { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_error, message: lang_gen_advanced_logbook_error_saving_options + error, type: BootstrapDialog.TYPE_DANGER, // Sets the dialog style to "danger" closable: true, buttonLabel: lang_gen_advanced_logbook_close }); }); } }, { label: lang_admin_close, cssClass: 'btn-sm', id: 'closeButton', action: function (dialogItself) { $('#optionButton').prop("disabled", false); dialogItself.close(); } }], onhide: function(dialogRef){ $('#optionButton').prop("disabled", false); }, }); } }); }); $('#qslSlideshow').click(function (event) { const id_list = getSelectedIds(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row_qslcard, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $('#qslSlideshow').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/qslSlideshow', type: 'post', data: { ids: JSON.stringify(id_list), }, success: function (html) { BootstrapDialog.show({ title: lang_gen_advanced_logbook_qsl_card, size: BootstrapDialog.SIZE_WIDE, cssClass: 'lookup-dialog', nl2br: false, message: html, onshown: function(dialog) { }, buttons: [{ label: lang_admin_close, action: function (dialogItself) { $('#qslSlideshow').prop("disabled", false); dialogItself.close(); } }], onhide: function(dialogRef){ $('#qslSlideshow').prop("disabled", false); }, }); } }); }); $('#fixCqZones').click(function (event) { const id_list = getSelectedIds(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_row_cq_zones, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $.ajax({ url: base_url + 'index.php/logbookadvanced/fixCqZones', type: 'POST', data: { 'ids': JSON.stringify(id_list, null, 2) }, success: function (response) { if (response != []) { $.each(response, function(k, v) { updateRow(this); unselectQsoID(this.qsoID); }); } BootstrapDialog.alert({ title: lang_gen_advanced_logbook_success, message: lang_gen_advanced_logbook_cq_zones_updated, type: BootstrapDialog.TYPE_SUCCESS }); }, error: function () { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_error, message: lang_gen_advanced_logbook_problem_fixing_cq_zones, type: BootstrapDialog.TYPE_DANGER }); } }); }); $('#dbtools').click(function (event) { $.ajax({ url: base_url + 'index.php/logbookadvanced/dbtoolsDialog', type: 'post', success: function (html) { BootstrapDialog.show({ title: 'Database tools', size: BootstrapDialog.SIZE_EXTRAWIDE, cssClass: 'options', nl2br: false, closable: false, message: html, buttons: [ { label: lang_admin_close, cssClass: 'btn btn-sm btn-secondary', id: 'closeButton', action: function (dialogItself) { dialogItself.close(); } }], }); } }); }); $('#fixItuZones').click(function (event) { const id_list = getSelectedIds(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_row_itu_zones, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $.ajax({ url: base_url + 'index.php/logbookadvanced/fixItuZones', type: 'post', data: { 'ids': JSON.stringify(id_list, null, 2) }, success: function (response) { if (response != []) { $.each(response, function(k, v) { updateRow(this); unselectQsoID(this.qsoID); }); } BootstrapDialog.alert({ title: lang_gen_advanced_logbook_success, message: lang_gen_advanced_logbook_itu_zones_updated, type: BootstrapDialog.TYPE_SUCCESS }); }, error: function () { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_error, message: lang_gen_advanced_logbook_problem_fixing_itu_zones, type: BootstrapDialog.TYPE_DANGER }); } }); }); // Fix State button handler $('#fixState').click(function (event) { const id_list = getSelectedIds(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_row_state, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $.ajax({ url: base_url + 'index.php/logbookadvanced/stateDialog', type: 'post', success: function (html) { BootstrapDialog.show({ title: lang_gen_advanced_logbook_fixing_state, size: BootstrapDialog.SIZE_NORMAL, cssClass: 'options', nl2br: false, message: html, buttons: [ { label: lang_gen_advanced_logbook_update_now + '
', cssClass: 'btn btn-sm btn-primary ld-ext-right', id: 'updateStateButton', action: function (dialogItself) { const id_list = getSelectedIds(); if (inStateFixing) { return; } inStateFixing = true; // Close the info dialog dialogItself.close(); // Reset statistics stateFixStats = {fixed: 0, skipped: 0, fixedDxcc: new Set(), skippedDxcc: new Set(), skipReasons: new Set(), skippedDetails: []}; const nElements = id_list.length; stateFixingDialog = BootstrapDialog.show({ title: lang_gen_advanced_logbook_fixing_state_qsos.replace('%s', nElements), message: lang_gen_advanced_logbook_fixing_state_remaining.replace('%s', nElements), type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, buttons: [{ label: lang_admin_close, action: function(dialog) { inStateFixing = false; dialog.close(); } }] }); processNextStateFixItem(); } }, { label: lang_admin_close, cssClass: 'btn btn-sm btn-secondary', id: 'closeStateDialogButton', action: function (dialogItself) { dialogItself.close(); } }], }); } }); }); function dupeSearchDialog() { $.ajax({ url: base_url + 'index.php/logbookadvanced/dupeSearchDialog', type: 'post', success: function (html) { BootstrapDialog.show({ title: lang_gen_advanced_logbook_dupe_search, size: BootstrapDialog.SIZE_NORMAL, cssClass: 'options', nl2br: false, message: html, buttons: [ { label: lang_gen_advanced_logbook_search + '
', cssClass: 'btn btn-sm btn-primary ld-ext-right', id: 'dupeSearchButton', action: function (dialogItself) { dialogItself.close(); $('#dupedate').val($('#date_check').is(':checked') ? "Y" : "N"); $('#dupemode').val($('#mode_check').is(':checked') ? "Y" : "N"); $('#dupeband').val($('#band_check').is(':checked') ? "Y" : "N"); $('#dupesat').val($('#satellite_check').is(':checked') ? "Y" : "N"); dupeSearch(); } }, { label: lang_admin_close, cssClass: 'btn btn-sm btn-secondary', id: 'closeDupeDialogButton', action: function (dialogItself) { dialogItself.close(); } }], }); } }); } function dupeSearch() { $("#dupes").val("Y"); $('#dupeButton').prop('disabled', true).addClass('running'); setTimeout(() => { $('#dupeButton').prop('disabled', false).removeClass("running"); }, 1000); $('#searchForm').submit(); } function invalidSearch() { $("#invalid").val("Y"); $('#invalidButton').prop('disabled', true).addClass('running'); setTimeout(() => { $('#invalidButton').prop('disabled', false).removeClass("running"); }, 1000); $('#searchForm').submit(); } function quickSearch(type) { var elements = $('#qsoList tbody input:checked'); var nElements = elements.length; if (nElements == 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row_quickfilter, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } if (nElements > 1) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_warning, message: lang_gen_advanced_logbook_select_only_one_row_quickfilter, type: BootstrapDialog.TYPE_WARNING, closable: false, draggable: false, callback: function (result) { } }); return; } elements.each(function() { var currentRow = $(this).first().closest('tr'); var col1 = ''; switch (type) { case 'dxcc': col1 = currentRow.find('#dxcc').html(); col1 = col1.match(/\d/g); col1 = col1.join(""); break; case 'cqzone': col1 = currentRow.find('#cqzone').text(); break; case 'ituzone': col1 = currentRow.find('#ituzone').text(); break; case 'iota': col1 = currentRow.find('#iota').text(); col1 = col1.trim(); break; case 'state': col1 = currentRow.find('#state').text(); break; case 'dx': col1 = currentRow.find('#dx').text().replaceAll('Ø', '0'); col1 = col1.match(/^([^\s]+)/gm); break; case 'gridsquare': col1 = $(currentRow).find('#dxgrid').text(); col1 = col1.substring(0, 4); break; case 'sota': col1 = $(currentRow).find('#dxsota').text(); break; case 'wwff': col1 = $(currentRow).find('#dxwwff').text(); break; case 'pota': col1 = $(currentRow).find('#dxpota').text(); break; case 'operator': col1 = $(currentRow).find('#operator').text(); break; case 'mode': col1 = currentRow.find("td:eq(4)").text(); break; case 'band': col1 = currentRow.find("td:eq(7)").text(); col1 = col1.match(/\S\w*/); break; case 'date': col1 = currentRow.find("td:eq(1)").text(); break; } if (col1.length == 0) return; silentReset = true; $('#searchForm').trigger("reset"); if (type == 'date') { let dateParts; let formattedDate; switch (custom_date_format) { case "DD/MM/YY": dateParts = col1.split(' ')[0].split('/'); formattedDate = `${ensureFourDigitYear(dateParts[2])}-${dateParts[1]}-${dateParts[0]}`; break; case "DD/MM/YYYY": dateParts = col1.split(' ')[0].split('/'); formattedDate = `${dateParts[2]}-${dateParts[1]}-${dateParts[0]}`; break; case "MM/DD/YY": dateParts = col1.split(' ')[0].split('/'); formattedDate = `${ensureFourDigitYear(dateParts[2])}-${dateParts[0]}-${dateParts[1]}`; break; case "MM/DD/YYYY": dateParts = col1.split(' ')[0].split('/'); formattedDate = `${dateParts[2]}-${dateParts[0]}-${dateParts[1]}`; break; case "DD.MM.YYYY": dateParts = col1.split(' ')[0].split('.'); formattedDate = `${dateParts[2]}-${dateParts[1]}-${dateParts[0]}`; break; case "YY/MM/DD": dateParts = col1.split(' ')[0].split('/'); formattedDate = `${ensureFourDigitYear(dateParts[0])}-${dateParts[1]}-${dateParts[2]}`; break; case "YYYY-MM-DD": dateParts = col1.split(' ')[0].split('-'); formattedDate = `${dateParts[0]}-${dateParts[1]}-${dateParts[2]}`; break; case "MMM DD, YY": case "MMM DD, YYYY": const monthNames = { Jan: "01", Feb: "02", Mar: "03", Apr: "04", May: "05", Jun: "06", Jul: "07", Aug: "08", Sep: "09", Oct: "10", Nov: "11", Dec: "12" }; // Split by space and comma const parts = col1.replace(',', '').split(' '); // Example: ["Dec", "03", "24"] const month = monthNames[parts[0]]; // Convert month name to numeric format const day = parts[1].padStart(2, '0'); // Ensure day has leading zero const year = ensureFourDigitYear(parts[2]); // Ensure 4-digit year formattedDate = `${year}-${month}-${day}`; // Convert to 'YYYY-MM-DD' break; default: dateParts = col1.split(' ')[0].split('/'); formattedDate = `${dateParts[2]}-${dateParts[1]}-${dateParts[0]}`; } $("#dateFrom").val(formattedDate); $("#dateTo").val(formattedDate); } else { $("#"+type).val(col1); } updateFilterButtonStates(); $('#searchForm').submit(); }); } function ensureFourDigitYear(year) { // Utility function to handle 2-digit year conversion if (year.length === 2) { return parseInt(year, 10) <= 49 ? `20${year}` // Years 00-49 are in the 21st century : `19${year}`; // Years 50-99 are in the 20th century } return year; // If already 4 digits, return as is } $('#printLabel').click(function (event) { const id_list = getSelectedIds(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row_label, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $('#printLabel').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/startAtLabel', type: 'post', success: function (html) { BootstrapDialog.show({ title: ''+lang_label_print_options, size: BootstrapDialog.SIZE_NORMAL, cssClass: 'qso-dialog', nl2br: false, message: html, onshown: function(dialog) { }, buttons: [{ label: 'Print', cssClass: 'btn btn-primary btn-sm', action: function (dialogItself) { printlabel(id_list); dialogItself.close(); } }, { label: lang_admin_close, cssClass: 'btn btn-secondary btn-sm', action: function (dialogItself) { $('#printLabel').prop("disabled", false); dialogItself.close(); } }], onhide: function(dialogRef){ $('#printLabel').prop("disabled", false); }, }); } }); }); $('#searchForm').on('reset', function(e) { if (silentReset) { silentReset = false; // reset flag return; // skip submit } requestAnimationFrame(function() { updateFilterButtonStates(); }); setTimeout(function() { $('#searchForm').submit(); }); }); $('#searchForm').on('change', 'input, select', function() { updateFilterButtonStates(); }); rebind_checkbox_trigger(); $('#searchForm').submit(); setTimeout(function() { updateFilterButtonStates(); }, 100); }); function hasActiveFilters() { return Object.keys(filterDefaults).some(selector => { const $el = $(selector); if (!$el.length) return false; const currentVal = $el.val(); const defaultVal = filterDefaults[selector]; // Handle arrays (multi-select) if (Array.isArray(currentVal)) { return false; // Multi-selects not currently used } // Compare current value to stored default return currentVal !== defaultVal; }); } function updateFilterButtonStates() { const hasActive = hasActiveFilters(); if (hasActive) { $('#filterDropdown').addClass('btn-filter-active'); } else { $('#filterDropdown').removeClass('btn-filter-active'); } } function rebind_checkbox_trigger() { $('#checkBoxAll').change(function (event) { if (this.checked) { $('#qsoList tbody tr').each(function (i) { selectQsoID($(this).first().closest('tr').attr('id')?.replace(/\D/g, '')); }); } else { $('#qsoList tbody tr').each(function (i) { unselectQsoID($(this).first().closest('tr').attr('id')?.replace(/\D/g, '')); }); } }); } function handleQsl(sent, method, tag) { const id_list = getSelectedIdsForMap(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $('#'+tag).prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/update_qsl', type: 'post', data: {'id': JSON.stringify(id_list, null, 2), 'sent' : sent, 'method' : method }, success: function(data) { if (data != []) { $.each(data, function(k, v) { updateRow(this); unselectQsoID(this.qsoID); }); } $('#'+tag).prop("disabled", false); } }); } function handleQslReceived(sent, method, tag) { const id_list = getSelectedIdsForMap(); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } $.ajax({ url: base_url + 'index.php/logbookadvanced/update_qsl_received', type: 'post', data: {'id': JSON.stringify(id_list, null, 2), 'sent' : sent, 'method' : method }, success: function(data) { if (data != []) { $.each(data, function(k, v) { updateRow(this); unselectQsoID(this.qsoID); }); } $('#'+tag).prop("disabled", false); } }); } function printlabel(id_list) { let markchecked = $('#markprinted')[0].checked; $.ajax({ url: base_url + 'index.php/labels/printids', type: 'post', data: {'id': JSON.stringify(id_list, null, 2), 'startat': $('#startat').val(), 'grid': $('#gridlabel')[0].checked, 'via': $('#via')[0].checked, 'tnxmsg': $('#tnxmsg')[0].checked, 'qslmsg': $('#qslmsg')[0].checked, 'reference': $('#reference')[0].checked, 'mycall': $('#mycall')[0].checked }, xhr:function(){ var xhr = new XMLHttpRequest(); xhr.responseType= 'blob' return xhr; }, success: function(data) { if (markchecked) { handleQsl('Y','B', 'sentBureau'); } else { $.each(id_list, function(k, v) { unselectQsoID(this); }); } $.each(BootstrapDialog.dialogs, function(id, dialog){ dialog.close(); }); if(data){ var file = new Blob([data], {type: 'application/pdf'}); var fileURL = URL.createObjectURL(file); window.open(fileURL); } $('#printLabel').prop("disabled", false); }, error: function (data) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_error, message: lang_gen_advanced_logbook_label_print_error, type: BootstrapDialog.TYPE_DANGER, closable: false, draggable: false, callback: function (result) { } }); $.each(id_list, function(k, v) { unselectQsoID(this); }); $('#printLabel').prop("disabled", false); }, }); } function saveOptions() { $('#saveButton').prop("disabled", true); $('#closeButton').prop("disabled", true); return new Promise((resolve, reject) => { $.ajax({ url: base_url + 'index.php/logbookadvanced/setUserOptions', type: 'post', data: { datetime: $('input[name="datetime"]').is(':checked') ? true : false, duration: $('input[name="duration"]').is(':checked') ? true : false, last_modification: $('input[name="last_modification"]').is(':checked') ? true : false, de: $('input[name="de"]').is(':checked') ? true : false, dx: $('input[name="dx"]').is(':checked') ? true : false, mode: $('input[name="mode"]').is(':checked') ? true : false, rsts: $('input[name="rsts"]').is(':checked') ? true : false, rstr: $('input[name="rstr"]').is(':checked') ? true : false, band: $('input[name="band"]').is(':checked') ? true : false, myrefs: $('input[name="myrefs"]').is(':checked') ? true : false, name: $('input[name="name"]').is(':checked') ? true : false, qslvia: $('input[name="qslvia"]').is(':checked') ? true : false, qsl: $('input[name="qsl"]').is(':checked') ? true : false, clublog: $('input[name="clublog"]').is(':checked') ? true : false, lotw: $('input[name="lotw"]').is(':checked') ? true : false, eqsl: $('input[name="eqsl"]').is(':checked') ? true : false, qslmsgs: $('input[name="qslmsgs"]').is(':checked') ? true : false, qslmsgr: $('input[name="qslmsgr"]').is(':checked') ? true : false, dxcc: $('input[name="dxcc"]').is(':checked') ? true : false, state: $('input[name="state"]').is(':checked') ? true : false, county: $('input[name="county"]').is(':checked') ? true : false, cqzone: $('input[name="cqzone"]').is(':checked') ? true : false, ituzone: $('input[name="ituzone"]').is(':checked') ? true : false, iota: $('input[name="iota"]').is(':checked') ? true : false, pota: $('input[name="pota"]').is(':checked') ? true : false, operator: $('input[name="operator"]').is(':checked') ? true : false, comment: $('input[name="comment"]').is(':checked') ? true : false, propagation: $('input[name="propagation"]').is(':checked') ? true : false, contest: $('input[name="contest"]').is(':checked') ? true : false, gridsquare: $('input[name="gridsquare"]').is(':checked') ? true : false, sota: $('input[name="sota"]').is(':checked') ? true : false, dok: $('input[name="dok"]').is(':checked') ? true : false, wwff: $('input[name="wwff"]').is(':checked') ? true : false, sig: $('input[name="sig"]').is(':checked') ? true : false, region: $('input[name="region"]').is(':checked') ? true : false, continent: $('input[name="continent"]').is(':checked') ? true : false, distance: $('input[name="distance"]').is(':checked') ? true : false, antennaazimuth: $('input[name="antennaazimuth"]').is(':checked') ? true : false, antennaelevation: $('input[name="antennaelevation"]').is(':checked') ? true : false, qrz: $('input[name="qrz"]').is(':checked') ? true : false, profilename: $('input[name="profilename"]').is(':checked') ? true : false, stationpower: $('input[name="stationpower"]').is(':checked') ? true : false, gridsquare_layer: $('input[name="gridsquareoverlay"]').is(':checked') ? true : false, path_lines: $('input[name="pathlines"]').is(':checked') ? true : false, cqzone_layer: $('input[name="cqzones"]').is(':checked') ? true : false, ituzone_layer: $('input[name="ituzones"]').is(':checked') ? true : false, nightshadow_layer: $('input[name="nightshadow"]').is(':checked') ? true : false, qth: $('input[name="qth"]').is(':checked') ? true : false, frequency: $('input[name="frequency"]').is(':checked') ? true : false, dcl: $('input[name="dcl"]').is(':checked') ? true : false }, success: function(data) { $('#saveButton').prop("disabled", false); $('#closeButton').prop("disabled", false); resolve(data); }, error: function(error) { $('#saveButton').prop("disabled", false); reject(error); }, }); }); } // Preset functionality function applyPreset(preset) { const dateFrom = document.getElementById('dateFrom'); const dateTo = document.getElementById('dateTo'); const today = new Date(); // Format date as YYYY-MM-DD function formatDate(date) { const year = date.getUTCFullYear(); const month = String(date.getUTCMonth() + 1).padStart(2, '0'); const day = String(date.getUTCDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } switch(preset) { case 'today': dateFrom.value = formatDate(today); dateTo.value = formatDate(today); break; case 'yesterday': const yesterday = new Date(today); yesterday.setDate(yesterday.getUTCDate() - 1); dateFrom.value = formatDate(yesterday); dateTo.value = formatDate(yesterday); break; case 'last7days': const sevenDaysAgo = new Date(today); sevenDaysAgo.setDate(sevenDaysAgo.getUTCDate() - 7); dateFrom.value = formatDate(sevenDaysAgo); dateTo.value = formatDate(today); break; case 'last30days': const thirtyDaysAgo = new Date(today); thirtyDaysAgo.setDate(thirtyDaysAgo.getUTCDate() - 30); dateFrom.value = formatDate(thirtyDaysAgo); dateTo.value = formatDate(today); break; case 'thismonth': const firstDayOfMonth = new Date(Date.UTC(today.getUTCFullYear(), today.getUTCMonth(), 1)); dateFrom.value = formatDate(firstDayOfMonth); dateTo.value = formatDate(today); break; case 'lastmonth': const firstDayOfLastMonth = new Date(Date.UTC(today.getUTCFullYear(), today.getUTCMonth() - 1, 1)); const lastDayOfLastMonth = new Date(Date.UTC(today.getUTCFullYear(), today.getUTCMonth(), 0)); dateFrom.value = formatDate(firstDayOfLastMonth); dateTo.value = formatDate(lastDayOfLastMonth); break; case 'thisyear': const firstDayOfYear = new Date(Date.UTC(today.getUTCFullYear(), 0, 1)); dateFrom.value = formatDate(firstDayOfYear); dateTo.value = formatDate(today); break; case 'lastyear': const lastYear = today.getUTCFullYear() - 1; const firstDayOfLastYear = new Date(Date.UTC(lastYear, 0, 1)); const lastDayOfLastYear = new Date(Date.UTC(lastYear, 11, 31)); dateFrom.value = formatDate(firstDayOfLastYear); dateTo.value = formatDate(lastDayOfLastYear); break; case 'alltime': dateFrom.value = ''; dateTo.value = ''; break; } updateFilterButtonStates(); } // Reset dates function function resetDates() { const dateFrom = document.getElementById('dateFrom'); const dateTo = document.getElementById('dateTo'); dateFrom.value = ''; dateTo.value = ''; updateFilterButtonStates(); } function checkUpdateDistances() { $('#checkUpdateDistancesBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkdistance', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkUpdateDistancesBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); }, error: function(xhr, status, error) { $('#checkUpdateDistancesBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop('disabled', false); let errorMsg = 'Error checking distance information'; if (xhr.responseJSON && xhr.responseJSON.message) { errorMsg += ': ' + xhr.responseJSON.message; } BootstrapDialog.alert({ title: 'Error', message: errorMsg, type: BootstrapDialog.TYPE_DANGER }); } }); } function checkFixContinent() { $('#checkFixContinentBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkcontinent', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkFixContinentBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); }, error: function(xhr, status, error) { $('#checkFixContinentBtn').prop('disabled', false).removeClass("running"); $('#closeButton').prop('disabled', false); let errorMsg = 'Error checking continent information'; if (xhr.responseJSON && xhr.responseJSON.message) { errorMsg += ': ' + xhr.responseJSON.message; } BootstrapDialog.alert({ title: 'Error', message: errorMsg, type: BootstrapDialog.TYPE_DANGER }); } }); } function checkFixState() { $('#checkFixStateBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkstate', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkFixStateBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); }, error: function(xhr, status, error) { $('#checkFixStateBtn').prop('disabled', false).removeClass("running"); $('#closeButton').prop('disabled', false); let errorMsg = 'Error checking state information'; if (xhr.responseJSON && xhr.responseJSON.message) { errorMsg += ': ' + xhr.responseJSON.message; } BootstrapDialog.alert({ title: 'Error', message: errorMsg, type: BootstrapDialog.TYPE_DANGER }); } }); } function fixState(dxcc, country) { $('#fixStateBtn_' + dxcc).prop("disabled", true).addClass("running"); $.ajax({ url: base_url + 'index.php/logbookadvanced/fixStateBatch', type: 'post', data: { dxcc: dxcc, country: country, stationid: $('#dbtools_station_id').val() }, success: function (response) { $('#fixStateBtn_' + dxcc).prop("disabled", false).removeClass("running"); $('.result').html(response); }, error: function () { $('#fixStateBtn_' + dxcc).prop("disabled", false).removeClass("running"); } }); } function openStateList(dxcc, country) { $('#openStateListBtn_' + dxcc).prop("disabled", true).addClass("running"); $.ajax({ url: base_url + 'index.php/logbookadvanced/openStateList', type: 'post', data: { dxcc: dxcc, country: country, stationid: $('#dbtools_station_id').val() }, success: function (response) { $('#openStateListBtn_' + dxcc).prop("disabled", false).removeClass("running"); BootstrapDialog.show({ title: 'QSO List', size: BootstrapDialog.SIZE_WIDE, cssClass: 'options', nl2br: false, message: response, buttons: [ { label: lang_admin_close, cssClass: 'btn-sm btn-secondary', id: 'closeButton', action: function (dialogItself) { dialogItself.close(); } }], onhide: function(dialogRef){ return; }, }); }, error: function () { $('#openStateListBtn_' + dxcc).prop("disabled", false).removeClass("running"); } }); } function runUpdateDistancesFix(dialogItself) { $('#updateDistanceButton').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/updateDistances', data: { stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function (response) { $('#updateDistanceButton').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); if (dialogItself != '') { dialogItself.close(); } $('.result').html(response); }, error: function(xhr, status, error) { $('#updateDistanceButton').prop("disabled", false).removeClass("running"); if (dialogItself != '') { dialogItself.close(); } $('.result').html(error); $('#closeButton').prop("disabled", false); } }); } function runContinentFix(dialogItself) { $('#updateContinentButton').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/fixContinent', data: { stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function (response) { $('#updateContinentButton').prop("disabled", false).removeClass("running"); if (dialogItself != '') { dialogItself.close(); } $('.result').html(response); $('#closeButton').prop("disabled", false); }, error: function(xhr, status, error) { $('#updateContinentButton').prop("disabled", false).removeClass("running"); $('.result').html(error); $('#closeButton').prop("disabled", false); } }); } function checkGrids() { $('#checkGridsBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkgrids', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkGridsBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); }, error: function(xhr, status, error) { $('#checkGridsBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop('disabled', false); $('.result').html(error); } }); } function fixMissingGrids() { $('#updateGridsBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/fixMissingGrids', data: { type: 'grids', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function (response) { $('#updateGridsBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); }, error: function(xhr, status, error) { $('#updateGridsBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(error); } }); } function checkDxcc() { $('#checkDxccBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkdxcc', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkDxccBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); $('#dxccCheckTable').DataTable({ "pageLength": 25, responsive: false, ordering: true, "scrollY": "510px", "scrollCollapse": true, "paging": false, "scrollX": false, "language": { url: getDataTablesLanguageUrl(), }, initComplete: function () { this.api() .columns('.select-filter') .every(function () { var column = this; var select = $('') .appendTo($(column.footer()).empty()) .on('change', function () { var val = $.fn.dataTable.util.escapeRegex($(this).val()); // Search in rendered content, not just data column.search(val ? val : '', true, false).draw(); }); // Count occurrences of each unique value var counts = {}; column.nodes().flatten().to$().each(function () { var text = $(this).text().trim(); if (text) { counts[text] = (counts[text] || 0) + 1; } }); // Add options with counts for (var text in counts) { if (!select.find('option[value="' + text + '"]').length) { select.append(''); } } // Sort options select.find('option:not(:first)').sort(function(a, b) { return a.text.localeCompare(b.text); }).appendTo(select); }); rebind_checkbox_trigger_dxcc(); }, }); }, error: function(xhr, status, error) { $('#checkDxccBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop('disabled', false); $('.result').html(error); } }); } function checkIncorrectCqZones() { $('#checkIncorrectCqZonesBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkincorrectcqzones', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkIncorrectCqZonesBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); $('#incorrectcqzonetable').DataTable({ "pageLength": 25, responsive: false, ordering: false, "scrollY": "510px", "scrollCollapse": true, "paging": false, "scrollX": false, "language": { url: getDataTablesLanguageUrl(), }, initComplete: function () { this.api() .columns('.select-filter') .every(function () { var column = this; var select = $('') .appendTo($(column.footer()).empty()) .on('change', function () { var val = $.fn.dataTable.util.escapeRegex($(this).val()); // Search in rendered content, not just data column.search(val ? val : '', true, false).draw(); }); // Count occurrences of each unique value var counts = {}; column.nodes().flatten().to$().each(function () { var text = $(this).text().trim(); if (text) { counts[text] = (counts[text] || 0) + 1; } }); // Add options with counts for (var text in counts) { if (!select.find('option[value="' + text + '"]').length) { select.append(''); } } // Sort options select.find('option:not(:first)').sort(function(a, b) { return a.text.localeCompare(b.text); }).appendTo(select); }); rebind_checkbox_trigger_cq_zone(); $('#forceMultiZoneUpdateCq').on('change', function() { $('#incorrectcqzonetable').DataTable().column(8).search('').draw(); $('#checkBoxAllCqZones').prop('checked', false); $('#incorrectcqzonetable tbody input[type="checkbox"]').prop('checked', false); $('#incorrectcqzonetable tbody tr.activeRow').removeClass('activeRow'); }); }, }); }, error: function(xhr, status, error) { $('#checkIncorrectCqZonesBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop('disabled', false); $('.result').html(error); } }); } function checkIncorrectItuZones() { $('#checkIncorrectItuZonesBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkincorrectituzones', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkIncorrectItuZonesBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); $('#incorrectituzonetable').DataTable({ "pageLength": 25, responsive: false, ordering: false, "scrollY": "510px", "scrollCollapse": true, "paging": false, "scrollX": false, "language": { url: getDataTablesLanguageUrl(), }, initComplete: function () { this.api() .columns('.select-filter') .every(function () { var column = this; var select = $('') .appendTo($(column.footer()).empty()) .on('change', function () { var val = $.fn.dataTable.util.escapeRegex($(this).val()); // Search in rendered content, not just data column.search(val ? val : '', true, false).draw(); }); // Count occurrences of each unique value var counts = {}; column.nodes().flatten().to$().each(function () { var text = $(this).text().trim(); if (text) { counts[text] = (counts[text] || 0) + 1; } }); // Add options with counts for (var text in counts) { if (!select.find('option[value="' + text + '"]').length) { select.append(''); } } // Sort options select.find('option:not(:first)').sort(function(a, b) { return a.text.localeCompare(b.text); }).appendTo(select); }); rebind_checkbox_trigger_itu_zone(); }, }); $('#forceMultiZoneUpdate').on('change', function() { $('#incorrectituzonetable').DataTable().column(8).search('').draw(); $('#checkBoxAllItuZones').prop('checked', false); $('#incorrectituzonetable tbody input[type="checkbox"]').prop('checked', false); $('#incorrectituzonetable tbody tr.activeRow').removeClass('activeRow'); }); }, error: function(xhr, status, error) { $('#checkIncorrectItuZonesBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop('disabled', false); $('.result').html(error); } }); } function rebind_checkbox_trigger_dxcc() { $('#checkBoxAllDxcc').change(function (event) { if (this.checked) { $('#dxccCheckTable tbody tr').each(function (i) { selectQsoIdDxcc($(this).first().closest('tr').attr('id')?.replace(/\D/g, ''), 'dxccCheckTable'); }); } else { $('#dxccCheckTable tbody tr').each(function (i) { unselectQsoIdDxcc($(this).first().closest('tr').attr('id')?.replace(/\D/g, ''), 'dxccCheckTable'); }); } }); } function selectQsoIdDxcc(qsoID, tablename) { var element = $("#" + tablename + " tbody tr#qsoID-" + qsoID); element.find(".row-check").prop("checked", true); element.addClass('activeRow'); } function unselectQsoIdDxcc(qsoID, tablename) { var element = $("#" + tablename + " tbody tr#qsoID-" + qsoID); element.find(".row-check").prop("checked", false); element.removeClass('activeRow'); } function rebind_checkbox_trigger_cq_zone() { $('#checkBoxAllCqZones').change(function (event) { if (this.checked) { $('#incorrectcqzonetable tbody tr').each(function (i) { if (!$(this).first().closest('tr').find("td[id='cqZones']").text().includes(',') || $('#forceMultiZoneUpdateCq').prop("checked")) { selectQsoIdDxcc($(this).first().closest('tr').attr('id')?.replace(/\D/g, ''), 'incorrectcqzonetable'); } }); if (!$('#forceMultiZoneUpdateCq').prop("checked")) { $('#incorrectcqzonetable').DataTable().column(8).search('^[^,]*$', true, false).draw(); } } else { $('#incorrectcqzonetable tbody tr').each(function (i) { unselectQsoIdDxcc($(this).first().closest('tr').attr('id')?.replace(/\D/g, ''), 'incorrectcqzonetable'); }); $('#incorrectcqzonetable').DataTable().column(8).search('').draw(); } }); } function rebind_checkbox_trigger_itu_zone() { $('#checkBoxAllItuZones').change(function (event) { if (this.checked) { $('#incorrectituzonetable tbody tr').each(function (i) { if (!$(this).first().closest('tr').find("td[id='ituZones']").text().includes(',') || $('#forceMultiZoneUpdate').prop("checked")) { selectQsoIdDxcc($(this).first().closest('tr').attr('id')?.replace(/\D/g, ''), 'incorrectituzonetable'); } }); if (!$('#forceMultiZoneUpdate').prop("checked")) { $('#incorrectituzonetable').DataTable().column(8).search('^[^,]*$', true, false).draw(); } } else { $('#incorrectituzonetable tbody tr').each(function (i) { unselectQsoIdDxcc($(this).first().closest('tr').attr('id')?.replace(/\D/g, ''), 'incorrectituzonetable'); }); $('#incorrectituzonetable').DataTable().column(8).search('').draw(); } }); } function fixDxccSelected() { let id_list = []; $('#dxccCheckTable tbody input:checked').each(function () { let id = $(this).closest('tr').attr('id')?.replace(/\D/g, ''); id_list.push(id); }); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } let table = $('#dxccCheckTable').DataTable(); $('#fixSelectedDxccBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/fixDxccSelected', type: 'post', data: {'ids': JSON.stringify(id_list, null, 2)}, success: function(data) { $('#fixSelectedDxccBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); id_list.forEach(function(id) { let row = $("#dxccCheckTable tbody tr#qsoID-" + id); table.row(row).remove(); $('#checkBoxAllDxcc').prop('checked', false); }); table.draw(false); $('.dxcctablediv').html(data.message); }, error: function(xhr, status, error) { $('#fixSelectedDxccBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(error); } }); } function checkIncorrectGridsquares() { $('#checkIncorrectGridsquaresBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkincorrectgridsquares', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkIncorrectGridsquaresBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); $('#gridsquareCheckTable').DataTable({ "pageLength": 25, responsive: false, ordering: false, "scrollY": "510px", "scrollCollapse": true, "paging": false, "scrollX": false, "language": { url: getDataTablesLanguageUrl(), }, initComplete: function () { this.api() .columns('.select-filter') .every(function () { var column = this; var select = $('') .appendTo($(column.footer()).empty()) .on('change', function () { var val = $.fn.dataTable.util.escapeRegex($(this).val()); // Search in rendered content, not just data column.search(val ? val : '', true, false).draw(); }); // Count occurrences of each unique value var counts = {}; column.nodes().flatten().to$().each(function () { var text = $(this).text().trim(); if (text) { counts[text] = (counts[text] || 0) + 1; } }); // Add options with counts for (var text in counts) { if (!select.find('option[value="' + text + '"]').length) { select.append(''); } } // Sort options select.find('option:not(:first)').sort(function(a, b) { return a.text.localeCompare(b.text); }).appendTo(select); }); }, }); }, error: function(xhr, status, error) { $('#checkIncorrectGridsquaresBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop('disabled', false); $('.result').html(error); } }); } function toggleGridsquare(id) { const shortSpan = document.getElementById(id + '-short'); const fullSpan = document.getElementById(id + '-full'); const link = document.getElementById(id + '-link'); if (shortSpan.style.display === 'none') { shortSpan.style.display = 'inline'; fullSpan.style.display = 'none'; link.textContent = lang_gen_advanced_logbook_show_more; } else { shortSpan.style.display = 'none'; fullSpan.style.display = 'inline'; link.textContent = lang_gen_advanced_logbook_show_less; } } function fixCqZoneSelected() { let id_list = []; $('#incorrectcqzonetable tbody input:checked').each(function () { let id = $(this).closest('tr').attr('id')?.replace(/\D/g, ''); // Skip entry if DXCC covers multiple CQ zones as the matching one cannot be identified automagically atm or force update if (!$(this).closest('tr').find("td[id='cqZones']").text().includes(',') || $('#forceMultiZoneUpdateCq').prop("checked")) { id_list.push(id); } }); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } let table = $('#incorrectcqzonetable').DataTable(); $('#fixSelectedCqZoneBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/fixCqZones', type: 'post', data: {'ids': JSON.stringify(id_list, null, 2)}, success: function(data) { $('#fixSelectedCqZoneBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); id_list.forEach(function(id) { let row = $("#incorrectcqzonetable tbody tr#qsoID-" + id); table.row(row).remove(); }); table.draw(false); }, error: function(xhr, status, error) { $('#fixSelectedCqZoneBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(error); } }); } function fixItuZoneSelected() { let id_list = []; $('#incorrectituzonetable tbody input:checked').each(function () { let id = $(this).closest('tr').attr('id')?.replace(/\D/g, ''); // Skip entry if DXCC covers multiple ITU zones as the matching one cannot be identified automagically atm or force update if (!$(this).closest('tr').find("td[id='ituZones']").text().includes(',') || $('#forceMultiZoneUpdate').prop("checked")) { id_list.push(id); } }); if (id_list.length === 0) { BootstrapDialog.alert({ title: lang_gen_advanced_logbook_info, message: lang_gen_advanced_logbook_select_at_least_one_row, type: BootstrapDialog.TYPE_INFO, closable: false, draggable: false, callback: function (result) { } }); return; } let table = $('#incorrectituzonetable').DataTable(); $('#fixSelectedItuZoneBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/fixItuZones', type: 'post', data: {'ids': JSON.stringify(id_list, null, 2)}, success: function(data) { $('#fixSelectedItuZoneBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); id_list.forEach(function(id) { let row = $("#incorrectituzonetable tbody tr#qsoID-" + id); table.row(row).remove(); }); table.draw(false); }, error: function(xhr, status, error) { $('#fixSelectedItuZoneBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(error); } }); } function checkIota() { $('#checkIotaBtn').prop("disabled", true).addClass("running"); $('#closeButton').prop("disabled", true); $.ajax({ url: base_url + 'index.php/logbookadvanced/checkDb', data: { type: 'checkiota', stationid: $('#dbtools_station_id').val() }, type: 'POST', success: function(response) { $('#checkIotaBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop("disabled", false); $('.result').html(response); $('#iotaCheckTable').DataTable({ "pageLength": 25, responsive: false, ordering: false, "scrollY": "510px", "scrollCollapse": true, "paging": false, "scrollX": false, "language": { url: getDataTablesLanguageUrl(), }, initComplete: function () { this.api() .columns('.select-filter') .every(function () { var column = this; var select = $('') .appendTo($(column.footer()).empty()) .on('change', function () { var val = $.fn.dataTable.util.escapeRegex($(this).val()); // Search in rendered content, not just data column.search(val ? val : '', true, false).draw(); }); // Count occurrences of each unique value var counts = {}; column.nodes().flatten().to$().each(function () { // Get text from the first anchor link which contains the IOTA reference var $anchor = $(this).find('a').first(); var text = $anchor.length ? $anchor.text().trim() : $(this).text().trim(); // Remove any extra whitespace text = text.split(/\s+/)[0]; if (text) { counts[text] = (counts[text] || 0) + 1; } }); // Add options with counts for (var text in counts) { if (!select.find('option[value="' + text + '"]').length) { select.append(''); } } // Sort options select.find('option:not(:first)').sort(function(a, b) { return a.text.localeCompare(b.text); }).appendTo(select); }); }, }); }, error: function(xhr, status, error) { $('#checkIotaBtn').prop("disabled", false).removeClass("running"); $('#closeButton').prop('disabled', false); let errorMsg = 'Error checking iota information'; if (xhr.responseJSON && xhr.responseJSON.message) { errorMsg += ': ' + xhr.responseJSON.message; } BootstrapDialog.alert({ title: 'Error', message: errorMsg, type: BootstrapDialog.TYPE_DANGER }); } }); } // Helper function to convert maidenhead grid to lat/lng bounds function maidenheadToBounds(grid) { if (!grid || grid.length < 2) return null; grid = grid.toUpperCase(); const d1 = "ABCDEFGHIJKLMNOPQR"; const d2 = "ABCDEFGHIJKLMNOPQRSTUVWX"; let lon = -180; let lat = -90; let lonWidth = 20; let latHeight = 10; // First pair (field) if (grid.length >= 2) { const lonIdx = d1.indexOf(grid[0]); const latIdx = d1.indexOf(grid[1]); if (lonIdx >= 0 && latIdx >= 0) { lon += lonIdx * 20; lat += latIdx * 10; lonWidth = 20; latHeight = 10; } } // Second pair (square) if (grid.length >= 4) { const lonIdx = parseInt(grid[2]); const latIdx = parseInt(grid[3]); if (!isNaN(lonIdx) && !isNaN(latIdx)) { lon += lonIdx * 2; lat += latIdx * 1; lonWidth = 2; latHeight = 1; } } // Third pair (subsquare) if (grid.length >= 6) { const lonIdx = d2.indexOf(grid[4]); const latIdx = d2.indexOf(grid[5]); if (lonIdx >= 0 && latIdx >= 0) { lon += lonIdx * (2 / 24); lat += latIdx * (1 / 24); lonWidth = 2 / 24; latHeight = 1 / 24; } } return L.latLngBounds([lat, lon], [lat + latHeight, lon + lonWidth]); } function showMapForIncorrectGrid(gridsquare, dxcc, dxccname) { $.ajax({ url: base_url + 'index.php/logbookadvanced/showMapForIncorrectGrid', type: 'post', data: { gridsquare: gridsquare, dxcc: dxcc, dxccname: dxccname }, success: function (data) { // Add metadata to data object data.gridsquareDisplay = gridsquare; data.dxccnameDisplay = dxccname; BootstrapDialog.show({ title: data.title, size: BootstrapDialog.SIZE_WIDE, cssClass: 'mapdialog', nl2br: false, message: '
', onshown: function(dialog) { drawMap(data); }, buttons: [{ label: lang_admin_close, action: function (dialogItself) { dialogItself.close(); } }] }); } }); } function drawMap(data) { if (typeof(user_map_custom.qsoconfirm) !== 'undefined') { confirmedColor = user_map_custom.qsoconfirm.color; } if (typeof(user_map_custom.qso) !== 'undefined') { workedColor = user_map_custom.qso.color; } let container = L.DomUtil.get('mapgridcontainer'); if(container != null){ container._leaflet_id = null; container.remove(); $(".mapgridcontent").html('
'); } // Initialize global arrays for colored maidenhead overlay if (typeof grid_two === 'undefined') grid_two = []; if (typeof grid_four === 'undefined') grid_four = []; if (typeof grid_six === 'undefined') grid_six = []; if (typeof grid_two_confirmed === 'undefined') grid_two_confirmed = []; if (typeof grid_four_confirmed === 'undefined') grid_four_confirmed = []; if (typeof grid_six_confirmed === 'undefined') grid_six_confirmed = []; // Clear arrays grid_two.length = 0; grid_four.length = 0; grid_six.length = 0; grid_two_confirmed.length = 0; grid_four_confirmed.length = 0; grid_six_confirmed.length = 0; grids = data.grids; // Process data.grids - mark in green (confirmed) if (data.grids) { // data.grids can be a comma-separated string or an array let gridsArray = Array.isArray(data.grids) ? data.grids : data.grids.split(',').map(g => g.trim()); gridsArray.forEach(function(grid) { let gridUpper = grid.toUpperCase(); if (gridUpper.length === 2) { grid_two_confirmed.push(gridUpper); grid_two.push(gridUpper); // Also add to worked so it shows up } else if (gridUpper.length === 4) { grid_four_confirmed.push(gridUpper); grid_four.push(gridUpper); // Also add to worked so it shows up } else if (gridUpper.length === 6) { grid_six_confirmed.push(gridUpper); grid_six.push(gridUpper); // Also add to worked so it shows up } }); } // Process data.gridsquare - mark first 4 letters in red (worked) if (data.gridsquare) { let gridsquareUpper = data.gridsquare.toUpperCase().substring(0, 4); if (gridsquareUpper.length >= 2) { let twoChar = gridsquareUpper.substring(0, 2); if (!grid_two_confirmed.includes(twoChar)) { grid_two.push(twoChar); } } if (gridsquareUpper.length >= 4) { let fourChar = gridsquareUpper.substring(0, 4); if (!grid_four_confirmed.includes(fourChar)) { grid_four.push(fourChar); } } } // Collect all grids to calculate bounds for auto-zoom // Include both data.grids (green) and data.gridsquare (red) let allGrids = []; if (data.grids) { let gridsArray = Array.isArray(data.grids) ? data.grids : data.grids.split(',').map(g => g.trim()); allGrids = allGrids.concat(gridsArray); } if (data.gridsquare) { allGrids.push(data.gridsquare.substring(0, Math.min(4, data.gridsquare.length))); } // Calculate bounds and center for auto-zoom let bounds = null; let centerLat = 0; let centerLng = 0; let minLat = 90; let maxLat = -90; let allLngs = []; allGrids.forEach(function(grid) { let gridBounds = maidenheadToBounds(grid); if (gridBounds) { // Track center points and extents for better handling let gridCenter = gridBounds.getCenter(); centerLat += gridCenter.lat; allLngs.push(gridCenter.lng); if (gridBounds.getSouth() < minLat) minLat = gridBounds.getSouth(); if (gridBounds.getNorth() > maxLat) maxLat = gridBounds.getNorth(); if (bounds) { bounds.extend(gridBounds); } else { bounds = gridBounds; } } }); // Calculate average center if (allLngs.length > 0) { centerLat = centerLat / allGrids.length; // Check if longitudes span more than 180° (crossing antimeridian or covering large area) let minLng = Math.min(...allLngs); let maxLng = Math.max(...allLngs); let lngSpan = maxLng - minLng; if (lngSpan > 300) { // Spans nearly the entire globe (like Asiatic Russia from -180 to 180) // Use a predefined sensible center for such cases centerLng = 120; // Center of Asiatic Russia/mainland Russia } else if (lngSpan > 180) { // When spanning >180°, we should go the "other way around" the globe // Add 360° to any negative longitudes, then average, then normalize back let wrappedLngs = allLngs.map(lng => lng < 0 ? lng + 360 : lng); let avgWrapped = wrappedLngs.reduce((a, b) => a + b, 0) / wrappedLngs.length; // Normalize to -180 to 180 range if (avgWrapped > 180) avgWrapped -= 360; centerLng = avgWrapped; } else { // Normal case - simple average centerLng = allLngs.reduce((a, b) => a + b, 0) / allLngs.length; } } // Make map global for L.MaidenheadColouredGridMap.js window.map = new L.Map('mapgridcontainer', { fullscreenControl: true, fullscreenControlOptions: { position: 'topleft' }, }); let maidenhead = L.maidenhead().addTo(window.map); let osmUrl = option_map_tile_server; let osmAttrib= option_map_tile_server_copyright; let osm = new L.TileLayer(osmUrl, {minZoom: 1, maxZoom: 12, attribution: osmAttrib}); let redIcon = L.icon({ iconUrl: icon_dot_url, iconSize: [10, 10], // size of the icon }); window.map.addLayer(osm); // Add legend let legend = L.control({position: 'topright'}); legend.onAdd = function (map) { let div = L.DomUtil.create('div', 'info legend'); div.style.backgroundColor = 'white'; div.style.padding = '10px'; div.style.borderRadius = '5px'; div.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)'; div.innerHTML = '
' + '
' + '' + lang_gen_advanced_logbook_confirmedLabel + ' ' + data.dxccnameDisplay + '' + '
' + '
' + '
' + '' + lang_gen_advanced_logbook_workedLabel + ' ' + data.gridsquareDisplay + '' + '
'; return div; }; legend.addTo(window.map); // Zoom to fit all grids with padding if (bounds) { const latSpan = maxLat - minLat; const lngSpan = Math.max(...allLngs) - Math.min(...allLngs); // For extremely large spans (near 360° like Asiatic Russia), use manual center // For moderate spans (100-200° like Japan+GM05), use fitBounds with lower maxZoom // For smaller spans, use fitBounds normally if (lngSpan > 300) { // Spans nearly the entire globe - use calculated center with fixed zoom let zoom = 3; // Increased from 2 to 3 for better detail window.map.setView([centerLat, centerLng], zoom); } else if (lngSpan > 100) { // Large span (like Japan to western hemisphere) - use fitBounds but limit zoom window.map.fitBounds(bounds, { padding: [30, 30], maxZoom: 3 }); } else { // Normal case - use fitBounds let maxZoom = 10; if (lngSpan < 50) maxZoom = 7; if (lngSpan < 20) maxZoom = 10; window.map.fitBounds(bounds, { padding: [50, 50], maxZoom: maxZoom }); } } else { window.map.setView([30, 0], 1.5); } }