mirror of
https://github.com/wavelog/wavelog.git
synced 2026-03-22 18:27:16 +00:00
983 lines
27 KiB
JavaScript
983 lines
27 KiB
JavaScript
// Callsign always has focus on load
|
|
$("#callsign").focus();
|
|
|
|
var sessiondata={};
|
|
$(document).ready(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());
|
|
$('#contestname').val($('#contestname_select').val());
|
|
|
|
// Clear the localStorage for the qrg units
|
|
localStorage.clear();
|
|
set_qrg();
|
|
qrg_inputtype();
|
|
|
|
// Storing the contestid in contest session
|
|
$('#contestname, #copyexchangeto, #exchangesequence_select, #band, #mode, #frequency, #radio').change(function () {
|
|
var formdata = new FormData(document.getElementById("qso_input"));
|
|
setSession(formdata);
|
|
});
|
|
|
|
// Storing the exchange type in contest session
|
|
$('#exchangetype').change(function () {
|
|
var exchangetype = $("#exchangetype").val();
|
|
setExchangetype(exchangetype);
|
|
var formdata = new FormData(document.getElementById("qso_input"));
|
|
setSession(formdata);
|
|
});
|
|
});
|
|
|
|
// Always update the contestname
|
|
$('#contestname_select').change(function () {
|
|
$('#contestname').val($('#contestname_select').val());
|
|
});
|
|
|
|
function disabledContestnameSelect(disabled) {
|
|
if (disabled) {
|
|
$("#contestname_select")
|
|
.prop('disabled', true)
|
|
.attr({
|
|
'title': lang_contestname_warning,
|
|
'data-bs-toggle': 'tooltip',
|
|
'data-bs-html': 'true',
|
|
'data-bs-placement': 'top'
|
|
})
|
|
.tooltip();
|
|
} else {
|
|
$("#contestname_select")
|
|
.prop('disabled', false)
|
|
.removeAttr('title data-bs-toggle data-bs-html data-bs-placement')
|
|
.tooltip('dispose');
|
|
}
|
|
}
|
|
|
|
function reset_dialog() {
|
|
BootstrapDialog.confirm({
|
|
title: lang_general_word_danger,
|
|
message: lang_contest_reset_session,
|
|
type: BootstrapDialog.TYPE_DANGER,
|
|
closable: true,
|
|
draggable: true,
|
|
btnOKClass: 'btn-danger',
|
|
callback: function(result) {
|
|
if(result) {
|
|
reset_contest_session();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Resets the logging form and deletes session from database
|
|
async function reset_contest_session() {
|
|
await $.ajax({
|
|
url: base_url + 'index.php/contesting/deleteSession',
|
|
type: 'post',
|
|
success: function (data) {
|
|
|
|
}
|
|
});
|
|
// the user is now allowed again to change the contest name
|
|
disabledContestnameSelect(false);
|
|
// reset the form
|
|
$('#name').val("");
|
|
$('.callsign-suggestions').text("");
|
|
$('#callsign').val("");
|
|
$('#comment').val("");
|
|
|
|
$("#exch_serial_s").val("1");
|
|
$("#exch_serial_r").val("");
|
|
$('#exch_sent').val("");
|
|
$('#exch_rcvd').val("");
|
|
$("#exch_gridsquare_r").val("");
|
|
|
|
$("#callsign").focus();
|
|
setRst($("#mode").val());
|
|
$("#exchangetype").val("None");
|
|
setExchangetype("None");
|
|
$("#contestname_select").val("Other").change();
|
|
$(".contest_qso_table_contents").empty();
|
|
$('#copyexchangeto').val("None");
|
|
|
|
if (!$.fn.DataTable.isDataTable('.qsotable')) {
|
|
$.fn.dataTable.moment('DD-MM-YYYY HH:mm:ss');
|
|
$('.qsotable').DataTable({
|
|
"stateSave": true,
|
|
"pageLength": 25,
|
|
responsive: false,
|
|
"scrollY": "400px",
|
|
"scrollCollapse": true,
|
|
"paging": false,
|
|
"scrollX": true,
|
|
"language": {
|
|
url: getDataTablesLanguageUrl(),
|
|
},
|
|
order: [0, 'desc'],
|
|
"columnDefs": [
|
|
{
|
|
"render": function ( data, type, row ) {
|
|
return row[8] !== null && row[8] !== '' ? pad(row[8], 3) : '';
|
|
},
|
|
"targets" : 8
|
|
},
|
|
{
|
|
"render": function ( data, type, row ) {
|
|
return row[9] !== null && row[9] !== '' ? pad(row[9], 3) : '';
|
|
},
|
|
"targets" : 9
|
|
}
|
|
]
|
|
});
|
|
}
|
|
var table = $('.qsotable').DataTable();
|
|
table.clear();
|
|
|
|
}
|
|
|
|
function sort_exchange() {
|
|
|
|
// Get the selected sequence
|
|
let exchangeSelect = $('#exchangesequence_select');
|
|
|
|
// If the sequence is not set, we need to set one to prevent errors
|
|
if (!exchangeSelect.val()) {
|
|
exchangeSelect.val('s-g-e');
|
|
}
|
|
|
|
// Split the squence into an array
|
|
let selectedOrder = exchangeSelect.val().split('-');
|
|
|
|
// Map sequence to corresponding SENT elements
|
|
let mapping = {
|
|
"g": ".gridsquares",
|
|
"s": ".serials",
|
|
"e": ".exchanges",
|
|
};
|
|
|
|
// Reorder the elements in the DOM
|
|
selectedOrder.forEach(function(item) {
|
|
$('#sent_exchange').append($(mapping[item]));
|
|
});
|
|
|
|
// Map sequence to corresponding RECEIVED elements
|
|
mapping = {
|
|
"g": ".gridsquarer",
|
|
"s": ".serialr",
|
|
"e": ".exchanger",
|
|
};
|
|
|
|
// Reorder the elements in the DOM
|
|
selectedOrder.forEach(function(item) {
|
|
$('#rcvd_exchange').append($(mapping[item]));
|
|
});
|
|
}
|
|
|
|
// Change the sequence of the exchange fields
|
|
$('#exchangesequence_select').change(function () {
|
|
sort_exchange();
|
|
});
|
|
|
|
// Show Settings modal on click
|
|
$('#moreSettingsButton').click(function () {
|
|
$('#moreSettingsModal').modal('show');
|
|
});
|
|
|
|
async function setSession(formdata) {
|
|
formdata.set('copyexchangeto',$("#copyexchangeto option:selected").index());
|
|
await $.ajax({
|
|
url: base_url + 'index.php/contesting/setSession',
|
|
type: 'post',
|
|
data: formdata,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function (data) {
|
|
sessiondata=data;
|
|
}
|
|
});
|
|
}
|
|
|
|
// realtime clock
|
|
if ( ! manual ) {
|
|
$(function ($) {
|
|
handleStart = setInterval(function() { getUTCTimeStamp($('.input_time')); }, 500);
|
|
});
|
|
|
|
$(function ($) {
|
|
handleDate = setInterval(function() { getUTCDateStamp($('.input_date')); }, 1000);
|
|
});
|
|
} else {
|
|
getUTCDateStamp($('.input_date'));
|
|
getUTCTimeStamp($('.input_time'));
|
|
}
|
|
|
|
// We don't want spaces to be written in callsign
|
|
// We don't want spaces to be written in exchange
|
|
// We don't want spaces to be written in gridsquare
|
|
// We don't want spaces to be written in time :)
|
|
$(function () {
|
|
$('#callsign, #exch_rcvd, #exch_gridsquare_r, #start_time').on('keypress', function (e) {
|
|
if (e.which == 32) {
|
|
return false;
|
|
}
|
|
});
|
|
});
|
|
|
|
// We don't want spaces to be written in serial
|
|
$(function () {
|
|
$('#exch_serial_r').on('keypress', function (e) {
|
|
if (e.which == 32) {
|
|
return false;
|
|
}
|
|
});
|
|
});
|
|
|
|
// Some Browsers (Firefox...) allow Chars in Serial Input. We don't want that.
|
|
// reference: https://stackoverflow.com/questions/49923588/input-type-number-with-pattern-0-9-allows-letters-in-firefox
|
|
$(function () {
|
|
$('#exch_serial_s, #exch_serial_r').on('keypress', function (e) {
|
|
var charCode = e.which || e.keyCode;
|
|
var charStr = String.fromCharCode(charCode);
|
|
|
|
if (!/^[0-9]+$/.test(charStr)) {
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
// Here we capture keystrokes to execute functions
|
|
document.onkeyup = function (e) {
|
|
// ALT-W wipe
|
|
if (e.altKey && e.key == "w") {
|
|
reset_log_fields();
|
|
// CTRL-Enter logs QSO
|
|
} else if ((e.key === "Enter") && (e.ctrlKey || e.metaKey)) {
|
|
$("#callsign").blur();
|
|
logQso();
|
|
// Enter in received exchange logs QSO
|
|
} else if ((e.key == "Enter") && (
|
|
($(document.activeElement).attr("id") == "exch_rcvd")
|
|
|| ($(document.activeElement).attr("id") == "exch_gridsquare_r")
|
|
|| ($(document.activeElement).attr("id") == "exch_serial_r")
|
|
|| (($(document.activeElement).attr("id") == "callsign") && ($("#exchangetype").val() == "None"))
|
|
)) {
|
|
logQso();
|
|
} else if (e.key == "Escape") {
|
|
reset_log_fields();
|
|
// Space to jump to either callsign or the various exchanges
|
|
} else if (e.key == " ") {
|
|
let exchangetype = $("#exchangetype").val();
|
|
let sequence = $('#exchangesequence_select').val().split('-');
|
|
|
|
let mapping = {
|
|
"g": "exch_gridsquare_r",
|
|
"s": "exch_serial_r",
|
|
"e": "exch_rcvd",
|
|
};
|
|
|
|
if (manual && $(document.activeElement).attr("id") == "start_time") {
|
|
$("#callsign").focus();
|
|
return false;
|
|
}
|
|
|
|
if (exchangetype == 'Exchange') {
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
$("#exch_rcvd").focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == "exch_rcvd") {
|
|
$("#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 == '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;
|
|
}
|
|
}
|
|
else if (exchangetype == 'Serialexchange') {
|
|
let filteredSequence = sequence.filter(key => key !== 'g');
|
|
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
$(`#${mapping[filteredSequence[0]]}`).focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[0]]) {
|
|
$(`#${mapping[filteredSequence[1]]}`).focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[1]]) {
|
|
$("#callsign").focus();
|
|
return false;
|
|
}
|
|
}
|
|
else if (exchangetype == 'Serialgridsquare') {
|
|
let filteredSequence = sequence.filter(key => key !== 'e');
|
|
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
$(`#${mapping[filteredSequence[0]]}`).focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[0]]) {
|
|
$(`#${mapping[filteredSequence[1]]}`).focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[1]]) {
|
|
$("#callsign").focus();
|
|
return false;
|
|
}
|
|
}
|
|
else if (exchangetype == 'SerialGridExchange') {
|
|
if ($(document.activeElement).attr("id") == "callsign") {
|
|
$(`#${mapping[sequence[0]]}`).focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == mapping[sequence[0]]) {
|
|
$(`#${mapping[sequence[1]]}`).focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == mapping[sequence[1]]) {
|
|
$(`#${mapping[sequence[2]]}`).focus();
|
|
return false;
|
|
} else if ($(document.activeElement).attr("id") == mapping[sequence[2]]) {
|
|
$("#callsign").focus();
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
/* 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);
|
|
}
|
|
});
|
|
|
|
/* 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);
|
|
}
|
|
});
|
|
|
|
|
|
$("#callsign").on( "blur", function() {
|
|
var call = $(this).val();
|
|
if ((call.length>=3) && ($("#bearing_info").html().length == 0)) {
|
|
getCallbook();
|
|
}
|
|
});
|
|
|
|
var scps=[];
|
|
|
|
$("#callsign").on("compositionstart", function(){ this.isComposing = true; });
|
|
$("#callsign").on("compositionend", function(e){
|
|
this.isComposing = false;
|
|
$(this).trigger("keyup");
|
|
});
|
|
|
|
// On Key up check and suggest callsigns
|
|
$("#callsign").keyup(async function (e) {
|
|
// Prevent checking when the user's composing in IME
|
|
if (this.isComposing || e.isComposing) return;
|
|
|
|
var call = $(this).val();
|
|
if ((!((e.keyCode == 10 || e.keyCode == 13) && (e.ctrlKey || e.metaKey))) && (call.length >= 3)) { // prevent checking again when pressing CTRL-Enter
|
|
|
|
if ($(this).val().length >= 3) {
|
|
$callsign = $(this).val().replace('Ø', '0');
|
|
if (scps.filter((call => call.includes($(this).val().toUpperCase()))).length <= 0) {
|
|
$.ajax({
|
|
url: 'lookup/scp',
|
|
method: 'POST',
|
|
data: {
|
|
callsign: $callsign.toUpperCase()
|
|
},
|
|
success: function(result) {
|
|
$('.callsign-suggestions').text(result);
|
|
scps=result.split(" ");
|
|
highlight(call.toUpperCase());
|
|
}
|
|
});
|
|
} else {
|
|
$('.callsign-suggestions').text(scps.filter((call) => call.includes($(this).val().toUpperCase())).join(' '));
|
|
highlight(call.toUpperCase());
|
|
}
|
|
}
|
|
|
|
await checkIfWorkedBefore();
|
|
var qTable = $('.qsotable').DataTable();
|
|
qTable.search(call).draw();
|
|
}
|
|
else if (call.length <= 2) {
|
|
$('.callsign-suggestions').text("");
|
|
$('#bearing_info').html("");
|
|
}
|
|
});
|
|
|
|
async function getCallbook() {
|
|
var call = $("#callsign").val();
|
|
if (call.length >= 3) {
|
|
$.getJSON(base_url + 'index.php/logbook/json/' + call + '/'+$("#band").val()+'/'+$("#band").val() + '/' + current_active_location, function(result) {
|
|
try {
|
|
$('#bearing_info').html(result.bearing);
|
|
} catch {}
|
|
});
|
|
}
|
|
}
|
|
|
|
async function checkIfWorkedBefore() {
|
|
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) {
|
|
if (result.message.substr(0,6) == 'Worked') {
|
|
$('#callsign_info').text(result.message);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
async function reset_log_fields() {
|
|
$('#name').val("");
|
|
$('.callsign-suggestions').text("");
|
|
$('#callsign').val("");
|
|
$('#comment').val("");
|
|
$('#exch_rcvd').val("");
|
|
$('#exch_serial_r').val("");
|
|
$('#exch_gridsquare_r').val("");
|
|
$("#callsign").focus();
|
|
setRst($("#mode").val());
|
|
$('#callsign_info').text("");
|
|
$('#bearing_info').text("");
|
|
|
|
await refresh_qso_table(sessiondata);
|
|
var qTable = $('.qsotable').DataTable();
|
|
qTable.search('').draw();
|
|
}
|
|
|
|
RegExp.escape = function (text) {
|
|
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
}
|
|
|
|
function highlight(term, base) {
|
|
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();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Only set the frequency when not set by userdata/PHP.
|
|
if ($('#frequency').val() == "") {
|
|
$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
|
|
$('#frequency').val(result).trigger("change");
|
|
$('#frequency_rx').val("");
|
|
set_qrg();
|
|
});
|
|
}
|
|
|
|
/* on mode change */
|
|
$('#mode').change(function () {
|
|
if ($('#radio').val() == '0') {
|
|
$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
|
|
$('#frequency').val(result).trigger("change");
|
|
$('#frequency_rx').val("");
|
|
});
|
|
}
|
|
setRst($("#mode").val());
|
|
checkIfWorkedBefore();
|
|
});
|
|
|
|
/* Calculate Frequency */
|
|
/* on band change */
|
|
$('#band').change(function () {
|
|
if ($('#radio').val() == '0') {
|
|
$.get('qso/band_to_freq/' + $(this).val() + '/' + $('.mode').val(), function (result) {
|
|
$('#frequency').val(result).trigger("change");
|
|
$('#frequency_rx').val("");
|
|
});
|
|
}
|
|
set_qrg();
|
|
checkIfWorkedBefore();
|
|
});
|
|
|
|
/* on radio change */
|
|
// in the footer is defined that we want to clear the frequency when changing the radio
|
|
// this may fit for QSOs, but not for the contesting module
|
|
// so we want atleast to set the frequency to the default frequency of the band
|
|
$('#radio').change(function () {
|
|
if ($('#radio').val() == '0') {
|
|
$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
|
|
$('#frequency').val(result).trigger("change");
|
|
$('#frequency_rx').val("");
|
|
});
|
|
}
|
|
});
|
|
|
|
// Handle manual frequency entry - sync visible field to hidden field
|
|
$('#freq_calculated').on('change', function() {
|
|
// set_new_qrg() is defined in qrg_handler.js and will:
|
|
// 1. Parse the frequency value and convert to Hz
|
|
// 2. Update #frequency (hidden field)
|
|
// 3. Update #band selector to match the frequency
|
|
if (typeof set_new_qrg === 'function') {
|
|
set_new_qrg();
|
|
}
|
|
});
|
|
|
|
function setSerial(data) {
|
|
var serialsent = 1;
|
|
if (data.serialsent != "") {
|
|
serialsent = parseInt(data.serialsent);
|
|
}
|
|
$("#exch_serial_s").val(serialsent);
|
|
}
|
|
|
|
function setExchangetype(exchangetype) {
|
|
// Perhaps a better approach is to hide everything, then just enable the things you need
|
|
$('#sent_exchange').hide().removeClass();
|
|
$('#rcvd_exchange').hide().removeClass();
|
|
$(".exchanger").hide();
|
|
$(".exchanges").hide();
|
|
$(".serials").hide();
|
|
$(".serialr").hide();
|
|
$(".gridsquarer").hide();
|
|
$(".gridsquares").hide();
|
|
|
|
// To track the transition, the code for the exchangecopy is kept
|
|
// separate.
|
|
switch(exchangetype) {
|
|
case 'None':
|
|
$('#sent_exchange').hide().removeClass();
|
|
$('#rcvd_exchange').hide().removeClass();
|
|
break;
|
|
|
|
case 'Serial':
|
|
$('#sent_exchange').show().addClass('d-flex gap-2 col-md-2');
|
|
$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-2');
|
|
$(".serials").show();
|
|
$(".serialr").show();
|
|
break;
|
|
|
|
case 'Serialgridsquare':
|
|
$('#sent_exchange').show().addClass('d-flex gap-2 col-md-3');
|
|
$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-3');
|
|
$(".serials").show();
|
|
$(".serialr").show();
|
|
$(".gridsquarer").show();
|
|
$(".gridsquares").show();
|
|
break;
|
|
|
|
case 'Gridsquare':
|
|
$('#sent_exchange').show().addClass('d-flex gap-2 col-md-2');
|
|
$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-2');
|
|
$(".gridsquarer").show();
|
|
$(".gridsquares").show();
|
|
if ($("#copyexchangeto").prop('disabled') == false) {
|
|
$("#copyexchangeto").prop('disabled','disabled');
|
|
$("#copyexchangeto").data('oldValue',$("#copyexchangeto").val());
|
|
$("#copyexchangeto").val('None');
|
|
} else {
|
|
// Do nothing
|
|
}
|
|
break;
|
|
|
|
case 'Exchange':
|
|
$('#sent_exchange').show().addClass('d-flex gap-2 col-md-2');
|
|
$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-2');
|
|
$(".exchanger").show();
|
|
$(".exchanges").show();
|
|
break;
|
|
|
|
case 'Serialexchange':
|
|
$('#sent_exchange').show().addClass('d-flex gap-2 col-md-3');
|
|
$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-3');
|
|
$(".exchanger").show();
|
|
$(".exchanges").show();
|
|
$(".serials").show();
|
|
$(".serialr").show();
|
|
if ($("#copyexchangeto").prop('disabled') == false) {
|
|
// Do nothing
|
|
} else {
|
|
$("#copyexchangeto").val($("#copyexchangeto").data('oldValue') ?? 'None');
|
|
$("#copyexchangeto").prop('disabled',false);
|
|
}
|
|
break;
|
|
|
|
case 'SerialGridExchange':
|
|
$('#sent_exchange').show().addClass('d-flex gap-2 col-md-4');
|
|
$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-4');
|
|
$(".serials").show();
|
|
$(".serialr").show();
|
|
$(".gridsquarer").show();
|
|
$(".gridsquares").show();
|
|
$(".exchanger").show();
|
|
$(".exchanges").show();
|
|
if ($("#copyexchangeto").prop('disabled') == false) {
|
|
// Do nothing
|
|
} else {
|
|
$("#copyexchangeto").val($("#copyexchangeto").data('oldValue') ?? 'None');
|
|
$("#copyexchangeto").prop('disabled',false);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
}
|
|
}
|
|
|
|
/*
|
|
Function: logQso
|
|
Job: this handles the logging done in the contesting module.
|
|
*/
|
|
function logQso() {
|
|
if ($("#callsign").val().length > 0) {
|
|
|
|
// To prevent changing the contest name while logging we disable the select
|
|
// Only "Start a new contest session" will enable it again
|
|
disabledContestnameSelect(true);
|
|
|
|
// Avoid resubmission by disabling the button
|
|
var saveQsoButtonText = $("#saveQso").html();
|
|
$("#saveQso").html('<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span> ' + saveQsoButtonText + '...').prop('disabled', true);
|
|
|
|
$('.callsign-suggestions').text("");
|
|
$('#callsign_info').text("");
|
|
|
|
var table = $('.qsotable').DataTable();
|
|
var exchangetype = $("#exchangetype").val();
|
|
|
|
var gridsquare = $("#exch_gridsquare_r").val();
|
|
var vucc = '';
|
|
|
|
if (gridsquare.indexOf(',') != -1) {
|
|
vucc = gridsquare;
|
|
gridsquare = '';
|
|
}
|
|
|
|
var gridr = '';
|
|
var vuccr = '';
|
|
var exchsent = '';
|
|
var exchrcvd = '';
|
|
var serials = '';
|
|
var serialr = '';
|
|
|
|
switch (exchangetype) {
|
|
case 'Exchange':
|
|
exchsent = $("#exch_sent").val();
|
|
exchrcvd = $("#exch_rcvd").val();
|
|
break;
|
|
|
|
case 'Gridsquare':
|
|
gridr = gridsquare;
|
|
vuccr = vucc;
|
|
break;
|
|
|
|
case 'Serial':
|
|
serials = $("#exch_serial_s").val();
|
|
serialr = $("#exch_serial_r").val();
|
|
break;
|
|
|
|
case 'Serialexchange':
|
|
exchsent = $("#exch_sent").val();
|
|
exchrcvd = $("#exch_rcvd").val();
|
|
serials = $("#exch_serial_s").val();
|
|
serialr = $("#exch_serial_r").val();
|
|
break;
|
|
|
|
case 'Serialgridsquare':
|
|
gridr = gridsquare;
|
|
vuccr = vucc;
|
|
serials = $("#exch_serial_s").val();
|
|
serialr = $("#exch_serial_r").val();
|
|
break;
|
|
|
|
case 'SerialGridExchange':
|
|
gridr = gridsquare;
|
|
vuccr = vucc;
|
|
exchsent = $("#exch_sent").val();
|
|
exchrcvd = $("#exch_rcvd").val();
|
|
serials = $("#exch_serial_s").val();
|
|
serialr = $("#exch_serial_r").val();
|
|
break;
|
|
}
|
|
|
|
var formdata = new FormData(document.getElementById("qso_input"));
|
|
|
|
let manual_addon = '?manual=' + qso_manual;
|
|
|
|
$.ajax({
|
|
url: base_url + 'index.php/qso/saveqso' + manual_addon,
|
|
type: 'post',
|
|
data: formdata,
|
|
processData: false,
|
|
contentType: false,
|
|
enctype: 'multipart/form-data',
|
|
success: async function (html) {
|
|
var exchangetype = $("#exchangetype").val();
|
|
if (exchangetype == "Serial" || exchangetype == 'Serialexchange' || exchangetype == 'Serialgridsquare' || exchangetype == 'SerialGridExchange') {
|
|
$("#exch_serial_s").val(+$("#exch_serial_s").val() + 1);
|
|
formdata.set('exch_serial_s', $("#exch_serial_s").val());
|
|
}
|
|
|
|
$('#name').val("");
|
|
$('#bearing_info').html("");
|
|
$('#callsign').val("");
|
|
$('#comment').val("");
|
|
$('#exch_rcvd').val("");
|
|
$('#exch_gridsquare_r').val("");
|
|
$('#exch_serial_r').val("");
|
|
if (manual) {
|
|
$("#start_time").focus().select();
|
|
} else {
|
|
$("#callsign").focus();
|
|
}
|
|
await setSession(formdata);
|
|
|
|
await refresh_qso_table(sessiondata);
|
|
var qTable = $('.qsotable').DataTable();
|
|
qTable.search('').order([0, 'desc']).draw();
|
|
|
|
// Re-enable the previously disabled button for resubmission avoidance
|
|
$("#saveQso").html(saveQsoButtonText).prop("disabled", false);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
async function getSession() {
|
|
return await $.ajax({
|
|
url: base_url + 'index.php/contesting/getSession',
|
|
type: 'post',
|
|
});
|
|
}
|
|
|
|
async function restoreContestSession(data) {
|
|
if (data) {
|
|
let settings = JSON.parse(data.settings);
|
|
|
|
if (settings.copyexchangeto != "") {
|
|
$('#copyexchangeto option')[settings.copyexchangeto].selected = true;
|
|
}
|
|
|
|
if (data.contestid != "") {
|
|
$("#contestname_select").val(data.contestid);
|
|
}
|
|
|
|
if (settings.exchangetype != "") {
|
|
$("#exchangetype").val(settings.exchangetype);
|
|
setExchangetype(settings.exchangetype);
|
|
setSerial(data);
|
|
}
|
|
|
|
if (settings.exchangesequence != "") {
|
|
$("#exchangesequence_select").val(settings.exchangesequence);
|
|
sort_exchange();
|
|
}
|
|
|
|
if (data.exchangesent != "") {
|
|
$("#exch_sent").val(data.exchangesent);
|
|
}
|
|
|
|
if (settings.radio != "0") {
|
|
$("#radio").val(settings.radio);
|
|
} else {
|
|
$("#radio").val(settings.radio);
|
|
$("#band").val(settings.band);
|
|
$("#mode").val(settings.mode);
|
|
if (settings.freq_display != "") {
|
|
$("#frequency").val(settings.freq_display);
|
|
} else {
|
|
$.get('qso/band_to_freq/' + settings.band + '/' + settings.mode, function (result) {
|
|
$('#frequency').val(result).trigger("change");
|
|
});
|
|
}
|
|
}
|
|
|
|
if (data.qso != "") {
|
|
disabledContestnameSelect(true);
|
|
await refresh_qso_table(data);
|
|
} else {
|
|
disabledContestnameSelect(false);
|
|
$("#contestname_select").val("Other").change();
|
|
}
|
|
} else {
|
|
$("#exch_serial_s").val("1");
|
|
}
|
|
}
|
|
|
|
async function refresh_qso_table(data) {
|
|
if (data !== null) {
|
|
$.ajax({
|
|
url: base_url + 'index.php/contesting/getSessionQsos',
|
|
type: 'post',
|
|
data: { 'qso': data.qso, },
|
|
success: function (html) {
|
|
if (!$.fn.DataTable.isDataTable('.qsotable')) {
|
|
$.fn.dataTable.moment('DD-MM-YYYY HH:mm:ss');
|
|
$('.qsotable').DataTable({
|
|
"stateSave": true,
|
|
"pageLength": 25,
|
|
responsive: false,
|
|
"scrollY": "400px",
|
|
"scrollCollapse": true,
|
|
"paging": false,
|
|
"scrollX": true,
|
|
"language": {
|
|
url: getDataTablesLanguageUrl(),
|
|
},
|
|
order: [0, 'desc'],
|
|
"columnDefs": [
|
|
{
|
|
"render": function ( data, type, row ) {
|
|
return row[8] !== null && row[8] !== '' ? pad(row[8], 3) : '';
|
|
},
|
|
"targets" : 8
|
|
},
|
|
{
|
|
"render": function ( data, type, row ) {
|
|
return row[9] !== null && row[9] !== '' ? pad(row[9], 3) : '';
|
|
},
|
|
"targets" : 9
|
|
}
|
|
]
|
|
});
|
|
}
|
|
var table = $('.qsotable').DataTable();
|
|
table.clear();
|
|
|
|
var mode = '';
|
|
var data = [];
|
|
$.each(html, function () {
|
|
if (this.col_submode == null || this.col_submode == '') {
|
|
mode = this.col_mode;
|
|
} else {
|
|
mode = this.col_submode;
|
|
}
|
|
|
|
data.push([
|
|
this.col_time_on,
|
|
'<a href="javascript:displayQso(' + this.col_primary_key + ');">'+this.col_call + '</a>',
|
|
this.col_band,
|
|
mode,
|
|
this.col_rst_sent,
|
|
this.col_rst_rcvd,
|
|
this.col_stx_string,
|
|
this.col_srx_string,
|
|
this.col_stx,
|
|
this.col_srx,
|
|
this.col_gridsquare,
|
|
this.col_vucc_grids
|
|
]);
|
|
});
|
|
|
|
if (data.length > 0) {
|
|
table.rows.add(data).draw();
|
|
}
|
|
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function pad (str, max) {
|
|
str = str.toString();
|
|
return str.length < max ? pad("0" + str, max) : str;
|
|
}
|
|
|
|
function getUTCTimeStamp(el) {
|
|
var now = new Date();
|
|
var localTime = now.getTime();
|
|
var utc = localTime + (now.getTimezoneOffset() * 60000);
|
|
if (manual) {
|
|
$(el).attr('value', ("0" + now.getUTCHours()).slice(-2)+':'+("0" + now.getUTCMinutes()).slice(-2));
|
|
} else {
|
|
$(el).attr('value', ("0" + now.getUTCHours()).slice(-2)+':'+("0" + now.getUTCMinutes()).slice(-2)+':'+("0" + now.getUTCSeconds()).slice(-2));
|
|
}
|
|
}
|
|
|
|
function getUTCDateStamp(el) {
|
|
var now = new Date();
|
|
var day = ("0" + now.getUTCDate()).slice(-2);
|
|
var month = ("0" + (now.getUTCMonth() + 1)).slice(-2);
|
|
var year = now.getUTCFullYear();
|
|
var short_year = year.toString().slice(-2);
|
|
|
|
// Format the date based on user_date_format passed from PHP
|
|
var formatted_date;
|
|
switch (user_date_format) {
|
|
case "d/m/y":
|
|
formatted_date = day + "/" + month + "/" + short_year;
|
|
break;
|
|
case "d/m/Y":
|
|
formatted_date = day + "/" + month + "/" + year;
|
|
break;
|
|
case "m/d/y":
|
|
formatted_date = month + "/" + day + "/" + short_year;
|
|
break;
|
|
case "m/d/Y":
|
|
formatted_date = month + "/" + day + "/" + year;
|
|
break;
|
|
case "d.m.Y":
|
|
formatted_date = day + "." + month + "." + year;
|
|
break;
|
|
case "y/m/d":
|
|
formatted_date = short_year + "/" + month + "/" + day;
|
|
break;
|
|
case "Y-m-d":
|
|
formatted_date = year + "-" + month + "-" + day;
|
|
break;
|
|
case "M d, Y":
|
|
// Need to get the month name abbreviation
|
|
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
formatted_date = monthNames[now.getUTCMonth()] + " " + parseInt(day) + ", " + year;
|
|
break;
|
|
case "M d, y":
|
|
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
formatted_date = monthNames[now.getUTCMonth()] + " " + parseInt(day) + ", " + short_year;
|
|
break;
|
|
case "d M y":
|
|
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
formatted_date = parseInt(day) + " " + monthNames[now.getUTCMonth()] + " " + short_year;
|
|
break;
|
|
default:
|
|
// Default to d-m-Y format as shown in the PHP code
|
|
formatted_date = day + "-" + month + "-" + year;
|
|
}
|
|
|
|
$(el).attr('value', formatted_date);
|
|
}
|