').text(value == null ? '' : String(value)).html();
}
function resetCallbookPanel() {
if ($('#qso-callbook-content').length === 0) {
return;
}
$('#qso-callbook-content').html('
Enter a callsign to load callbook details.
').attr('class', 'pt-2');
}
function renderCallbookPanel(callsign, result) {
if ($('#qso-callbook-content').length === 0) {
return;
}
var showProfileImage = (typeof qso_show_profile_image === 'undefined') ? true : !!qso_show_profile_image;
var safeCallsign = escapeCallbookHtml(callsign || '');
var safeName = escapeCallbookHtml(result.callsign_name || '');
var safeQth = escapeCallbookHtml(result.callsign_qth || '');
var safeLocator = escapeCallbookHtml(result.callsign_qra || '');
var safeIota = escapeCallbookHtml(result.callsign_iota || '');
var hasImage = showProfileImage && result.image && result.image !== 'n/a';
var imageColumnHtml = '';
if (hasImage) {
imageColumnHtml = '
';
} else if (showProfileImage) {
imageColumnHtml = '
No profile image returned by callbook provider.
';
}
var layoutClass = imageColumnHtml ? 'callbook-layout' : 'callbook-layout callbook-layout-no-image';
var html = ''
+ '
'
+ imageColumnHtml
+ '
'
+ '
' + safeCallsign + '
'
+ '
'
+ '
'
+ ' Name' + (safeName || '-') + ''
+ ' QTH' + (safeQth || '-') + ''
+ ' Locator' + (safeLocator || '-') + ''
+ ' IOTA' + (safeIota || '-') + ''
+ '
'
+ '
'
+ '
';
$('#qso-callbook-content').html(html).attr('class', 'pt-2');
}
function clearSatelliteFields() {
$('#sat_name').val('');
$('#sat_mode').val('');
$('.satellite_modes_list').find('option').remove().end();
selected_sat = '';
selected_sat_mode = '';
if ($('#selectPropagation').val() === 'SAT') {
$('#selectPropagation').val('');
}
}
function isSatelliteLookupContext() {
var propagationMode = normalizeFieldValue($('#selectPropagation').val()).toUpperCase();
var propagationModeCat = normalizeFieldValue($('#selectPropagation').data('catValue')).toUpperCase();
var satName = normalizeFieldValue($('#sat_name').val());
var satMode = normalizeFieldValue($('#sat_mode').val());
var satNameCat = normalizeFieldValue($('#sat_name').data('catValue'));
var satModeCat = normalizeFieldValue($('#sat_mode').data('catValue'));
if (propagationMode === 'SAT' || propagationModeCat === 'SAT' || satName !== '' || satMode !== '' || satNameCat !== '' || satModeCat !== '') {
return true;
}
var selectedRadioID = normalizeFieldValue($('select.radios').first().val());
var lastCatRadioID = normalizeFieldValue(window.cloudlogLastCatRadioId);
var lastCatData = window.cloudlogLastCatData;
if (selectedRadioID === '' || selectedRadioID === '0' || selectedRadioID !== lastCatRadioID || !lastCatData) {
return false;
}
var catPropMode = normalizeFieldValue(lastCatData.prop_mode).toUpperCase();
var catSatName = normalizeFieldValue(lastCatData.satname);
var catSatMode = normalizeFieldValue(lastCatData.satmode);
return catPropMode === 'SAT' || catSatName !== '' || catSatMode !== '';
}
function clearCatTrackedFieldState() {
$('#frequency, #frequency_rx, #sat_name, #sat_mode, #transmit_power, #selectPropagation, #mode').removeData('catValue');
}
/* Function: reset_fields is used to reset the fields on the QSO page */
function reset_fields() {
// Reset submission state
resetSubmissionState();
resetCallsignLookupState();
$('#locator_info').text("");
$('#country').val("");
$('#continent').val("");
$('#lotw_info').text("");
$('#lotw_info').removeClass("lotw_info_red");
$('#lotw_info').removeClass("lotw_info_yellow");
$('#lotw_info').removeClass("lotw_info_orange");
$('#qrz_info').text("");
$('#hamqth_info').text("");
$('#sota_info').text("");
$('#wwff_info').html('').attr('title', '');
$('#pota_info').html('').attr('title', '');
$('#dxcc_id').val("").trigger('change');
$('#cqz').val("");
$('#name').val("");
$('#qth').val("");
$('#locator').val("");
$('#iota_ref').val("");
$select = $('#sota_ref').selectize();
selectize = $select[0] ? $select[0].selectize : null;
if (selectize) selectize.clear();
$("#locator").removeClass("confirmedGrid");
$("#locator").removeClass("workedGrid");
$("#locator").removeClass("newGrid");
$("#callsign").removeClass("confirmedGrid");
$("#callsign").removeClass("workedGrid");
$("#callsign").removeClass("newGrid");
$('#callsign_info').removeClass("text-bg-secondary");
$('#callsign_info').removeClass("text-bg-success");
$('#callsign_info').removeClass("text-bg-danger");
resetCallbookPanel();
$('#qsl_via').val("");
$('#callsign_info').text("");
$('#input_usa_state').val("");
$('#qso-last-table').show();
$('#partial_view').html('');
$('#partial_view').hide();
previousContactsLookupMode = false;
resumeAutoRefresh();
var $select = $('#wwff_ref').selectize();
var selectize = $select[0] ? $select[0].selectize : null;
if (selectize) selectize.clear();
$select = $('#pota_ref').selectize();
selectize = $select[0] ? $select[0].selectize : null;
if (selectize) selectize.clear();
$select = $('#darc_dok').selectize();
selectize = $select[0] ? $select[0].selectize : null;
if (selectize) selectize.clear();
$select = $('#stationCntyInput').selectize();
selectize = $select[0] ? $select[0].selectize : null;
if (selectize) selectize.clear();
clearSatelliteFields();
clearCatTrackedFieldState();
mymap.setView(pos, 12);
mymap.removeLayer(markers);
$('.callsign-suggest').hide();
$('.dxccsummary').remove();
$('#timesWorked').html(lang_qso_title_previous_contacts);
renderQsoCallhistoryPanel([], 'Type a callsign to see membership details from your uploaded call history files.');
// Reapply default RST values for the current mode (e.g., CW => 599).
if (typeof setRst === 'function') {
setRst($('.mode').val());
}
}
function reapplyPostSaveDefaults(defaults) {
if (!defaults) {
return;
}
var selectedRadioForReset = normalizeFieldValue(defaults.radio || $('select.radios').first().val());
var hasSelectedRadioForReset = selectedRadioForReset !== '' && selectedRadioForReset !== '0';
if (typeof defaults.start_date !== 'undefined') {
$('#qso_input [name="start_date"]').val(defaults.start_date);
}
if (typeof defaults.band !== 'undefined') {
$('#band').val(defaults.band);
}
if (typeof defaults.mode !== 'undefined') {
$('#mode').val(defaults.mode);
}
if (!hasSelectedRadioForReset && typeof defaults.sat_name !== 'undefined') {
$('#sat_name').val(defaults.sat_name);
}
if (!hasSelectedRadioForReset && typeof defaults.sat_mode !== 'undefined') {
$('#sat_mode').val(defaults.sat_mode);
}
if (typeof defaults.radio !== 'undefined' && defaults.radio !== '') {
var radioValue = String(defaults.radio);
$('#qso_input select[name="radio"]').val(radioValue);
$('select.radios').val(radioValue);
if (typeof localStorage !== 'undefined') {
localStorage.setItem('selectedRadio', radioValue);
}
}
if (hasSelectedRadioForReset) {
// Prefer selected radio CAT values after save; avoid restoring stale sat fields.
$('#sat_name').val('').removeData('catValue');
$('#sat_mode').val('').removeData('catValue');
$('#selectPropagation').val('').removeData('catValue');
} else if ((defaults.sat_name && defaults.sat_name !== '') || (defaults.sat_mode && defaults.sat_mode !== '')) {
$('#sat_name').trigger('input');
}
if (typeof setRst === 'function') {
setRst($('#mode').val());
}
}
function resetTimers(manual) {
if (typeof manual !== 'undefined' && manual != 1) {
handleStart = setInterval(function() { getUTCTimeStamp($('.input_start_time')); }, 500);
handleEnd = setInterval(function() { getUTCTimeStamp($('.input_end_time')); }, 500);
handleDate = setInterval(function() { getUTCDateStamp($('.input_date')); }, 1000);
}
}
$("#callsign").focusout(function() {
// Temp store the callsign
var temp_callsign = $(this).val();
if (temp_callsign == lastCallsignUpdated) {
return;
}
lastCallsignUpdated = temp_callsign;
if ($(this).val().length >= 3) {
/* Find and populate DXCC */
$('.callsign-suggest').hide();
if (isSatelliteLookupContext()) {
var sat_type = "SAT";
var json_band = "0";
var json_mode = "0";
} else {
var sat_type = "0";
var json_band = $("#band").val();
var json_mode = $("#mode").val();
}
var find_callsign = $(this).val().toUpperCase();
var callsign = find_callsign;
var requestId = ++callsignLookupRequestId;
find_callsign=find_callsign.replace(/\//g, "-");
find_callsign=find_callsign.replace('Ø', '0');
// Replace / in a callsign with - to stop urls breaking
$.getJSON(base_url + 'index.php/logbook/json/' + find_callsign + '/' + sat_type + '/' + json_band + '/' + json_mode + '/' + $('#stationProfile').val(), function(result)
{
if (!isLookupStillCurrent(requestId, find_callsign)) {
return;
}
// Make sure the typed callsign and json result match
var currentCallsign = $('#callsign').val().toUpperCase().replace(/\//g, "-").replace('Ø', '0');
if(currentCallsign === find_callsign) {
// Enter lookup mode - pause auto-refresh of logbook pagination
previousContactsLookupMode = true;
pauseAutoRefresh();
// Reset QSO fields but keep current DXCC badge/country to avoid flicker.
resetDefaultQSOFields(true);
if(result.dxcc.entity != undefined) {
$('#country').val(convert_case(result.dxcc.entity));
$('#callsign_info').text(convert_case(result.dxcc.entity));
// Reset CSS values before updating
$('#callsign').removeClass("confirmedGrid");
$('#callsign').removeClass("workedGrid");
$('#callsign').removeClass("newGrid");
$('#callsign').attr('title', '');
if (result.callsignConfirmed || result.confirmed) {
$('#callsign').addClass("confirmedGrid");
$('#callsign').attr('title', 'Callsign was already worked and confirmed in the past on this band and mode!');
} else if (result.callsignWorkedBefore) {
$('#callsign').addClass("workedGrid");
$('#callsign').attr('title', 'Callsign was already worked in the past on this band and mode!');
} else {
$('#callsign').addClass("newGrid");
$('#callsign').attr('title', 'New Callsign!');
}
changebadge(result.dxcc.entity);
}
if(result.lotw_member == "active") {
$('#lotw_info').text("LoTW");
if (result.lotw_days > 365) {
$('#lotw_info').addClass('lotw_info_red');
} else if (result.lotw_days > 30) {
$('#lotw_info').addClass('lotw_info_orange');
$lotw_hint = ' lotw_info_orange';
} else if (result.lotw_days > 7) {
$('#lotw_info').addClass('lotw_info_yellow');
}
$('#lotw_link').attr('href',"https://lotw.arrl.org/lotwuser/act?act="+callsign);
$('#lotw_link').attr('target',"_blank");
$('#lotw_info').attr('data-bs-toggle',"tooltip");
$('#lotw_info').attr('title',"LoTW User. Last upload was "+result.lotw_days+" days ago");
$('[data-bs-toggle="tooltip"]').tooltip();
}
$('#qrz_info').html('

');
$('#qrz_info').attr('title', 'Lookup '+callsign+' info on qrz.com');
$('#hamqth_info').html('

');
$('#hamqth_info').attr('title', 'Lookup '+callsign+' info on hamqth.com');
renderCallbookPanel(callsign, result);
var $dok_select = $('#darc_dok').selectize();
var dok_selectize = $dok_select[0] ? $dok_select[0].selectize : null;
if (result.dxcc.adif == '230') {
$.get(base_url + 'index.php/lookup/dok/' + $('#callsign').val().toUpperCase(), function(result) {
if (!isLookupStillCurrent(requestId, find_callsign)) {
return;
}
if (result && dok_selectize) {
dok_selectize.addOption({name: result});
dok_selectize.setValue(result, false);
}
});
} else {
if (dok_selectize) dok_selectize.clear();
}
$('#dxcc_id').val(result.dxcc.adif);
$('#cqz').val(result.dxcc.cqz);
$('#ituz').val(result.dxcc.ituz);
var redIcon = L.icon({
iconUrl: icon_dot_url,
iconSize: [18, 18], // size of the icon
});
// Set Map to Lat/Long
markers.clearLayers();
mymap.setZoom(8);
if (typeof result.latlng !== "undefined" && result.latlng !== false) {
var marker = L.marker([result.latlng[0], result.latlng[1]], {icon: redIcon});
mymap.panTo([result.latlng[0], result.latlng[1]]);
mymap.setView([result.latlng[0], result.latlng[1]], 8);
} else {
var marker = L.marker([result.dxcc.lat, result.dxcc.long], {icon: redIcon});
mymap.panTo([result.dxcc.lat, result.dxcc.long]);
mymap.setView([result.dxcc.lat, result.dxcc.long], 8);
}
markers.addLayer(marker).addTo(mymap);
var overwriteConflicts = getLookupOverwriteConflicts(result);
showLookupOverwriteModal(overwriteConflicts).then(function(approval) {
if (!isLookupStillCurrent(requestId, find_callsign)) {
return;
}
if (shouldReplaceLookupField($('#qsl_via'), result.qsl_manager, 'qsl_via', approval)) {
$('#qsl_via').val(result.qsl_manager);
}
if (shouldReplaceLookupField($('#name'), result.callsign_name, 'name', approval)) {
$('#name').val(result.callsign_name);
}
if (shouldReplaceLookupField($('#qth'), result.callsign_qth, 'qth', approval)) {
$('#qth').val(result.callsign_qth);
}
applyLookupLocator(result, approval);
});
if($('#continent').val() == "") {
$('#continent').val(result.dxcc.cont);
}
/*
* Update state with returned value
*/
if($("#input_usa_state").val() == "") {
$("#input_usa_state").val(result.callsign_state).trigger('change');
}
/*
* Update county with returned value
*/
var $county_elem = $('#stationCntyInput');
if( $county_elem.length && $county_elem.has('option').length == 0 && result.callsign_us_county != "") {
var $county_select = $county_elem.selectize();
var county_selectize = $county_select[0] ? $county_select[0].selectize : null;
if (county_selectize) {
county_selectize.addOption({name: result.callsign_us_county});
county_selectize.setValue(result.callsign_us_county, false);
}
}
if(result.timesWorked != "") {
$('#timesWorked').html(result.timesWorked + ' ' + lang_qso_title_times_worked_before);
} else {
$('#timesWorked').html(lang_qso_title_previous_contacts);
}
if($('#iota_ref').val() == "") {
$('#iota_ref').val(result.callsign_iota);
}
/* display past QSOs */
var partialHtml = (typeof result.partial === 'string') ? result.partial : '';
if (partialHtml.trim() !== '') {
// State 2: Callsign found in log with past QSOs
$('#partial_view').html(partialHtml);
setPreviousContactsPanelState(true);
} else {
// State 3: Callsign found but NO past QSOs in database
var noQsoMsg = '
'
+ ''
+ 'No past QSOs with ' + escapeNoticeValue(find_callsign) + '—see callbook details above.'
+ '
';
$('#partial_view').html(noQsoMsg);
setPreviousContactsPanelState(true);
}
// Get DXX Summary
getDxccResult(result.dxcc.adif, convert_case(result.dxcc.entity));
}
});
} else {
// Reset QSO fields
resetDefaultQSOFields();
// Reset tabs - go back to Previous Contacts when callsign is cleared
resetToPreviousContactsTab();
}
})
function pauseAutoRefresh() {
if (typeof htmx !== 'undefined' && document.getElementById('qso-last-table-content')) {
var elem = document.getElementById('qso-last-table-content');
if (elem) {
elem.removeAttribute('hx-trigger');
}
}
}
function resumeAutoRefresh() {
if (typeof htmx !== 'undefined' && document.getElementById('qso-last-table-content')) {
var elem = document.getElementById('qso-last-table-content');
if (elem) {
elem.setAttribute('hx-trigger', 'every 5s');
htmx.process(elem);
}
}
}
function setPreviousContactsPanelState(showLookupDetails) {
if (showLookupDetails) {
// Show callsign-specific results (either QSOs found or "not found" message)
$('#qso-last-table').hide();
$('#qso-last-table').next('small').hide();
$('#partial_view').show();
previousContactsLookupMode = true;
return;
}
// Show paginated logbook (no callsign lookup active)
$('#qso-last-table').show();
$('#qso-last-table').next('small').show();
$('#partial_view').html('');
$('#partial_view').hide();
previousContactsLookupMode = false;
}
// Function to reset back to Previous Contacts tab
function resetToPreviousContactsTab() {
// Clear DXCC Summary tab content
$('#dxcc-summary-content').html('');
// Switch back to Previous Contacts tab
if (document.getElementById('previous-contacts-tab')) {
var previousContactsTab = new bootstrap.Tab(document.getElementById('previous-contacts-tab'));
previousContactsTab.show();
}
// Show the default previous contacts table and hide lookup details.
setPreviousContactsPanelState(false);
}
// Re-apply visibility state after HTMX updates the previous contacts markup.
if (typeof htmx !== 'undefined' && document.body) {
document.body.addEventListener('htmx:afterSwap', function(evt) {
var detail = evt && evt.detail ? evt.detail : null;
var target = detail && detail.target ? detail.target : null;
if (!target) {
return;
}
if (target.id !== 'qso-last-table' && target.id !== 'qso-last-table-content') {
return;
}
// If we're in lookup mode, keep showing the partial_view (callsign-specific results)
// If we're not in lookup mode, show the main pagination table
if (previousContactsLookupMode) {
setPreviousContactsPanelState(true);
} else if ($('#partial_view').html().trim() !== '') {
setPreviousContactsPanelState(true);
}
});
}
// If a radio is selected, prefer current CAT values over stale form defaults.
function syncFromSelectedRadioAfterReset() {
var $radios = $('select.radios');
var selectedRadioID = String($radios.first().val() || '0');
if (selectedRadioID === '0') {
return false;
}
// Use the radio change path so CAT lock state is reset before applying values.
if ($radios.length > 0) {
$radios.first().trigger('change');
return true;
}
if (typeof updateFromCAT === 'function') {
var now = Date.now();
if (now - lastResetCatSyncNoticeAt > 1000) {
showQsoNotice('Form reset. Syncing live data from selected radio.', 'info');
lastResetCatSyncNoticeAt = now;
}
updateFromCAT(selectedRadioID);
return true;
}
return false;
}
// Reset to Previous Contacts tab when form is reset
$('#qso_input').on('reset', function() {
resetCallsignLookupState();
if (suppressNextResetHandler) {
suppressNextResetHandler = false;
return;
}
setTimeout(function() {
reset_fields();
resetToPreviousContactsTab();
syncFromSelectedRadioAfterReset();
}, 100);
});
function resetQsoEntryOnEscape() {
var qsoForm = document.getElementById('qso_input');
if (!qsoForm) {
return;
}
var selectedRadioID = String($('select.radios').first().val() || '0');
var hasSelectedRadio = selectedRadioID !== '0';
// Capture the operating context the user currently has selected BEFORE native
// form reset clobbers it with server-session defaults (last logged QSO values).
var preBand = $('#band').val();
var preMode = $('#mode').val();
var preSatName = $('#sat_name').val();
var preSatMode = $('#sat_mode').val();
var prePropMode = $('#selectPropagation').val();
qsoForm.reset();
resetCallsignLookupState();
resetDefaultQSOFields();
resetToPreviousContactsTab();
$('#callsign').trigger('focus');
// The on('reset') handler runs reset_fields() + clearSatelliteFields() in 100ms.
// Re-apply the captured context afterwards so the user stays on the band/mode/
// satellite they had selected, not the one from the previous QSO session.
setTimeout(function() {
$('#band').val(preBand);
$('#mode').val(preMode);
if (!hasSelectedRadio && (preSatName || preSatMode || String(prePropMode || '').toUpperCase() === 'SAT')) {
$('#sat_name').val(preSatName);
$('#sat_mode').val(preSatMode);
$('#selectPropagation').val(prePropMode || 'SAT');
} else if (hasSelectedRadio) {
// Keep satellite fields clear until fresh CAT data is applied.
$('#sat_name').val('').removeData('catValue');
$('#sat_mode').val('').removeData('catValue');
$('#selectPropagation').val('').removeData('catValue');
}
if (typeof setRst === 'function') {
setRst($('#mode').val());
}
syncFromSelectedRadioAfterReset();
}, 150);
}
// Global ESC handling on the QSO page: reset form, return to Previous Contacts, and focus callsign.
$(document).off('keydown.qsoEscapeReset').on('keydown.qsoEscapeReset', function(e) {
if (e.key !== 'Escape' && e.keyCode !== 27) {
return;
}
if (!document.getElementById('qso_input')) {
return;
}
if ($(e.target).closest('.modal.show').length) {
return;
}
e.preventDefault();
e.stopPropagation();
window.cloudlogQsoEscHandledAt = Date.now();
resetQsoEntryOnEscape();
});
// Also handle when callsign is cleared (empty value entered)
$('#callsign').on('input keyup', function() {
if ($(this).val() === '' && lastCallsignUpdated !== '') {
resetCallsignLookupState();
resetDefaultQSOFields();
resetToPreviousContactsTab();
}
});
// Only set the frequency when not set by userdata/PHP.
if ($('#frequency').val() == "")
{
$.get(base_url + 'index.php/qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function(result) {
$('#frequency').val(result);
$('#frequency_rx').val("");
});
}
/* time input shortcut */
$('#start_time').change(function() {
var raw_time = $(this).val();
if(raw_time.match(/^\d\[0-6]d$/)) {
raw_time = "0"+raw_time;
}
if(raw_time.match(/^[012]\d[0-5]\d$/)) {
raw_time = raw_time.substring(0,2)+":"+raw_time.substring(2,4);
$('#start_time').val(raw_time);
}
});
$('#end_time').change(function() {
var raw_time = $(this).val();
if(raw_time.match(/^\d\[0-6]d$/)) {
raw_time = "0"+raw_time;
}
if(raw_time.match(/^[012]\d[0-5]\d$/)) {
raw_time = raw_time.substring(0,2)+":"+raw_time.substring(2,4);
$('#end_time').val(raw_time);
}
});
/* date input shortcut */
$('#start_date').change(function() {
raw_date = $(this).val();
if(raw_date.match(/^[12]\d{3}[01]\d[0123]\d$/)) {
raw_date = raw_date.substring(0,4)+"-"+raw_date.substring(4,6)+"-"+raw_date.substring(6,8);
$('#start_date').val(raw_date);
}
});
/* on mode change */
$('.mode').change(function() {
$.get(base_url + 'index.php/qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function(result) {
$('#frequency').val(result);
$('#frequency_rx').val("");
});
});
/* Calculate Frequency */
/* on band change */
$('#band').change(function() {
$.get(base_url + 'index.php/qso/band_to_freq/' + $(this).val() + '/' + $('.mode').val(), function(result) {
$('#frequency').val(result);
$('#frequency_rx').val("");
});
});
/* On Key up Calculate Bearing and Distance */
var locatorDebounceTimer = null;
$("#locator").keyup(function(){
clearTimeout(locatorDebounceTimer);
var $locator = $(this);
locatorDebounceTimer = setTimeout(function(){
if ($locator.val()) {
var qra_input = $locator.val();
var qra_lookup = qra_input.substring(0, 4);
if(qra_lookup.length >= 4) {
// Check Log if satname is provided
if (isSatelliteLookupContext()) {
//logbook/jsonlookupgrid/io77/SAT/0/0
$.getJSON(base_url + 'index.php/logbook/jsonlookupgrid/' + qra_lookup.toUpperCase() + '/SAT/0/0', function(result)
{
// Reset CSS values before updating
$('#locator').removeClass("confirmedGrid");
$('#locator').removeClass("workedGrid");
$('#locator').removeClass("newGrid");
$('#locator').attr('title', '');
if (result.confirmed) {
$('#locator').addClass("confirmedGrid");
$('#locator').attr('title', 'Grid was already worked and confirmed in the past');
} else if (result.workedBefore) {
$('#locator').addClass("workedGrid");
$('#locator').attr('title', 'Grid was already worked in the past');
} else {
$('#locator').addClass("newGrid");
$('#locator').attr('title', 'New grid!');
}
})
} else {
$.getJSON(base_url + 'index.php/logbook/jsonlookupgrid/' + qra_lookup.toUpperCase() + '/0/' + $("#band").val() +'/' + $("#mode").val(), function(result)
{
// Reset CSS values before updating
$('#locator').removeClass("confirmedGrid");
$('#locator').removeClass("workedGrid");
$('#locator').removeClass("newGrid");
$('#locator').attr('title', '');
if (result.confirmed) {
$('#locator').addClass("confirmedGrid");
$('#locator').attr('title', 'Grid was already worked and confimred in the past');
} else if (result.workedBefore) {
$('#locator').addClass("workedGrid");
$('#locator').attr('title', 'Grid was already worked in the past');
} else {
$('#locator').addClass("newGrid");
$('#locator').attr('title', 'New grid!');
}
})
}
}
if(qra_input.length >= 4 && $locator.val().length > 0) {
// Map pin — grid → lat/lng (pure frontend math, no server round-trip)
var latlng = QraUtils.qra2latlong(qra_input);
markers.clearLayers();
if (latlng && typeof latlng[0] !== "undefined" && typeof latlng[1] !== "undefined") {
var redIcon = L.icon({
iconUrl: icon_dot_url,
iconSize: [18, 18],
});
var marker = L.marker([latlng[0], latlng[1]], {icon: redIcon});
mymap.setZoom(8);
mymap.panTo([latlng[0], latlng[1]]);
mymap.setView([latlng[0], latlng[1]], 8);
markers.addLayer(marker).addTo(mymap);
}
// Bearing and distance — pure frontend math using injected station gridsquares
var myGrid = station_gridsquares[$('#stationProfile').val()];
if (myGrid) {
var bearingStr = QraUtils.bearingString(myGrid, qra_input, qso_measurement_base);
if (bearingStr) {
$('#locator_info').html(bearingStr).fadeIn("slow");
}
var dist = QraUtils.distanceKm(myGrid, qra_input);
document.getElementById("distance").value = dist !== null ? dist : '';
}
}
}
}, 300);
});
// Change report based on mode
$('.mode').change(function(){
setRst($('.mode') .val());
});
function convert_case(str) {
var lower = str.toLowerCase();
return lower.replace(/(^| )(\w)/g, function(x) {
return x.toUpperCase();
});
}
var qsoCallhistoryLookupTimer = null;
function qsoCallhistoryEscapeHtml(unsafeText) {
return String(unsafeText || '').replace(/[&<>\"]/g, function(tag) {
var replacements = {
'&': '&',
'<': '<',
'>': '>',
'"': '"'
};
return replacements[tag] || tag;
});
}
function qsoCallhistoryNormalizeText(value) {
return String(value || '').trim().toLowerCase();
}
function renderQsoCallhistoryPanel(matches, defaultText) {
var $card = $('#qso-callhistory-inline');
var $panel = $('#qso-callhistory-results');
if ($panel.length === 0 || $card.length === 0) {
return;
}
if (!matches || matches.length === 0) {
$panel.html('');
$card.hide();
return;
}
var html = '
';
$.each(matches, function(_, match) {
var organizationLabel = String(match.organization_label || 'Member');
var membershipNumber = String(match.exch1 || '');
var memberName = String(match.name || '');
var normalizedMembershipNumber = qsoCallhistoryNormalizeText(membershipNumber);
var normalizedMemberName = qsoCallhistoryNormalizeText(memberName);
var line = '' + qsoCallhistoryEscapeHtml(match.organization_label || 'Member') + '';
if (membershipNumber && qsoCallhistoryNormalizeText(organizationLabel).indexOf(normalizedMembershipNumber) === -1) {
line += ' #' + qsoCallhistoryEscapeHtml(membershipNumber);
}
if (memberName && normalizedMemberName !== normalizedMembershipNumber) {
line += ' - ' + qsoCallhistoryEscapeHtml(memberName);
}
var sigValue = qsoCallhistoryEscapeHtml(match.organization_label || '');
var sigInfoValue = qsoCallhistoryEscapeHtml(match.exch1 || '');
if (sigValue !== '' || sigInfoValue !== '') {
line += ' ';
}
html += '- ' + line + '
';
});
html += '
';
$panel.html(html);
$card.show();
}
$(document).on('click', '.qso-copy-sig-btn', function() {
var sig = $(this).data('sig') || '';
var sigInfo = $(this).data('siginfo') || '';
$('#sig').val(sig);
$('#sig_info').val(sigInfo);
});
function lookupQsoCallhistory(callsign) {
if (qsoCallhistoryLookupTimer !== null) {
clearTimeout(qsoCallhistoryLookupTimer);
}
qsoCallhistoryLookupTimer = setTimeout(function() {
$.ajax({
url: base_url + 'index.php/callhistory/lookup',
type: 'post',
data: { callsign: callsign },
success: function(response) {
if (!response || response.status !== 'ok') {
renderQsoCallhistoryPanel([], 'No call history match for this callsign.');
return;
}
renderQsoCallhistoryPanel(response.matches || [], 'No call history match for this callsign.');
},
error: function() {
renderQsoCallhistoryPanel([], 'Call history lookup failed.');
}
});
}, 250);
}
$('#dxcc_id').on('change', function() {
if (typeof toggleDokField === 'function') toggleDokField();
if (typeof toggleUsaFields === 'function') toggleUsaFields();
$.getJSON(base_url + 'index.php/logbook/jsonentity/' + $(this).val(), function (result) {
if (result.dxcc.name != undefined) {
$('#country').val(convert_case(result.dxcc.name));
$('#cqz').val(convert_case(result.dxcc.cqz));
$('#callsign_info').removeClass("text-bg-secondary");
$('#callsign_info').removeClass("text-bg-success");
$('#callsign_info').removeClass("text-bg-danger");
$('#callsign_info').attr('title', '');
$('#callsign_info').text(convert_case(result.dxcc.name));
changebadge(result.dxcc.name);
// Set Map to Lat/Long it locator is not empty
if($('#locator').val() == "") {
var redIcon = L.icon({
iconUrl: icon_dot_url,
iconSize: [18, 18], // size of the icon
});
markers.clearLayers();
var marker = L.marker([result.dxcc.lat, result.dxcc.long], {icon: redIcon});
mymap.setZoom(8);
mymap.panTo([result.dxcc.lat, result.dxcc.long]);
markers.addLayer(marker).addTo(mymap);
}
}
});
});
//Spacebar moves to the name field when you're entering a callsign
//Similar to contesting ux, good for pileups.
$("#callsign").on("keypress", function(e) {
if (e.which == 32){
$("#name").focus();
return false; //Eliminate space char
}
});
function quickLookupDxcc(callsign) {
if (!callsign || callsign.length < 3) {
return;
}
var requestId = ++callsignDxccQuickRequestId;
var find_callsign = callsign.toUpperCase().replace(/\//g, "-").replace('Ø', '0');
$.getJSON(base_url + 'index.php/logbook/jsondxcc/' + find_callsign, function(result) {
if (requestId !== callsignDxccQuickRequestId) {
return;
}
var currentCallsign = $('#callsign').val().toUpperCase().replace(/\//g, "-").replace('Ø', '0');
if (currentCallsign !== find_callsign) {
return;
}
if (result.dxcc && result.dxcc.entity !== undefined) {
$('#country').val(convert_case(result.dxcc.entity));
$('#callsign_info').text(convert_case(result.dxcc.entity));
changebadge(result.dxcc.entity);
$('#dxcc_id').val(result.dxcc.adif);
$('#cqz').val(result.dxcc.cqz);
$('#ituz').val(result.dxcc.ituz);
}
});
}
// On Key up check and suggest callsigns
$("#callsign").keyup(function() {
if (callsignDxccQuickTimer) {
clearTimeout(callsignDxccQuickTimer);
}
var currentCall = $(this).val();
if (currentCall.length >= 3) {
callsignDxccQuickTimer = setTimeout(function() {
quickLookupDxcc(currentCall);
}, 200);
}
if ($(this).val().length >= 3) {
$('.callsign-suggest').show();
$callsign = $(this).val().replace('Ø', '0');
lookupQsoCallhistory($callsign.toUpperCase());
$.ajax({
url: 'lookup/scp',
method: 'POST',
data: {
callsign: $callsign.toUpperCase()
},
success: function(result) {
$('.callsign-suggestions').text(result);
}
});
} else {
renderQsoCallhistoryPanel([], 'Type a callsign to see membership details from your uploaded call history files.');
}
});
//Reset QSO form Fields function
function resetDefaultQSOFields(preserveDxccState) {
var keepDxcc = preserveDxccState === true;
var preservedCountry = '';
var preservedCallsignInfoText = '';
var preservedCallsignInfoTitle = '';
var preservedCallsignInfoClass = '';
var preservedDxccId = '';
var preservedCqz = '';
var preservedItuz = '';
if (keepDxcc) {
preservedCountry = $('#country').val();
preservedCallsignInfoText = $('#callsign_info').text();
preservedCallsignInfoTitle = $('#callsign_info').attr('title') || '';
preservedCallsignInfoClass = $('#callsign_info').attr('class') || '';
preservedDxccId = $('#dxcc_id').val();
preservedCqz = $('#cqz').val();
preservedItuz = $('#ituz').val();
}
$('#callsign_info').text("");
$('#locator_info').text("");
$('#country').val("");
$('#continent').val("");
$('#lotw_info').text("");
$('#lotw_info').removeClass("lotw_info_red");
$('#lotw_info').removeClass("lotw_info_yellow");
$('#lotw_info').removeClass("lotw_info_orange");
$('#qrz_info').text("");
$('#hamqth_info').text("");
$('#dxcc_id').val("").trigger('change');
$('#cqz').val("");
$('#ituz').val("");
$("#locator").removeClass("workedGrid");
$("#locator").removeClass("confirmedGrid");
$("#locator").removeClass("newGrid");
$("#callsign").removeClass("workedGrid");
$("#callsign").removeClass("confirmedGrid");
$("#callsign").removeClass("newGrid");
$('#callsign_info').removeClass("text-bg-secondary");
$('#callsign_info').removeClass("text-bg-success");
$('#callsign_info').removeClass("text-bg-danger");
resetCallbookPanel();
$('.dxccsummary').remove();
$('#timesWorked').html(lang_qso_title_previous_contacts);
if (keepDxcc) {
$('#country').val(preservedCountry);
$('#callsign_info').text(preservedCallsignInfoText);
$('#callsign_info').attr('title', preservedCallsignInfoTitle);
$('#callsign_info').attr('class', preservedCallsignInfoClass);
$('#dxcc_id').val(preservedDxccId);
$('#cqz').val(preservedCqz);
$('#ituz').val(preservedItuz);
}
}
function closeModal() {
var container = document.getElementById("modals-here")
var backdrop = document.getElementById("modal-backdrop")
var modal = document.getElementById("modal")
modal.classList.remove("show")
backdrop.classList.remove("show")
setTimeout(function() {
container.removeChild(backdrop)
container.removeChild(modal)
}, 200)
}
// [TimeOff] test Consistency timeOff value (concidering start and end are between 23:00 and 00:59) //
function testTimeOffConsistency() {
var _start_time = $('#qso_input input[name="start_time"]').val();
var _end_time = $('#qso_input input[name="end_time"]').val();
$('#qso_input input[name="end_time"]').removeClass('inputError');
$('#qso_input .warningOnSubmit').hide();
$('#qso_input .warningOnSubmit_txt').empty();
if ( !( (parseInt(_start_time.replaceAll(':','')) <= parseInt(_end_time.replaceAll(':','')))
|| ((_start_time.substring(0,2)=="23")&&(_end_time.substring(0,2)=="00")) ) ) {
$('#qso_input input[name="end_time"]').addClass('inputError');
$('#qso_input .warningOnSubmit_txt').html(text_error_timeoff_less_timeon);
$('#qso_input .warningOnSubmit').show();
$('#qso_input input[name="end_time"]').off('change').on('change',function(){ testTimeOffConsistency(); });
return false;
}
return true;
}