2020-12-07 21:26:16 +01:00
|
|
|
// Callsign always has focus on load
|
|
|
|
|
$("#callsign").focus();
|
|
|
|
|
|
2024-01-14 18:04:35 +00:00
|
|
|
var sessiondata = {};
|
2026-03-24 14:13:35 +00:00
|
|
|
$(document).ready(function () {
|
|
|
|
|
(async function() {
|
|
|
|
|
sessiondata = await getSession(); // save sessiondata global (we need it later, when adding qso)
|
|
|
|
|
await restoreContestSession(sessiondata); // wait for restoring until finished
|
|
|
|
|
setRst($("#mode").val());
|
2026-03-24 16:07:44 +00:00
|
|
|
setContestingTabOrder($("#exchangetype").val());
|
|
|
|
|
$("#callsign").focus().select();
|
2026-03-24 14:13:35 +00:00
|
|
|
})();
|
2026-03-24 22:36:54 +00:00
|
|
|
renderCallhistoryPanel([]);
|
2026-03-24 14:13:35 +00:00
|
|
|
|
|
|
|
|
/* On Key up Calculate Bearing and Distance for Contest Gridsquare */
|
|
|
|
|
$(document).on('keyup', '#exch_gridsquare_r', function(){
|
|
|
|
|
calculateContestBearingDistance();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/* On Change also calculate Bearing and Distance for Contest Gridsquare */
|
|
|
|
|
$(document).on('change', '#exch_gridsquare_r', function(){
|
|
|
|
|
calculateContestBearingDistance();
|
|
|
|
|
});
|
2020-12-27 09:37:48 +01:00
|
|
|
});
|
|
|
|
|
|
2026-03-24 22:36:54 +00:00
|
|
|
function escapeHtml(unsafeText) {
|
|
|
|
|
return String(unsafeText || '').replace(/[&<>"]/g, function (tag) {
|
|
|
|
|
var replacements = {
|
|
|
|
|
'&': '&',
|
|
|
|
|
'<': '<',
|
|
|
|
|
'>': '>',
|
|
|
|
|
'"': '"'
|
|
|
|
|
};
|
|
|
|
|
return replacements[tag] || tag;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 22:54:15 +00:00
|
|
|
function normalizeCallhistoryText(value) {
|
|
|
|
|
return String(value || '').trim().toLowerCase();
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 22:36:54 +00:00
|
|
|
function renderCallhistoryPanel(matches) {
|
|
|
|
|
var $card = $('#callhistory-info-panel');
|
|
|
|
|
var $panel = $('#callhistory-results');
|
|
|
|
|
if ($panel.length === 0 || $card.length === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!matches || matches.length === 0) {
|
|
|
|
|
$card.hide();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var html = '<ul class="list-group list-group-flush">';
|
|
|
|
|
|
|
|
|
|
$.each(matches, function (_, match) {
|
2026-03-24 22:54:15 +00:00
|
|
|
var organizationLabel = String(match.organization_label || 'Member');
|
|
|
|
|
var membershipNumber = String(match.exch1 || '');
|
|
|
|
|
var memberName = String(match.name || '');
|
|
|
|
|
var normalizedMembershipNumber = normalizeCallhistoryText(membershipNumber);
|
|
|
|
|
var normalizedMemberName = normalizeCallhistoryText(memberName);
|
|
|
|
|
|
|
|
|
|
var line = '<strong>' + escapeHtml(organizationLabel) + '</strong>';
|
|
|
|
|
if (membershipNumber && normalizeCallhistoryText(organizationLabel).indexOf(normalizedMembershipNumber) === -1) {
|
|
|
|
|
line += ' #' + escapeHtml(membershipNumber);
|
2026-03-24 22:36:54 +00:00
|
|
|
}
|
2026-03-24 22:54:15 +00:00
|
|
|
if (memberName && normalizedMemberName !== normalizedMembershipNumber) {
|
|
|
|
|
line += ' - ' + escapeHtml(memberName);
|
2026-03-24 22:36:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html += '<li class="list-group-item px-0 py-2">' + line + '</li>';
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
html += '</ul>';
|
|
|
|
|
$panel.html(html);
|
|
|
|
|
$card.show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function lookupCallhistory(call) {
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/callhistory/lookup',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: { callsign: call },
|
|
|
|
|
success: function (response) {
|
|
|
|
|
if (!response || response.status !== 'ok') {
|
|
|
|
|
renderCallhistoryPanel([]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
renderCallhistoryPanel(response.matches || []);
|
|
|
|
|
},
|
|
|
|
|
error: function () {
|
|
|
|
|
renderCallhistoryPanel([]);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 16:07:44 +00:00
|
|
|
function setContestingTabOrder(exchangetype) {
|
|
|
|
|
var orderedFieldIds = ['callsign', 'rst_sent'];
|
|
|
|
|
|
|
|
|
|
switch (exchangetype) {
|
|
|
|
|
case 'Exchange':
|
|
|
|
|
orderedFieldIds.push('exch_sent');
|
|
|
|
|
orderedFieldIds.push('rst_rcvd');
|
|
|
|
|
orderedFieldIds.push('exch_rcvd');
|
|
|
|
|
break;
|
|
|
|
|
case 'Gridsquare':
|
|
|
|
|
orderedFieldIds.push('rst_rcvd');
|
|
|
|
|
orderedFieldIds.push('exch_gridsquare_r');
|
|
|
|
|
break;
|
|
|
|
|
case 'Serial':
|
|
|
|
|
orderedFieldIds.push('exch_serial_s');
|
|
|
|
|
orderedFieldIds.push('rst_rcvd');
|
|
|
|
|
orderedFieldIds.push('exch_serial_r');
|
|
|
|
|
break;
|
|
|
|
|
case 'Serialexchange':
|
|
|
|
|
orderedFieldIds.push('exch_serial_s');
|
|
|
|
|
orderedFieldIds.push('exch_sent');
|
|
|
|
|
orderedFieldIds.push('rst_rcvd');
|
|
|
|
|
orderedFieldIds.push('exch_serial_r');
|
|
|
|
|
orderedFieldIds.push('exch_rcvd');
|
|
|
|
|
break;
|
|
|
|
|
case 'Serialgridsquare':
|
|
|
|
|
orderedFieldIds.push('exch_serial_s');
|
|
|
|
|
orderedFieldIds.push('rst_rcvd');
|
|
|
|
|
orderedFieldIds.push('exch_serial_r');
|
|
|
|
|
orderedFieldIds.push('exch_gridsquare_r');
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
orderedFieldIds.push('rst_rcvd');
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
orderedFieldIds.push('name');
|
|
|
|
|
orderedFieldIds.push('comment');
|
|
|
|
|
orderedFieldIds.push('save_qso');
|
|
|
|
|
|
|
|
|
|
$('#qso_input').find('input, select, button, textarea').attr('tabindex', '-1');
|
|
|
|
|
|
|
|
|
|
var tabindex = 1;
|
|
|
|
|
orderedFieldIds.forEach(function (id) {
|
|
|
|
|
var $field = $('#' + id);
|
|
|
|
|
if ($field.length === 0 || $field.is(':disabled')) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$field.is(':visible')) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$field.attr('tabindex', tabindex);
|
|
|
|
|
tabindex += 1;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 14:13:35 +00:00
|
|
|
function calculateCallsignBearingDistance(callsign) {
|
|
|
|
|
if (!callsign || callsign.length < 3) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only proceed if we have a home gridsquare
|
|
|
|
|
if (!my_gridsquare || my_gridsquare.length < 4) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look up the callsign's QRA and get bearing/distance
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/logbook/contest_callsign_qra',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: {
|
|
|
|
|
callsign: callsign,
|
|
|
|
|
my_grid: my_gridsquare
|
|
|
|
|
},
|
|
|
|
|
success: function(data) {
|
|
|
|
|
if (data && (data.bearing !== '' || data.distance > 0)) {
|
|
|
|
|
var unit = (measurement_base === 'M' ? ' mi' : measurement_base === 'N' ? ' nmi' : ' km');
|
|
|
|
|
|
|
|
|
|
// Display in the always-visible DXCC bearing area
|
|
|
|
|
if (data.bearing !== '' && data.bearing !== undefined) {
|
|
|
|
|
$('#locator_info_contest_dxcc').html(String(data.bearing) + '°');
|
|
|
|
|
$('#locator_info_contest_dxcc').show();
|
|
|
|
|
}
|
|
|
|
|
if (data.distance && data.distance > 0) {
|
|
|
|
|
$('#distance_contest_dxcc').text(parseFloat(data.distance).toFixed(0) + unit);
|
|
|
|
|
$('#distance_contest_dxcc').show();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
error: function(xhr, status, error) {
|
|
|
|
|
console.log("Callsign QRA lookup error: " + error);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function calculateContestBearingDistance() {
|
|
|
|
|
var received_grid = $("#exch_gridsquare_r").val();
|
|
|
|
|
|
|
|
|
|
if (!received_grid || received_grid.length < 4) {
|
|
|
|
|
$('#locator_info_contest').text("");
|
|
|
|
|
$('#distance_contest').val("");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only proceed if we have a home gridsquare
|
|
|
|
|
if (!my_gridsquare || my_gridsquare.length < 4) {
|
|
|
|
|
$('#locator_info_contest').text("No home grid");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Call backend to calculate bearing
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/logbook/contest_bearing',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: {
|
|
|
|
|
grid: received_grid,
|
|
|
|
|
my_grid: my_gridsquare
|
|
|
|
|
},
|
|
|
|
|
success: function(data) {
|
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
|
// Format bearing with degree symbol
|
|
|
|
|
$('#locator_info_contest').html(data.trim() + '°');
|
|
|
|
|
} else {
|
|
|
|
|
$('#locator_info_contest').text("");
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
error: function(xhr, status, error) {
|
|
|
|
|
console.log("Bearing error: " + error);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Call backend to calculate distance
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/logbook/contest_distance',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: {
|
|
|
|
|
grid: received_grid,
|
|
|
|
|
my_grid: my_gridsquare
|
|
|
|
|
},
|
|
|
|
|
success: function(data) {
|
|
|
|
|
if (data && data.length > 0 && !isNaN(data)) {
|
|
|
|
|
// Format distance with unit based on user preference
|
|
|
|
|
var distance_value = parseFloat(data).toFixed(2);
|
|
|
|
|
var unit = ' km'; // Default
|
|
|
|
|
|
|
|
|
|
if (measurement_base === 'M') {
|
|
|
|
|
unit = ' mi';
|
|
|
|
|
} else if (measurement_base === 'N') {
|
|
|
|
|
unit = ' nmi';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$('#distance_contest').val(distance_value + unit);
|
|
|
|
|
} else {
|
|
|
|
|
$('#distance_contest').val("");
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
error: function(xhr, status, error) {
|
|
|
|
|
console.log("Distance error: " + error);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
// Resets the logging form and deletes session from database
|
2020-12-28 19:55:51 +01:00
|
|
|
function reset_contest_session() {
|
2021-10-11 18:54:48 +02:00
|
|
|
$('#name').val("");
|
|
|
|
|
$('.callsign-suggestions').text("");
|
|
|
|
|
$('#callsign').val("");
|
|
|
|
|
$('#comment').val("");
|
2021-08-12 19:37:16 +02:00
|
|
|
|
|
|
|
|
$("#exch_serial_s").val("1");
|
|
|
|
|
$("#exch_serial_r").val("");
|
2021-10-11 18:54:48 +02:00
|
|
|
$('#exch_sent').val("");
|
2022-11-08 23:57:39 +01:00
|
|
|
$('#exch_rcvd').val("");
|
2021-08-12 19:37:16 +02:00
|
|
|
$("#exch_gridsquare_r").val("");
|
2026-03-24 14:13:35 +00:00
|
|
|
$('#locator_info_contest').text("");
|
|
|
|
|
$('#distance_contest').val("");
|
|
|
|
|
$('#locator_info_contest_dxcc').text("");
|
|
|
|
|
$('#distance_contest_dxcc').text("");
|
|
|
|
|
$('#locator_info_contest_dxcc').hide();
|
|
|
|
|
$('#distance_contest_dxcc').hide();
|
2021-08-12 19:37:16 +02:00
|
|
|
|
2021-10-11 18:54:48 +02:00
|
|
|
$("#callsign").focus();
|
|
|
|
|
setRst($("#mode").val());
|
2021-08-12 19:37:16 +02:00
|
|
|
$("#exchangetype").val("None");
|
2021-10-11 18:54:48 +02:00
|
|
|
setExchangetype("None");
|
|
|
|
|
$("#contestname").val("Other").change();
|
|
|
|
|
$(".contest_qso_table_contents").empty();
|
2024-03-27 11:31:39 +01:00
|
|
|
$('#copyexchangeto').val("None");
|
2020-12-29 16:29:43 +00:00
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/contesting/deleteSession',
|
|
|
|
|
type: 'post',
|
|
|
|
|
success: function (data) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-12-27 09:37:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Storing the contestid in contest session
|
2024-03-27 11:31:39 +01:00
|
|
|
$('#contestname, #copyexchangeto').change(function () {
|
2023-04-10 18:54:24 +02:00
|
|
|
var formdata = new FormData(document.getElementById("qso_input"));
|
|
|
|
|
setSession(formdata);
|
2020-12-27 09:37:48 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Storing the exchange type in contest session
|
2021-10-11 18:54:48 +02:00
|
|
|
$('#exchangetype').change(function () {
|
2023-04-10 18:54:24 +02:00
|
|
|
var exchangetype = $("#exchangetype").val();
|
|
|
|
|
var formdata = new FormData(document.getElementById("qso_input"));
|
|
|
|
|
setSession(formdata);
|
|
|
|
|
setExchangetype(exchangetype);
|
2026-03-24 16:07:44 +00:00
|
|
|
setContestingTabOrder(exchangetype);
|
2020-12-27 09:37:48 +01:00
|
|
|
});
|
|
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
function setSession(formdata) {
|
2024-03-27 11:31:39 +01:00
|
|
|
formdata.set('copyexchangeto',$("#copyexchangeto option:selected").index());
|
Add Cabrillo export modal & format improvements
Add a full Cabrillo export workflow and harden Cabrillo/QSO formatting. Introduces a modal UI to export contest logs (new button + modal form with fields for location, category time, operators, club, soapbox, date range and other Cabrillo categories). Controller updates pass the new fields to the export action. Cabrilloformat library extended to accept and emit LOCATION and CATEGORY-TIME, improve header field ordering and presence checks, map ADIF modes to the five Cabrillo modes (CW/PH/FM/RY/DG), fix a band label (2.4G -> 2.3G), and emit placeholders for missing received exchanges to preserve column alignment. Contesting_model: more robust date parsing with UTC fallback, ensure session QSO marker only persists when timestamp valid, and build start timestamp when LIVE mode omits start_date/start_time. Frontend JS: setSession() now returns the ajax promise so callers can await it; several callers updated to await setSession and re-fetch session data before refreshing the QSO table; restore full table search on callsign blur and when suggestions are cleared. Misc: small form/input fixes (club field type, default overlay option) and additional server-supplied data loaded into the contesting view (active station id, contest session, station profile). These changes add required Cabrillo fields for certain contests and make exports and session handling more reliable.
2026-03-27 00:04:21 +00:00
|
|
|
return $.ajax({
|
2023-04-10 18:54:24 +02:00
|
|
|
url: base_url + 'index.php/contesting/setSession',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: formdata,
|
|
|
|
|
processData: false,
|
|
|
|
|
contentType: false,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-07 21:26:16 +01:00
|
|
|
// realtime clock
|
2024-01-14 18:04:35 +00:00
|
|
|
if (!manual) {
|
2022-03-27 17:33:05 +02:00
|
|
|
$(function ($) {
|
2024-01-14 18:04:35 +00:00
|
|
|
handleStart = setInterval(function () { getUTCTimeStamp($('.input_time')); }, 500);
|
2022-03-27 17:33:05 +02:00
|
|
|
});
|
2020-12-07 21:26:16 +01:00
|
|
|
|
2022-03-27 17:33:05 +02:00
|
|
|
$(function ($) {
|
2024-01-14 18:04:35 +00:00
|
|
|
handleDate = setInterval(function () { getUTCDateStamp($('.input_date')); }, 1000);
|
2022-03-27 17:33:05 +02:00
|
|
|
});
|
|
|
|
|
}
|
2020-12-07 21:26:16 +01:00
|
|
|
|
|
|
|
|
// We don't want spaces to be written in callsign
|
|
|
|
|
// We don't want spaces to be written in exchange
|
2024-03-27 11:29:58 +01:00
|
|
|
// We don't want spaces to be written in time :)
|
2021-10-11 18:54:48 +02:00
|
|
|
$(function () {
|
2024-03-27 11:29:58 +01:00
|
|
|
$('#callsign, #exch_rcvd, #start_time').on('keypress', function (e) {
|
2021-10-11 18:54:48 +02:00
|
|
|
if (e.which == 32) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-12-07 21:26:16 +01:00
|
|
|
});
|
|
|
|
|
|
2024-03-23 17:33:32 +01:00
|
|
|
// We don't want anything but numbers to be written in serial
|
2023-04-05 14:52:05 +02:00
|
|
|
$(function () {
|
2024-03-23 17:33:32 +01:00
|
|
|
$('#exch_serial_r, #exch_serial_s').on('keypress', function (e) {
|
|
|
|
|
if (e.key.charCodeAt(0) < 48 || e.key.charCodeAt(0) > 57) {
|
2023-04-05 14:52:05 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2024-03-08 12:41:12 +00:00
|
|
|
// checked if worked before after blur
|
|
|
|
|
$("#callsign").blur(function () {
|
Add Cabrillo export modal & format improvements
Add a full Cabrillo export workflow and harden Cabrillo/QSO formatting. Introduces a modal UI to export contest logs (new button + modal form with fields for location, category time, operators, club, soapbox, date range and other Cabrillo categories). Controller updates pass the new fields to the export action. Cabrilloformat library extended to accept and emit LOCATION and CATEGORY-TIME, improve header field ordering and presence checks, map ADIF modes to the five Cabrillo modes (CW/PH/FM/RY/DG), fix a band label (2.4G -> 2.3G), and emit placeholders for missing received exchanges to preserve column alignment. Contesting_model: more robust date parsing with UTC fallback, ensure session QSO marker only persists when timestamp valid, and build start timestamp when LIVE mode omits start_date/start_time. Frontend JS: setSession() now returns the ajax promise so callers can await it; several callers updated to await setSession and re-fetch session data before refreshing the QSO table; restore full table search on callsign blur and when suggestions are cleared. Misc: small form/input fixes (club field type, default overlay option) and additional server-supplied data loaded into the contesting view (active station id, contest session, station profile). These changes add required Cabrillo fields for certain contests and make exports and session handling more reliable.
2026-03-27 00:04:21 +00:00
|
|
|
checkIfWorkedBefore();
|
|
|
|
|
// Restore full logbook table once user moves away from callsign field
|
|
|
|
|
if ($.fn.DataTable.isDataTable('.qsotable')) {
|
|
|
|
|
$('.qsotable').DataTable().search('').draw();
|
|
|
|
|
}
|
2024-03-08 12:41:12 +00:00
|
|
|
});
|
|
|
|
|
|
2021-08-12 19:37:16 +02:00
|
|
|
// Here we capture keystrokes to execute functions
|
2021-10-11 18:54:48 +02:00
|
|
|
document.onkeyup = function (e) {
|
|
|
|
|
// ALT-W wipe
|
|
|
|
|
if (e.altKey && e.which == 87) {
|
|
|
|
|
reset_log_fields();
|
|
|
|
|
// CTRL-Enter logs QSO
|
|
|
|
|
} else if ((e.keyCode == 10 || e.keyCode == 13) && (e.ctrlKey || e.metaKey)) {
|
|
|
|
|
logQso();
|
2023-04-01 21:20:03 +02:00
|
|
|
// Enter in received exchange logs QSO
|
|
|
|
|
} else if ((e.which == 13) && (
|
2024-01-14 18:04:35 +00:00
|
|
|
($(document.activeElement).attr("id") == "exch_rcvd")
|
|
|
|
|
|| ($(document.activeElement).attr("id") == "exch_gridsquare_r")
|
|
|
|
|
|| ($(document.activeElement).attr("id") == "exch_serial_r")
|
|
|
|
|
)
|
2023-04-01 21:20:03 +02:00
|
|
|
) {
|
2021-10-11 18:54:48 +02:00
|
|
|
logQso();
|
|
|
|
|
} else if (e.which == 27) {
|
|
|
|
|
reset_log_fields();
|
|
|
|
|
// Space to jump to either callsign or the various exchanges
|
|
|
|
|
} else if (e.which == 32) {
|
2021-08-13 12:47:17 +02:00
|
|
|
var exchangetype = $("#exchangetype").val();
|
2024-03-27 11:29:58 +01:00
|
|
|
|
|
|
|
|
if (manual && $(document.activeElement).attr("id") == "start_time") {
|
|
|
|
|
$("#callsign").focus();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-11 18:54:48 +02:00
|
|
|
if (exchangetype == 'Exchange') {
|
2021-08-13 12:47:17 +02:00
|
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
2022-11-08 23:57:39 +01:00
|
|
|
$("#exch_rcvd").focus();
|
2021-08-13 12:47:17 +02:00
|
|
|
return false;
|
2022-11-08 23:57:39 +01:00
|
|
|
} else if ($(document.activeElement).attr("id") == "exch_rcvd") {
|
2021-08-13 12:47:17 +02:00
|
|
|
$("#callsign").focus();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (exchangetype == 'Serial') {
|
|
|
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
|
|
|
$("#exch_serial_r").focus();
|
|
|
|
|
return false;
|
|
|
|
|
} else if ($(document.activeElement).attr("id") == "exch_serial_r") {
|
|
|
|
|
$("#callsign").focus();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (exchangetype == 'Serialexchange') {
|
|
|
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
|
|
|
$("#exch_serial_r").focus();
|
|
|
|
|
return false;
|
|
|
|
|
} else if ($(document.activeElement).attr("id") == "exch_serial_r") {
|
2022-11-08 23:57:39 +01:00
|
|
|
$("#exch_rcvd").focus();
|
2021-08-13 12:47:17 +02:00
|
|
|
return false;
|
2022-11-08 23:57:39 +01:00
|
|
|
} else if ($(document.activeElement).attr("id") == "exch_rcvd") {
|
2021-08-13 12:47:17 +02:00
|
|
|
$("#callsign").focus();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (exchangetype == 'Serialgridsquare') {
|
|
|
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
|
|
|
$("#exch_serial_r").focus();
|
|
|
|
|
return false;
|
|
|
|
|
} else if ($(document.activeElement).attr("id") == "exch_serial_r") {
|
|
|
|
|
$("#exch_gridsquare_r").focus();
|
|
|
|
|
return false;
|
|
|
|
|
} else if ($(document.activeElement).attr("id") == "exch_gridsquare_r") {
|
|
|
|
|
$("#callsign").focus();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (exchangetype == 'Gridsquare') {
|
|
|
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
|
|
|
$("#exch_gridsquare_r").focus();
|
|
|
|
|
return false;
|
|
|
|
|
} else if ($(document.activeElement).attr("id") == "exch_gridsquare_r") {
|
|
|
|
|
$("#callsign").focus();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-11 18:54:48 +02:00
|
|
|
}
|
2020-12-07 21:26:16 +01:00
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2022-09-25 12:32:39 +02:00
|
|
|
/* time input shortcut */
|
2024-01-14 18:04:35 +00:00
|
|
|
$('#start_time').change(function () {
|
2022-09-25 12:32:39 +02:00
|
|
|
var raw_time = $(this).val();
|
2024-01-14 18:04:35 +00:00
|
|
|
if (raw_time.match(/^\d\[0-6]d$/)) {
|
|
|
|
|
raw_time = "0" + raw_time;
|
2022-09-25 12:32:39 +02:00
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
if (raw_time.match(/^[012]\d[0-5]\d$/)) {
|
|
|
|
|
raw_time = raw_time.substring(0, 2) + ":" + raw_time.substring(2, 4);
|
2022-09-25 12:32:39 +02:00
|
|
|
$('#start_time').val(raw_time);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/* date input shortcut */
|
2024-01-14 18:04:35 +00:00
|
|
|
$('#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);
|
2022-09-25 12:32:39 +02:00
|
|
|
$('#start_date').val(raw_date);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-07 21:26:16 +01:00
|
|
|
// On Key up check and suggest callsigns
|
2026-03-27 16:10:39 +00:00
|
|
|
var dupeCheckTimer = null;
|
2021-10-11 18:54:48 +02:00
|
|
|
$("#callsign").keyup(function () {
|
|
|
|
|
var call = $(this).val();
|
|
|
|
|
if (call.length >= 3) {
|
2023-07-08 13:38:28 +01:00
|
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: 'lookup/scp',
|
|
|
|
|
method: 'POST',
|
|
|
|
|
data: {
|
2024-01-14 18:04:35 +00:00
|
|
|
callsign: $(this).val().toUpperCase()
|
2023-07-08 13:38:28 +01:00
|
|
|
},
|
2024-01-14 18:04:35 +00:00
|
|
|
success: function (result) {
|
2026-03-27 16:10:39 +00:00
|
|
|
if (result && result.trim() !== '') {
|
|
|
|
|
$('.callsign-suggestions').text(result);
|
|
|
|
|
highlight(call.toUpperCase());
|
|
|
|
|
$('.callsign-suggest').show();
|
|
|
|
|
} else {
|
|
|
|
|
$('.callsign-suggestions').text('');
|
|
|
|
|
$('.callsign-suggest').hide();
|
|
|
|
|
}
|
2023-07-08 13:38:28 +01:00
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
});
|
2026-03-27 16:10:39 +00:00
|
|
|
// Debounced dupe check while typing
|
|
|
|
|
clearTimeout(dupeCheckTimer);
|
|
|
|
|
dupeCheckTimer = setTimeout(function() { checkIfWorkedBefore(); }, 400);
|
2022-10-30 08:02:32 +01:00
|
|
|
var qTable = $('.qsotable').DataTable();
|
|
|
|
|
qTable.search(call).draw();
|
2026-03-24 22:36:54 +00:00
|
|
|
lookupCallhistory(call.toUpperCase());
|
2021-10-11 18:54:48 +02:00
|
|
|
}
|
|
|
|
|
else if (call.length <= 2) {
|
|
|
|
|
$('.callsign-suggestions').text("");
|
2026-03-27 16:10:39 +00:00
|
|
|
$('.callsign-suggest').hide();
|
|
|
|
|
$('#callsign').css({'border-color': '', 'box-shadow': ''});
|
|
|
|
|
$('#callsign_info').text("").removeClass('text-bg-danger text-bg-success');
|
2026-03-24 22:36:54 +00:00
|
|
|
renderCallhistoryPanel([]);
|
Add Cabrillo export modal & format improvements
Add a full Cabrillo export workflow and harden Cabrillo/QSO formatting. Introduces a modal UI to export contest logs (new button + modal form with fields for location, category time, operators, club, soapbox, date range and other Cabrillo categories). Controller updates pass the new fields to the export action. Cabrilloformat library extended to accept and emit LOCATION and CATEGORY-TIME, improve header field ordering and presence checks, map ADIF modes to the five Cabrillo modes (CW/PH/FM/RY/DG), fix a band label (2.4G -> 2.3G), and emit placeholders for missing received exchanges to preserve column alignment. Contesting_model: more robust date parsing with UTC fallback, ensure session QSO marker only persists when timestamp valid, and build start timestamp when LIVE mode omits start_date/start_time. Frontend JS: setSession() now returns the ajax promise so callers can await it; several callers updated to await setSession and re-fetch session data before refreshing the QSO table; restore full table search on callsign blur and when suggestions are cleared. Misc: small form/input fixes (club field type, default overlay option) and additional server-supplied data loaded into the contesting view (active station id, contest session, station profile). These changes add required Cabrillo fields for certain contests and make exports and session handling more reliable.
2026-03-27 00:04:21 +00:00
|
|
|
if ($.fn.DataTable.isDataTable('.qsotable')) {
|
|
|
|
|
$('.qsotable').DataTable().search('').draw();
|
|
|
|
|
}
|
2021-10-11 18:54:48 +02:00
|
|
|
}
|
2020-12-07 21:26:16 +01:00
|
|
|
});
|
|
|
|
|
|
2021-10-24 16:48:23 +02:00
|
|
|
function checkIfWorkedBefore() {
|
2023-04-10 18:54:24 +02:00
|
|
|
var call = $("#callsign").val();
|
|
|
|
|
if (call.length >= 3) {
|
|
|
|
|
$('#callsign_info').text("");
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/contesting/checkIfWorkedBefore',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: {
|
|
|
|
|
'call': call,
|
|
|
|
|
'mode': $("#mode").val(),
|
|
|
|
|
'band': $("#band").val(),
|
|
|
|
|
'contest': $("#contestname").val()
|
|
|
|
|
},
|
|
|
|
|
success: function (result) {
|
2024-01-14 18:04:35 +00:00
|
|
|
if (result.message.substr(0, 6) == 'Worked') {
|
2024-03-08 12:41:12 +00:00
|
|
|
$('#callsign_info').removeClass('text-bg-success');
|
|
|
|
|
$('#callsign_info').addClass('text-bg-danger');
|
2023-12-30 20:17:43 +00:00
|
|
|
$('#callsign_info').text(result.message);
|
2026-03-27 16:10:39 +00:00
|
|
|
$('#callsign').css({'border-color': '#dc3545', 'box-shadow': '0 0 0 0.2rem rgba(220,53,69,.25)'});
|
2023-04-10 18:54:24 +02:00
|
|
|
}
|
2024-03-08 12:41:12 +00:00
|
|
|
else if (result.message == "OKAY") {
|
|
|
|
|
$('#callsign_info').removeClass('text-bg-danger');
|
|
|
|
|
$('#callsign_info').addClass('text-bg-success');
|
|
|
|
|
$('#callsign_info').text("Go Work Them!");
|
2026-03-27 16:10:39 +00:00
|
|
|
$('#callsign').css({'border-color': '#198754', 'box-shadow': '0 0 0 0.2rem rgba(25,135,84,.25)'});
|
2024-03-08 12:41:12 +00:00
|
|
|
} else {
|
|
|
|
|
$('#callsign_info').text("");
|
2026-03-27 16:10:39 +00:00
|
|
|
$('#callsign').css({'border-color': '', 'box-shadow': ''});
|
2024-03-08 12:41:12 +00:00
|
|
|
}
|
2021-10-24 16:48:23 +02:00
|
|
|
}
|
2023-04-10 18:54:24 +02:00
|
|
|
});
|
2026-03-24 14:13:35 +00:00
|
|
|
|
|
|
|
|
// If gridsquare field is empty, try to get it from callsign lookup
|
|
|
|
|
if ($("#exch_gridsquare_r").val().length === 0) {
|
|
|
|
|
calculateCallsignBearingDistance(call);
|
|
|
|
|
}
|
2024-03-08 12:41:12 +00:00
|
|
|
} else {
|
2026-03-27 16:10:39 +00:00
|
|
|
$('#callsign_info').text("").removeClass('text-bg-danger text-bg-success');
|
|
|
|
|
$('#callsign').css({'border-color': '', 'box-shadow': ''});
|
2023-04-10 18:54:24 +02:00
|
|
|
}
|
2021-10-24 16:48:23 +02:00
|
|
|
}
|
|
|
|
|
|
2023-10-02 11:46:01 +00:00
|
|
|
async function reset_log_fields() {
|
2021-10-11 18:54:48 +02:00
|
|
|
$('#name').val("");
|
|
|
|
|
$('.callsign-suggestions').text("");
|
2026-03-27 16:10:39 +00:00
|
|
|
$('.callsign-suggest').hide();
|
|
|
|
|
$('#callsign').val("").css({'border-color': '', 'box-shadow': ''});
|
2021-10-11 18:54:48 +02:00
|
|
|
$('#comment').val("");
|
2022-11-08 23:57:39 +01:00
|
|
|
$('#exch_rcvd').val("");
|
2021-08-12 19:37:16 +02:00
|
|
|
$('#exch_serial_r').val("");
|
|
|
|
|
$('#exch_gridsquare_r').val("");
|
2026-03-24 14:13:35 +00:00
|
|
|
$('#locator_info_contest').text("");
|
|
|
|
|
$('#distance_contest').val("");
|
|
|
|
|
$('#locator_info_contest_dxcc').text("");
|
|
|
|
|
$('#distance_contest_dxcc').text("");
|
|
|
|
|
$('#locator_info_contest_dxcc').hide();
|
|
|
|
|
$('#distance_contest_dxcc').hide();
|
2021-10-11 18:54:48 +02:00
|
|
|
$("#callsign").focus();
|
|
|
|
|
setRst($("#mode").val());
|
2026-03-27 16:10:39 +00:00
|
|
|
$('#callsign_info').text("").removeClass('text-bg-danger text-bg-success');
|
2026-03-24 22:36:54 +00:00
|
|
|
renderCallhistoryPanel([]);
|
2022-10-30 08:02:32 +01:00
|
|
|
|
Add Cabrillo export modal & format improvements
Add a full Cabrillo export workflow and harden Cabrillo/QSO formatting. Introduces a modal UI to export contest logs (new button + modal form with fields for location, category time, operators, club, soapbox, date range and other Cabrillo categories). Controller updates pass the new fields to the export action. Cabrilloformat library extended to accept and emit LOCATION and CATEGORY-TIME, improve header field ordering and presence checks, map ADIF modes to the five Cabrillo modes (CW/PH/FM/RY/DG), fix a band label (2.4G -> 2.3G), and emit placeholders for missing received exchanges to preserve column alignment. Contesting_model: more robust date parsing with UTC fallback, ensure session QSO marker only persists when timestamp valid, and build start timestamp when LIVE mode omits start_date/start_time. Frontend JS: setSession() now returns the ajax promise so callers can await it; several callers updated to await setSession and re-fetch session data before refreshing the QSO table; restore full table search on callsign blur and when suggestions are cleared. Misc: small form/input fixes (club field type, default overlay option) and additional server-supplied data loaded into the contesting view (active station id, contest session, station profile). These changes add required Cabrillo fields for certain contests and make exports and session handling more reliable.
2026-03-27 00:04:21 +00:00
|
|
|
sessiondata = await getSession();
|
2023-10-02 11:46:01 +00:00
|
|
|
await refresh_qso_table(sessiondata);
|
2022-10-30 08:02:32 +01:00
|
|
|
var qTable = $('.qsotable').DataTable();
|
|
|
|
|
qTable.search('').draw();
|
2020-12-07 21:26:16 +01:00
|
|
|
}
|
|
|
|
|
|
2021-10-11 18:54:48 +02:00
|
|
|
RegExp.escape = function (text) {
|
|
|
|
|
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
2020-12-07 21:26:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function highlight(term, base) {
|
2021-10-11 18:54:48 +02:00
|
|
|
if (!term) return;
|
|
|
|
|
base = base || document.body;
|
|
|
|
|
var re = new RegExp("(" + RegExp.escape(term) + ")", "gi");
|
|
|
|
|
var replacement = "<span class=\"text-primary\">" + term + "</span>";
|
|
|
|
|
$(".callsign-suggestions", base).contents().each(function (i, el) {
|
|
|
|
|
if (el.nodeType === 3) {
|
|
|
|
|
var data = el.data;
|
|
|
|
|
if (data = data.replace(re, replacement)) {
|
|
|
|
|
var wrapper = $("<span>").html(data);
|
|
|
|
|
$(el).before(wrapper.contents()).remove();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-12-07 21:26:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Only set the frequency when not set by userdata/PHP.
|
2021-10-11 18:54:48 +02:00
|
|
|
if ($('#frequency').val() == "") {
|
|
|
|
|
$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
|
|
|
|
|
$('#frequency').val(result);
|
|
|
|
|
$('#frequency_rx').val("");
|
|
|
|
|
});
|
2020-12-07 21:26:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* on mode change */
|
2021-10-11 18:54:48 +02:00
|
|
|
$('#mode').change(function () {
|
|
|
|
|
$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
|
|
|
|
|
$('#frequency').val(result);
|
|
|
|
|
$('#frequency_rx').val("");
|
|
|
|
|
});
|
2021-08-12 19:37:16 +02:00
|
|
|
setRst($("#mode").val());
|
2021-10-24 16:48:23 +02:00
|
|
|
checkIfWorkedBefore();
|
2020-12-07 21:26:16 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/* Calculate Frequency */
|
|
|
|
|
/* on band change */
|
2021-10-11 18:54:48 +02:00
|
|
|
$('#band').change(function () {
|
|
|
|
|
$.get('qso/band_to_freq/' + $(this).val() + '/' + $('.mode').val(), function (result) {
|
|
|
|
|
$('#frequency').val(result);
|
|
|
|
|
$('#frequency_rx').val("");
|
|
|
|
|
});
|
2021-10-24 16:48:23 +02:00
|
|
|
checkIfWorkedBefore();
|
2021-03-14 11:44:42 +00:00
|
|
|
});
|
|
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
function setSerial(data) {
|
|
|
|
|
var serialsent = 1;
|
|
|
|
|
if (data.serialsent != "") {
|
2023-04-29 10:17:07 +02:00
|
|
|
serialsent = parseInt(data.serialsent);
|
2023-04-10 18:54:24 +02:00
|
|
|
}
|
|
|
|
|
$("#exch_serial_s").val(serialsent);
|
|
|
|
|
}
|
2021-08-12 11:52:36 +02:00
|
|
|
|
|
|
|
|
function setExchangetype(exchangetype) {
|
2021-10-12 13:10:54 +02:00
|
|
|
// Perhaps a better approach is to hide everything, then just enable the things you need
|
|
|
|
|
$(".exchanger").hide();
|
|
|
|
|
$(".exchanges").hide();
|
|
|
|
|
$(".serials").hide();
|
|
|
|
|
$(".serialr").hide();
|
|
|
|
|
$(".gridsquarer").hide();
|
|
|
|
|
$(".gridsquares").hide();
|
|
|
|
|
|
|
|
|
|
if (exchangetype == 'Exchange') {
|
2021-08-12 11:52:36 +02:00
|
|
|
$(".exchanger").show();
|
|
|
|
|
$(".exchanges").show();
|
|
|
|
|
}
|
|
|
|
|
else if (exchangetype == 'Serial') {
|
2021-10-12 13:10:54 +02:00
|
|
|
$(".serials").show();
|
|
|
|
|
$(".serialr").show();
|
|
|
|
|
}
|
2021-08-12 11:52:36 +02:00
|
|
|
else if (exchangetype == 'Serialexchange') {
|
2021-08-10 22:32:15 +02:00
|
|
|
$(".exchanger").show();
|
|
|
|
|
$(".exchanges").show();
|
|
|
|
|
$(".serials").show();
|
|
|
|
|
$(".serialr").show();
|
2021-08-07 10:13:38 +02:00
|
|
|
}
|
2021-08-12 11:52:36 +02:00
|
|
|
else if (exchangetype == 'Serialgridsquare') {
|
2021-08-10 22:32:15 +02:00
|
|
|
$(".serials").show();
|
|
|
|
|
$(".serialr").show();
|
|
|
|
|
$(".gridsquarer").show();
|
|
|
|
|
$(".gridsquares").show();
|
2021-08-07 10:13:38 +02:00
|
|
|
}
|
2021-08-12 11:52:36 +02:00
|
|
|
else if (exchangetype == 'Gridsquare') {
|
2021-08-10 22:32:15 +02:00
|
|
|
$(".gridsquarer").show();
|
|
|
|
|
$(".gridsquares").show();
|
2021-08-07 10:13:38 +02:00
|
|
|
}
|
2026-03-24 16:07:44 +00:00
|
|
|
|
|
|
|
|
setContestingTabOrder(exchangetype);
|
2026-03-27 16:10:39 +00:00
|
|
|
updateTableColumns(exchangetype);
|
2021-08-12 11:52:36 +02:00
|
|
|
}
|
2021-08-07 10:13:38 +02:00
|
|
|
|
2021-08-11 08:54:24 +02:00
|
|
|
/*
|
|
|
|
|
Function: logQso
|
|
|
|
|
Job: this handles the logging done in the contesting module.
|
|
|
|
|
*/
|
|
|
|
|
function logQso() {
|
|
|
|
|
if ($("#callsign").val().length > 0) {
|
|
|
|
|
|
|
|
|
|
$('.callsign-suggestions').text("");
|
|
|
|
|
|
|
|
|
|
var table = $('.qsotable').DataTable();
|
2023-04-06 19:28:16 +02:00
|
|
|
var exchangetype = $("#exchangetype").val();
|
|
|
|
|
|
2021-08-13 12:47:17 +02:00
|
|
|
var gridsquare = $("#exch_gridsquare_r").val();
|
|
|
|
|
var vucc = '';
|
2021-08-11 08:54:24 +02:00
|
|
|
|
2021-08-13 12:47:17 +02:00
|
|
|
if (gridsquare.indexOf(',') != -1) {
|
|
|
|
|
vucc = gridsquare;
|
|
|
|
|
gridsquare = '';
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 19:28:16 +02:00
|
|
|
var gridr = '';
|
|
|
|
|
var vuccr = '';
|
|
|
|
|
var exchsent = '';
|
|
|
|
|
var exchrcvd = '';
|
|
|
|
|
var serials = '';
|
|
|
|
|
var serialr = '';
|
|
|
|
|
|
|
|
|
|
switch (exchangetype) {
|
|
|
|
|
case 'Exchange':
|
|
|
|
|
exchsent = $("#exch_sent").val();
|
|
|
|
|
exchrcvd = $("#exch_rcvd").val();
|
2024-01-14 18:04:35 +00:00
|
|
|
break;
|
2023-04-06 19:28:16 +02:00
|
|
|
|
|
|
|
|
case 'Gridsquare':
|
|
|
|
|
gridr = gridsquare;
|
|
|
|
|
vuccr = vucc;
|
2024-01-14 18:04:35 +00:00
|
|
|
break;
|
2023-04-06 19:28:16 +02:00
|
|
|
|
|
|
|
|
case 'Serial':
|
|
|
|
|
serials = $("#exch_serial_s").val();
|
|
|
|
|
serialr = $("#exch_serial_r").val();
|
2024-01-14 18:04:35 +00:00
|
|
|
break;
|
|
|
|
|
|
2023-04-06 19:28:16 +02:00
|
|
|
case 'Serialexchange':
|
|
|
|
|
exchsent = $("#exch_sent").val();
|
|
|
|
|
exchrcvd = $("#exch_rcvd").val();
|
|
|
|
|
serials = $("#exch_serial_s").val();
|
|
|
|
|
serialr = $("#exch_serial_r").val();
|
2024-01-14 18:04:35 +00:00
|
|
|
break;
|
|
|
|
|
|
2023-04-06 19:28:16 +02:00
|
|
|
case 'Serialgridsquare':
|
|
|
|
|
gridr = gridsquare;
|
|
|
|
|
vuccr = vucc;
|
|
|
|
|
serials = $("#exch_serial_s").val();
|
|
|
|
|
serialr = $("#exch_serial_r").val();
|
2024-01-14 18:04:35 +00:00
|
|
|
break;
|
2023-04-06 19:28:16 +02:00
|
|
|
}
|
|
|
|
|
|
2021-08-13 12:47:17 +02:00
|
|
|
var data = [[
|
2021-10-11 18:54:48 +02:00
|
|
|
$("#start_date").val() + ' ' + $("#start_time").val(),
|
2025-04-12 14:09:04 +01:00
|
|
|
$("#callsign").val($("#callsign").val().replace(/\s+/g, '').toUpperCase()),
|
2021-08-11 08:54:24 +02:00
|
|
|
$("#band").val(),
|
|
|
|
|
$("#mode").val(),
|
|
|
|
|
$("#rst_sent").val(),
|
2022-11-08 23:57:39 +01:00
|
|
|
$("#rst_rcvd").val(),
|
2023-04-06 19:28:16 +02:00
|
|
|
exchsent,
|
|
|
|
|
exchrcvd,
|
|
|
|
|
serials,
|
|
|
|
|
serialr,
|
|
|
|
|
gridr,
|
|
|
|
|
vuccr,
|
2021-08-13 12:47:17 +02:00
|
|
|
]];
|
2021-08-11 08:54:24 +02:00
|
|
|
|
|
|
|
|
var formdata = new FormData(document.getElementById("qso_input"));
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/qso/saveqso',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: formdata,
|
|
|
|
|
processData: false,
|
|
|
|
|
contentType: false,
|
|
|
|
|
enctype: 'multipart/form-data',
|
2023-08-06 07:05:33 +00:00
|
|
|
success: async function (html) {
|
2023-04-29 10:17:07 +02:00
|
|
|
var exchangetype = $("#exchangetype").val();
|
|
|
|
|
if (exchangetype == "Serial" || exchangetype == 'Serialexchange' || exchangetype == 'Serialgridsquare') {
|
|
|
|
|
$("#exch_serial_s").val(+$("#exch_serial_s").val() + 1);
|
|
|
|
|
formdata.set('exch_serial_s', $("#exch_serial_s").val());
|
|
|
|
|
}
|
2021-08-11 08:54:24 +02:00
|
|
|
|
2023-04-29 10:17:07 +02:00
|
|
|
$('#name').val("");
|
2024-01-14 18:04:35 +00:00
|
|
|
|
2021-08-11 08:54:24 +02:00
|
|
|
$('#callsign').val("");
|
|
|
|
|
$('#comment').val("");
|
2022-11-08 23:57:39 +01:00
|
|
|
$('#exch_rcvd').val("");
|
2021-08-13 12:47:17 +02:00
|
|
|
$('#exch_gridsquare_r').val("");
|
|
|
|
|
$('#exch_serial_r').val("");
|
Add Cabrillo export modal & format improvements
Add a full Cabrillo export workflow and harden Cabrillo/QSO formatting. Introduces a modal UI to export contest logs (new button + modal form with fields for location, category time, operators, club, soapbox, date range and other Cabrillo categories). Controller updates pass the new fields to the export action. Cabrilloformat library extended to accept and emit LOCATION and CATEGORY-TIME, improve header field ordering and presence checks, map ADIF modes to the five Cabrillo modes (CW/PH/FM/RY/DG), fix a band label (2.4G -> 2.3G), and emit placeholders for missing received exchanges to preserve column alignment. Contesting_model: more robust date parsing with UTC fallback, ensure session QSO marker only persists when timestamp valid, and build start timestamp when LIVE mode omits start_date/start_time. Frontend JS: setSession() now returns the ajax promise so callers can await it; several callers updated to await setSession and re-fetch session data before refreshing the QSO table; restore full table search on callsign blur and when suggestions are cleared. Misc: small form/input fixes (club field type, default overlay option) and additional server-supplied data loaded into the contesting view (active station id, contest session, station profile). These changes add required Cabrillo fields for certain contests and make exports and session handling more reliable.
2026-03-27 00:04:21 +00:00
|
|
|
$('.callsign-suggestions').text("");
|
2026-03-27 16:10:39 +00:00
|
|
|
$('.callsign-suggest').hide();
|
|
|
|
|
$('#callsign').css({'border-color': '', 'box-shadow': ''});
|
|
|
|
|
$('#callsign_info').text("").removeClass('text-bg-danger text-bg-success');
|
Add Cabrillo export modal & format improvements
Add a full Cabrillo export workflow and harden Cabrillo/QSO formatting. Introduces a modal UI to export contest logs (new button + modal form with fields for location, category time, operators, club, soapbox, date range and other Cabrillo categories). Controller updates pass the new fields to the export action. Cabrilloformat library extended to accept and emit LOCATION and CATEGORY-TIME, improve header field ordering and presence checks, map ADIF modes to the five Cabrillo modes (CW/PH/FM/RY/DG), fix a band label (2.4G -> 2.3G), and emit placeholders for missing received exchanges to preserve column alignment. Contesting_model: more robust date parsing with UTC fallback, ensure session QSO marker only persists when timestamp valid, and build start timestamp when LIVE mode omits start_date/start_time. Frontend JS: setSession() now returns the ajax promise so callers can await it; several callers updated to await setSession and re-fetch session data before refreshing the QSO table; restore full table search on callsign blur and when suggestions are cleared. Misc: small form/input fixes (club field type, default overlay option) and additional server-supplied data loaded into the contesting view (active station id, contest session, station profile). These changes add required Cabrillo fields for certain contests and make exports and session handling more reliable.
2026-03-27 00:04:21 +00:00
|
|
|
renderCallhistoryPanel([]);
|
2024-03-27 11:29:58 +01:00
|
|
|
if (manual) {
|
|
|
|
|
$("#start_time").focus().select();
|
|
|
|
|
} else {
|
|
|
|
|
$("#callsign").focus();
|
|
|
|
|
}
|
Add Cabrillo export modal & format improvements
Add a full Cabrillo export workflow and harden Cabrillo/QSO formatting. Introduces a modal UI to export contest logs (new button + modal form with fields for location, category time, operators, club, soapbox, date range and other Cabrillo categories). Controller updates pass the new fields to the export action. Cabrilloformat library extended to accept and emit LOCATION and CATEGORY-TIME, improve header field ordering and presence checks, map ADIF modes to the five Cabrillo modes (CW/PH/FM/RY/DG), fix a band label (2.4G -> 2.3G), and emit placeholders for missing received exchanges to preserve column alignment. Contesting_model: more robust date parsing with UTC fallback, ensure session QSO marker only persists when timestamp valid, and build start timestamp when LIVE mode omits start_date/start_time. Frontend JS: setSession() now returns the ajax promise so callers can await it; several callers updated to await setSession and re-fetch session data before refreshing the QSO table; restore full table search on callsign blur and when suggestions are cleared. Misc: small form/input fixes (club field type, default overlay option) and additional server-supplied data loaded into the contesting view (active station id, contest session, station profile). These changes add required Cabrillo fields for certain contests and make exports and session handling more reliable.
2026-03-27 00:04:21 +00:00
|
|
|
await setSession(formdata);
|
|
|
|
|
|
|
|
|
|
// Re-fetch session so table shows all QSOs from session start, not just last minute
|
|
|
|
|
sessiondata = await getSession();
|
2023-08-06 07:05:33 +00:00
|
|
|
await refresh_qso_table(sessiondata);
|
2023-05-03 12:28:41 +02:00
|
|
|
|
2021-08-11 08:54:24 +02:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-06 07:05:33 +00:00
|
|
|
async function getSession() {
|
|
|
|
|
return await $.ajax({
|
2023-04-10 18:54:24 +02:00
|
|
|
url: base_url + 'index.php/contesting/getSession',
|
|
|
|
|
type: 'post',
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
|
2023-08-06 07:05:33 +00:00
|
|
|
async function restoreContestSession(data) {
|
2023-04-10 18:54:24 +02:00
|
|
|
if (data) {
|
2024-03-27 11:31:39 +01:00
|
|
|
if (data.copytodok != "") {
|
|
|
|
|
$('#copyexchangeto option')[data.copytodok].selected = true;
|
2023-04-10 18:54:24 +02:00
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
if (data.contestid != "") {
|
|
|
|
|
$("#contestname").val(data.contestid);
|
|
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
if (data.exchangetype != "") {
|
|
|
|
|
$("#exchangetype").val(data.exchangetype);
|
|
|
|
|
setExchangetype(data.exchangetype);
|
2023-04-28 15:55:58 +02:00
|
|
|
setSerial(data);
|
2023-04-10 18:54:24 +02:00
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
if (data.exchangesent != "") {
|
|
|
|
|
$("#exch_sent").val(data.exchangesent);
|
|
|
|
|
}
|
2023-04-29 10:17:07 +02:00
|
|
|
|
2023-04-10 18:54:24 +02:00
|
|
|
if (data.qso != "") {
|
2023-08-06 07:05:33 +00:00
|
|
|
await refresh_qso_table(data);
|
2023-04-10 18:54:24 +02:00
|
|
|
}
|
2023-04-29 10:17:07 +02:00
|
|
|
} else {
|
|
|
|
|
$("#exch_serial_s").val("1");
|
2021-08-11 08:54:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-05-27 14:52:55 +02:00
|
|
|
|
2023-08-06 07:05:33 +00:00
|
|
|
async function refresh_qso_table(data) {
|
2024-01-14 18:04:35 +00:00
|
|
|
if (data && data.qso) {
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/contesting/getSessionQsos',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: { 'qso': data.qso, },
|
|
|
|
|
success: function (html) {
|
2026-03-27 16:32:15 +00:00
|
|
|
// Destroy DataTables FIRST so DOM manipulation is clean
|
|
|
|
|
if ($.fn.DataTable.isDataTable('.qsotable')) {
|
|
|
|
|
$('.qsotable').DataTable().destroy();
|
|
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
var mode = '';
|
|
|
|
|
$(".contest_qso_table_contents").empty();
|
2026-03-27 16:10:39 +00:00
|
|
|
var dupeCounts = {};
|
|
|
|
|
$.each(html, function () {
|
|
|
|
|
var key = this.col_call + '|' + this.col_band + '|' + this.col_mode;
|
|
|
|
|
dupeCounts[key] = (dupeCounts[key] || 0) + 1;
|
|
|
|
|
});
|
2024-01-14 18:04:35 +00:00
|
|
|
$.each(html, function () {
|
|
|
|
|
if (this.col_submode == null || this.col_submode == '') {
|
|
|
|
|
mode = this.col_mode;
|
|
|
|
|
} else {
|
|
|
|
|
mode = this.col_submode;
|
|
|
|
|
}
|
2026-03-27 16:10:39 +00:00
|
|
|
var isDupe = dupeCounts[this.col_call + '|' + this.col_band + '|' + this.col_mode] > 1;
|
|
|
|
|
$(".qsotable tbody").prepend('<tr' + (isDupe ? ' class="table-warning"' : '') + '>' +
|
2024-01-14 18:04:35 +00:00
|
|
|
'<td>' + this.col_time_on + '</td>' +
|
|
|
|
|
'<td>' + this.col_call + '</td>' +
|
|
|
|
|
'<td>' + this.col_band + '</td>' +
|
|
|
|
|
'<td>' + mode + '</td>' +
|
|
|
|
|
'<td>' + this.col_rst_sent + '</td>' +
|
|
|
|
|
'<td>' + this.col_rst_rcvd + '</td>' +
|
|
|
|
|
'<td>' + this.col_stx_string + '</td>' +
|
|
|
|
|
'<td>' + this.col_srx_string + '</td>' +
|
|
|
|
|
'<td>' + this.col_stx + '</td>' +
|
|
|
|
|
'<td>' + this.col_srx + '</td>' +
|
|
|
|
|
'<td>' + this.col_gridsquare + '</td>' +
|
|
|
|
|
'<td>' + this.col_vucc_grids + '</td>' +
|
|
|
|
|
'</tr>');
|
|
|
|
|
});
|
2026-03-27 16:32:15 +00:00
|
|
|
$.fn.dataTable.moment('DD-MM-YYYY HH:mm:ss');
|
|
|
|
|
$('.qsotable').DataTable({
|
|
|
|
|
"pageLength": 25,
|
|
|
|
|
responsive: false,
|
|
|
|
|
"scrollY": "400px",
|
|
|
|
|
"scrollCollapse": true,
|
|
|
|
|
"paging": false,
|
|
|
|
|
"scrollX": true,
|
|
|
|
|
"dom": 'rt<"bottom"i>',
|
|
|
|
|
"language": {
|
|
|
|
|
url: getDataTablesLanguageUrl(),
|
|
|
|
|
},
|
|
|
|
|
"search": { "search": $('#logbook-search').val() },
|
|
|
|
|
order: [0, 'desc'],
|
|
|
|
|
"columnDefs": [
|
|
|
|
|
{
|
|
|
|
|
"render": function (data, type, row) {
|
|
|
|
|
return pad(row[8], 3);
|
|
|
|
|
},
|
|
|
|
|
"targets": 8
|
2023-08-06 07:05:33 +00:00
|
|
|
},
|
2026-03-27 16:32:15 +00:00
|
|
|
{
|
|
|
|
|
"render": function (data, type, row) {
|
|
|
|
|
return pad(row[9], 3);
|
2023-08-06 07:05:33 +00:00
|
|
|
},
|
2026-03-27 16:32:15 +00:00
|
|
|
"targets": 9
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
$('#logbook-search').off('keyup.logbook').on('keyup.logbook', function () {
|
|
|
|
|
$('.qsotable').DataTable().search(this.value).draw();
|
|
|
|
|
});
|
2026-03-27 16:10:39 +00:00
|
|
|
updateContestStats(html);
|
|
|
|
|
updateTableColumns($('#exchangetype').val());
|
2024-01-14 18:04:35 +00:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// Runs when no session is set usually when its a clean contest
|
|
|
|
|
var selectElement = document.getElementById('contestname');
|
|
|
|
|
var selected_contest_id = selectElement.options[selectElement.selectedIndex].value;
|
|
|
|
|
$.ajax({
|
|
|
|
|
url: base_url + 'index.php/contesting/getSessionFreshQsos',
|
|
|
|
|
type: 'post',
|
|
|
|
|
data: { 'contest_id': selected_contest_id },
|
|
|
|
|
success: function (html) {
|
2026-03-27 16:32:15 +00:00
|
|
|
// Destroy DataTables FIRST so DOM manipulation is clean
|
|
|
|
|
if ($.fn.DataTable.isDataTable('.qsotable')) {
|
|
|
|
|
$('.qsotable').DataTable().destroy();
|
|
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
var mode = '';
|
|
|
|
|
$(".contest_qso_table_contents").empty();
|
2026-03-27 16:10:39 +00:00
|
|
|
var dupeCounts = {};
|
|
|
|
|
$.each(html, function () {
|
|
|
|
|
var key = this.col_call + '|' + this.col_band + '|' + this.col_mode;
|
|
|
|
|
dupeCounts[key] = (dupeCounts[key] || 0) + 1;
|
|
|
|
|
});
|
2024-01-14 18:04:35 +00:00
|
|
|
$.each(html, function () {
|
|
|
|
|
if (this.col_submode == null || this.col_submode == '') {
|
|
|
|
|
mode = this.col_mode;
|
|
|
|
|
} else {
|
|
|
|
|
mode = this.col_submode;
|
|
|
|
|
}
|
2026-03-27 16:10:39 +00:00
|
|
|
var isDupe = dupeCounts[this.col_call + '|' + this.col_band + '|' + this.col_mode] > 1;
|
|
|
|
|
$(".qsotable tbody").prepend('<tr' + (isDupe ? ' class="table-warning"' : '') + '>' +
|
2024-01-14 18:04:35 +00:00
|
|
|
'<td>' + this.col_time_on + '</td>' +
|
|
|
|
|
'<td>' + this.col_call + '</td>' +
|
|
|
|
|
'<td>' + this.col_band + '</td>' +
|
|
|
|
|
'<td>' + mode + '</td>' +
|
|
|
|
|
'<td>' + this.col_rst_sent + '</td>' +
|
|
|
|
|
'<td>' + this.col_rst_rcvd + '</td>' +
|
|
|
|
|
'<td>' + this.col_stx_string + '</td>' +
|
|
|
|
|
'<td>' + this.col_srx_string + '</td>' +
|
|
|
|
|
'<td>' + this.col_stx + '</td>' +
|
|
|
|
|
'<td>' + this.col_srx + '</td>' +
|
|
|
|
|
'<td>' + this.col_gridsquare + '</td>' +
|
|
|
|
|
'<td>' + this.col_vucc_grids + '</td>' +
|
|
|
|
|
'</tr>');
|
2023-08-06 07:05:33 +00:00
|
|
|
});
|
2026-03-27 16:32:15 +00:00
|
|
|
$.fn.dataTable.moment('DD-MM-YYYY HH:mm:ss');
|
|
|
|
|
$('.qsotable').DataTable({
|
|
|
|
|
"pageLength": 25,
|
|
|
|
|
responsive: false,
|
|
|
|
|
"scrollY": "400px",
|
|
|
|
|
"scrollCollapse": true,
|
|
|
|
|
"paging": false,
|
|
|
|
|
"scrollX": true,
|
|
|
|
|
"dom": 'rt<"bottom"i>',
|
|
|
|
|
"language": {
|
|
|
|
|
url: getDataTablesLanguageUrl(),
|
|
|
|
|
},
|
|
|
|
|
"search": { "search": $('#logbook-search').val() },
|
|
|
|
|
order: [0, 'desc'],
|
|
|
|
|
"columnDefs": [
|
|
|
|
|
{
|
|
|
|
|
"render": function (data, type, row) {
|
|
|
|
|
return pad(row[8], 3);
|
|
|
|
|
},
|
|
|
|
|
"targets": 8
|
2024-01-14 18:04:35 +00:00
|
|
|
},
|
2026-03-27 16:32:15 +00:00
|
|
|
{
|
|
|
|
|
"render": function (data, type, row) {
|
|
|
|
|
return pad(row[9], 3);
|
2024-01-14 18:04:35 +00:00
|
|
|
},
|
2026-03-27 16:32:15 +00:00
|
|
|
"targets": 9
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
$('#logbook-search').off('keyup.logbook').on('keyup.logbook', function () {
|
|
|
|
|
$('.qsotable').DataTable().search(this.value).draw();
|
|
|
|
|
});
|
2026-03-27 16:10:39 +00:00
|
|
|
updateContestStats(html);
|
|
|
|
|
updateTableColumns($('#exchangetype').val());
|
2023-08-06 07:05:33 +00:00
|
|
|
}
|
2024-01-14 18:04:35 +00:00
|
|
|
});
|
|
|
|
|
}
|
2023-08-06 07:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-27 16:10:39 +00:00
|
|
|
function updateTableColumns(exchangetype) {
|
|
|
|
|
if (!$.fn.DataTable.isDataTable('.qsotable')) return;
|
|
|
|
|
var table = $('.qsotable').DataTable();
|
|
|
|
|
var showExch = ['Exchange', 'Serialexchange'].indexOf(exchangetype) !== -1;
|
|
|
|
|
var showSerial = ['Serial', 'Serialexchange', 'Serialgridsquare'].indexOf(exchangetype) !== -1;
|
|
|
|
|
var showGrid = ['Gridsquare', 'Serialgridsquare'].indexOf(exchangetype) !== -1;
|
|
|
|
|
table.column(6).visible(showExch, false);
|
|
|
|
|
table.column(7).visible(showExch, false);
|
|
|
|
|
table.column(8).visible(showSerial, false);
|
|
|
|
|
table.column(9).visible(showSerial, false);
|
|
|
|
|
table.column(10).visible(showGrid, false);
|
|
|
|
|
table.column(11).visible(showGrid, false);
|
2026-03-27 17:39:32 +00:00
|
|
|
table.draw(false);
|
2026-03-27 16:10:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updateContestStats(qsoData) {
|
|
|
|
|
if (!qsoData || qsoData.length === 0) {
|
|
|
|
|
$('#contest-stats-card').hide();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bandOrder = ['160m','80m','60m','40m','30m','20m','17m','15m','12m','10m','6m','4m','2m','70cm','23cm'];
|
|
|
|
|
var bandCounts = {};
|
|
|
|
|
var now = new Date();
|
|
|
|
|
var cutoff = new Date(now.getTime() - 60 * 60 * 1000);
|
|
|
|
|
var recentCount = 0;
|
|
|
|
|
|
|
|
|
|
$.each(qsoData, function () {
|
|
|
|
|
var band = this.col_band || 'Unknown';
|
|
|
|
|
bandCounts[band] = (bandCounts[band] || 0) + 1;
|
|
|
|
|
|
|
|
|
|
// Parse col_time_on: format DD-MM-YYYY HH:mm:ss
|
|
|
|
|
var parts = this.col_time_on.match(/(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2}):(\d{2})/);
|
|
|
|
|
if (parts) {
|
|
|
|
|
var qsoTime = new Date(Date.UTC(
|
|
|
|
|
parseInt(parts[3]), parseInt(parts[2]) - 1, parseInt(parts[1]),
|
|
|
|
|
parseInt(parts[4]), parseInt(parts[5]), parseInt(parts[6])
|
|
|
|
|
));
|
|
|
|
|
if (qsoTime >= cutoff) {
|
|
|
|
|
recentCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var total = qsoData.length;
|
|
|
|
|
$('#stats-total').text(total + (total === 1 ? ' QSO' : ' QSOs'));
|
|
|
|
|
$('#stats-rate').text(recentCount + '/hr');
|
|
|
|
|
|
|
|
|
|
// Build per-band badges in canonical order, then remaining bands alphabetically
|
|
|
|
|
var orderedBands = bandOrder.filter(function (b) { return bandCounts[b]; });
|
|
|
|
|
var extraBands = Object.keys(bandCounts).filter(function (b) { return bandOrder.indexOf(b) === -1; }).sort();
|
|
|
|
|
var allBands = orderedBands.concat(extraBands);
|
|
|
|
|
|
|
|
|
|
var html = allBands.map(function (b) {
|
|
|
|
|
return '<span class="badge text-bg-secondary me-1">' + b + ': ' + bandCounts[b] + '</span>';
|
|
|
|
|
}).join('');
|
|
|
|
|
$('#stats-bands').html(html);
|
|
|
|
|
|
|
|
|
|
$('#contest-stats-card').show();
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-14 18:04:35 +00:00
|
|
|
function pad(str, max) {
|
2023-05-27 14:52:55 +02:00
|
|
|
str = str.toString();
|
|
|
|
|
return str.length < max ? pad("0" + str, max) : str;
|
|
|
|
|
}
|
2023-11-01 14:24:13 +01:00
|
|
|
|
|
|
|
|
function getUTCTimeStamp(el) {
|
|
|
|
|
var now = new Date();
|
|
|
|
|
var localTime = now.getTime();
|
|
|
|
|
var utc = localTime + (now.getTimezoneOffset() * 60000);
|
2024-01-14 18:04:35 +00:00
|
|
|
$(el).attr('value', ("0" + now.getUTCHours()).slice(-2) + ':' + ("0" + now.getUTCMinutes()).slice(-2) + ':' + ("0" + now.getUTCSeconds()).slice(-2));
|
2023-11-01 14:24:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getUTCDateStamp(el) {
|
|
|
|
|
var now = new Date();
|
|
|
|
|
var localTime = now.getTime();
|
|
|
|
|
var utc = localTime + (now.getTimezoneOffset() * 60000);
|
2024-01-14 18:04:35 +00:00
|
|
|
$(el).attr('value', ("0" + now.getUTCDate()).slice(-2) + '-' + ("0" + (now.getUTCMonth() + 1)).slice(-2) + '-' + now.getUTCFullYear());
|
2023-11-01 14:24:13 +01:00
|
|
|
}
|