[CQ Award] Changed to filter dropdown

This commit is contained in:
Andreas Kristiansen
2025-11-27 20:40:37 +01:00
parent c8c1208558
commit 636a4eacad
5 changed files with 290 additions and 100 deletions

View File

@@ -676,6 +676,8 @@ class Awards extends CI_Controller {
$postdata['notworked'] = $this->security->xss_clean($this->input->post('notworked'));
$postdata['band'] = $this->security->xss_clean($this->input->post('band'));
$postdata['mode'] = $this->security->xss_clean($this->input->post('mode'));
$postdata['datefrom'] = $this->security->xss_clean($this->input->post('dateFrom'));
$postdata['dateto'] = $this->security->xss_clean($this->input->post('dateTo'));
}
else { // Setting default values at first load of page
$postdata['qsl'] = 1;
@@ -687,6 +689,8 @@ class Awards extends CI_Controller {
$postdata['notworked'] = 1;
$postdata['band'] = 'All';
$postdata['mode'] = 'All';
$postdata['datefrom'] = null;
$postdata['dateto'] = null;
}
if ($logbooks_locations_array) {
@@ -1612,6 +1616,8 @@ class Awards extends CI_Controller {
$postdata['notworked'] = $this->input->post('notworked') == 0 ? NULL: 1;
$postdata['band'] = $this->security->xss_clean($this->input->post('band'));
$postdata['mode'] = $this->security->xss_clean($this->input->post('mode'));
$postdata['datefrom'] = $this->security->xss_clean($this->input->post('datefrom'));
$postdata['dateto'] = $this->security->xss_clean($this->input->post('dateto'));
if ($logbooks_locations_array) {
$location_list = "'".implode("','",$logbooks_locations_array)."'";

View File

@@ -82,6 +82,16 @@ class CQ extends CI_Model{
$bindings[]=$postdata['mode'];
}
if ($postdata['datefrom'] != NULL) {
$sql .= " and date(col_time_on) >= ?";
$bindings[]=$postdata['datefrom'];
}
if ($postdata['dateto'] != NULL) {
$sql .= " and date(col_time_on) <= ?";
$bindings[]=$postdata['dateto'];
}
$sql .= $this->genfunctions->addBandToQuery($band,$bindings);
$sql .= " and not exists (select 1 from " . $this->config->item('table_name') .
@@ -94,6 +104,16 @@ class CQ extends CI_Model{
$bindings[]=$postdata['mode'];
}
if ($postdata['datefrom'] != NULL) {
$sql .= " and date(col_time_on) >= ?";
$bindings[]=$postdata['datefrom'];
}
if ($postdata['dateto'] != NULL) {
$sql .= " and date(col_time_on) <= ?";
$bindings[]=$postdata['dateto'];
}
$sql .= $this->genfunctions->addBandToQuery($band,$bindings);
$sql .= $this->genfunctions->addQslToQuery($postdata);
@@ -120,6 +140,16 @@ class CQ extends CI_Model{
$bindings[]=$postdata['mode'];
}
if ($postdata['datefrom'] != NULL) {
$sql .= " and date(col_time_on) >= ?";
$bindings[]=$postdata['datefrom'];
}
if ($postdata['dateto'] != NULL) {
$sql .= " and date(col_time_on) <= ?";
$bindings[]=$postdata['dateto'];
}
$sql .= $this->genfunctions->addBandToQuery($band,$bindings);
$sql .= $this->genfunctions->addQslToQuery($postdata);
@@ -180,6 +210,16 @@ class CQ extends CI_Model{
$bindings[]=$postdata['mode'];
}
if ($postdata['datefrom'] != NULL) {
$sql .= " and date(col_time_on) >= ?";
$bindings[]=$postdata['datefrom'];
}
if ($postdata['dateto'] != NULL) {
$sql .= " and date(col_time_on) <= ?";
$bindings[]=$postdata['dateto'];
}
$query = $this->db->query($sql,$bindings);
return $query->result();
@@ -215,6 +255,16 @@ class CQ extends CI_Model{
$bindings[]=$postdata['mode'];
}
if ($postdata['datefrom'] != NULL) {
$sql .= " and date(col_time_on) >= ?";
$bindings[]=$postdata['datefrom'];
}
if ($postdata['dateto'] != NULL) {
$sql .= " and date(col_time_on) <= ?";
$bindings[]=$postdata['dateto'];
}
$sql .= $this->genfunctions->addQslToQuery($postdata);
$query = $this->db->query($sql,$bindings);

View File

@@ -1,16 +1,25 @@
<script>
var tileUrl="<?php echo $this->optionslib->get_option('option_map_tile_server');?>";
var lang_general_hamradio_cqzone = "<?= __("CQ Zone"); ?>";
var lang_hover_over_a_zone = "<?= __("Hover over a zone"); ?>";
</script>
<script>
let user_map_custom = JSON.parse('<?php echo $user_map_custom; ?>');
let tileUrl="<?php echo $this->optionslib->get_option('option_map_tile_server');?>";
let lang_general_hamradio_cqzone = "<?= __("CQ Zone"); ?>";
let lang_hover_over_a_zone = "<?= __("Hover over a zone"); ?>";
let user_map_custom = JSON.parse('<?php echo $user_map_custom; ?>');
</script>
<style>
#cqmap {
height: calc(100vh - 480px) !important;
max-height: 900px !important;
}
.dropdown-filters-responsive {
width: 800px;
}
@media (max-width: 900px) {
.dropdown-filters-responsive {
width: 90vw;
max-width: none;
}
}
</style>
<div class="container">
@@ -19,108 +28,138 @@
<br>
<div id="awardInfoButton">
<script>
var lang_awards_info_button = "<?= __("Award Info"); ?>";
var lang_award_info_ln1 = "<?= __("CQ WAZ (Worked All Zones) Award"); ?>";
var lang_award_info_ln2 = "<?= __("The CQ Magazine was located in the US and one of the most popular amateur radio magazines in the world. They stopped service by the end of 2023. The magazine first appeared in January 1945 and focuses on awards and the practical aspects of amateur radio."); ?>";
var lang_award_info_ln3 = "<?= __("The WAZ Award stands for 'Worked All Zones' and requires radio contacts to all 40 CQ Zones along with the corresponding confirmation. Since the CQ Magazine does no longer exists the CQ WAZ Awards is now managed directly by N4BAA."); ?>";
var lang_award_info_ln4 = "<?= sprintf(__("You can find all the information and rules on the Website of N4BAA: %s"), "<a href='https://n4baa.com/cqwaz.html' target='_blank'>N4BAA.com</a>"); ?>";
var lang_award_info_ln5 = "<?= __("Fields taken for this Award: CQ-Zone (ADIF: CQZ)"); ?>";
let lang_awards_info_button = "<?= __("Award Info"); ?>";
let lang_award_info_ln1 = "<?= __("CQ WAZ (Worked All Zones) Award"); ?>";
let lang_award_info_ln2 = "<?= __("The CQ Magazine was located in the US and one of the most popular amateur radio magazines in the world. They stopped service by the end of 2023. The magazine first appeared in January 1945 and focuses on awards and the practical aspects of amateur radio."); ?>";
let lang_award_info_ln3 = "<?= __("The WAZ Award stands for 'Worked All Zones' and requires radio contacts to all 40 CQ Zones along with the corresponding confirmation. Since the CQ Magazine does no longer exists the CQ WAZ Awards is now managed directly by N4BAA."); ?>";
let lang_award_info_ln4 = "<?= sprintf(__("You can find all the information and rules on the Website of N4BAA: %s"), "<a href='https://n4baa.com/cqwaz.html' target='_blank'>N4BAA.com</a>"); ?>";
let lang_award_info_ln5 = "<?= __("Fields taken for this Award: CQ-Zone (ADIF: CQZ)"); ?>";
</script>
<h2><?= __("Awards - CQ WAZ"); ?></h2>
<button type="button" class="btn btn-sm btn-primary me-1" id="displayAwardInfo"><?= __("Award Info"); ?></button>
</div>
<!-- End of Award Info Box -->
<form class="form" action="<?php echo site_url('awards/cq'); ?>" method="post" enctype="multipart/form-data">
<fieldset>
<div class="mb-4 text-center">
<div class="dropdown" data-bs-auto-close="outside">
<button class="btn btn-sm btn-primary dropdown-toggle" type="button" id="filterDropdown" data-bs-toggle="dropdown" aria-expanded="false"><?= __("Filters") ?></button>
<button id="button1id" type="submit" name="button1id" class="btn btn-sm btn-primary"><?= __("Show"); ?></button>
<?php if ($cq_array) {
?><button type="button" onclick="load_cq_map();" class="btn btn-info btn-sm"><i class="fas fa-globe-americas"></i> <?= __("Show CQ Zone Map"); ?></button>
<?php }?>
<!-- Multiple Checkboxes (inline) -->
<div class="mb-3 row">
<div class="col-md-2" for="checkboxes"><?= __("Worked") . ' / ' . __("Confirmed")?></div>
<div class="col-md-10">
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="worked" id="worked" value="1" <?php if ($this->input->post('worked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="worked"><?= __("Show worked"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="confirmed" id="confirmed" value="1" <?php if ($this->input->post('confirmed') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="confirmed"><?= __("Show confirmed"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="notworked" id="notworked" value="1" <?php if ($this->input->post('notworked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="notworked"><?= __("Show not worked"); ?></label>
</div>
</div>
</div>
<!-- Dropdown Menu with Filter Content -->
<div class="dropdown-menu start-50 translate-middle-x p-3 mt-5 dropdown-filters-responsive" aria-labelledby="filterDropdown" style="max-width: 800px;">
<div class="card-body filterbody">
<div class="row mb-3">
<label class="form-label" for="checkboxes"><?= __("Date Presets") . ": " ?></label>
<div class="d-flex gap-1 d-flex flex-wrap">
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('today')"><?= __("Today") ?></button>
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('yesterday')"><?= __("Yesterday") ?></button>
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('last7days')"><?= __("Last 7 Days") ?></button>
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('last30days')"><?= __("Last 30 Days") ?></button>
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('thismonth')"><?= __("This Month") ?></button>
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('lastmonth')"><?= __("Last Month") ?></button>
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('thisyear')"><?= __("This Year") ?></button>
<button type="button" class="btn btn-primary btn-sm flex-shrink-0" onclick="applyPreset('lastyear')"><?= __("Last Year") ?></button>
<button type="button" class="btn btn-danger btn-sm flex-shrink-0" onclick="resetDates()"><i class="fas fa-times"></i> <?= __("Clear") ?></button>
</div>
</div>
<div class="mb-3 row">
<div class="col-md-2"><?= __("Show QSO with QSL Type"); ?></div>
<div class="col-md-10">
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="qsl" value="1" id="qsl" <?php if ($this->input->post('qsl') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="qsl"><?= __("QSL Card"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="lotw" value="1" id="lotw" <?php if ($this->input->post('lotw') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="lotw"><?= __("LoTW"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="eqsl" value="1" id="eqsl" <?php if ($this->input->post('eqsl')) echo ' checked="checked"'; ?> >
<label class="form-check-label" for="eqsl"><?= __("eQSL"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="qrz" value="1" id="qrz" <?php if ($this->input->post('qrz')) echo ' checked="checked"'; ?> >
<label class="form-check-label" for="qrz"><?= __("QRZ.com"); ?></label>
</div>
</div>
</div>
<div class="mb-3 row">
<div class="col-md-2 control-label" for="checkboxes"><?= __("Date from"); ?></div>
<div class="col-md-10">
<div class="form-check-inline">
<input name="dateFrom" id="dateFrom" type="date" class="form-control form-control-sm w-auto border border-secondary" <?php if ($this->input->post('dateFrom')) echo 'value="' . $this->input->post('dateFrom') . '"'; ?>>
</div>
</div>
</div>
<div class="mb-3 row">
<div class="col-md-2 control-label" for="checkboxes"><?= __("Date to"); ?></div>
<div class="col-md-10">
<div class="form-check-inline">
<input name="dateTo" id="dateTo" type="date" class="form-control form-control-sm w-auto border border-secondary" <?php if ($this->input->post('dateTo')) echo 'value="' . $this->input->post('dateTo') . '"'; ?>>
</div>
</div>
</div>
<div class="mb-3 row">
<label class="col-md-2 control-label" for="band2"><?= __("Band"); ?></label>
<div class="col-md-2">
<select id="band2" name="band" class="form-select form-select-sm">
<option value="All" <?php if ($this->input->post('band') == "All" || $this->input->method() !== 'post') echo ' selected'; ?> ><?= __("All"); ?></option>
<?php foreach($worked_bands as $band) {
echo '<option value="' . $band . '"';
if ($this->input->post('band') == $band) echo ' selected';
echo '>' . $band . '</option>'."\n";
} ?>
</select>
</div>
</div>
<!-- Multiple Checkboxes (inline) -->
<div class="mb-3 row">
<div class="col-md-2" for="checkboxes"><?= __("Worked") . ' / ' . __("Confirmed")?></div>
<div class="col-md-10">
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="worked" id="worked" value="1" <?php if ($this->input->post('worked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="worked"><?= __("Show worked"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="confirmed" id="confirmed" value="1" <?php if ($this->input->post('confirmed') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="confirmed"><?= __("Show confirmed"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="notworked" id="notworked" value="1" <?php if ($this->input->post('notworked') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="notworked"><?= __("Show not worked"); ?></label>
</div>
</div>
</div>
<div class="mb-3 row">
<label class="col-md-2 control-label" for="mode"><?= __("Mode"); ?></label>
<div class="col-md-2">
<select id="mode" name="mode" class="form-select form-select-sm">
<option value="All" <?php if ($this->input->post('mode') == "All" || $this->input->method() !== 'mode') echo ' selected'; ?>><?= __("All"); ?></option>
<?php
foreach($modes->result() as $mode){
if ($mode->submode == null) {
echo '<option value="' . $mode->mode . '"';
if ($this->input->post('mode') == $mode->mode) echo ' selected';
echo '>'. $mode->mode . '</option>'."\n";
} else {
echo '<option value="' . $mode->submode . '"';
if ($this->input->post('mode') == $mode->submode) echo ' selected';
echo '>' . $mode->submode . '</option>'."\n";
<div class="mb-3 row">
<div class="col-md-2"><?= __("Show QSO with QSL Type"); ?></div>
<div class="col-md-10">
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="qsl" value="1" id="qsl" <?php if ($this->input->post('qsl') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="qsl"><?= __("QSL Card"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="lotw" value="1" id="lotw" <?php if ($this->input->post('lotw') || $this->input->method() !== 'post') echo ' checked="checked"'; ?> >
<label class="form-check-label" for="lotw"><?= __("LoTW"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="eqsl" value="1" id="eqsl" <?php if ($this->input->post('eqsl')) echo ' checked="checked"'; ?> >
<label class="form-check-label" for="eqsl"><?= __("eQSL"); ?></label>
</div>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="qrz" value="1" id="qrz" <?php if ($this->input->post('qrz')) echo ' checked="checked"'; ?> >
<label class="form-check-label" for="qrz"><?= __("QRZ.com"); ?></label>
</div>
</div>
</div>
<div class="mb-3 row">
<label class="col-md-2 control-label" for="band2"><?= __("Band"); ?></label>
<div class="col-md-3">
<select id="band2" name="band" class="form-select form-select-sm">
<option value="All" <?php if ($this->input->post('band') == "All" || $this->input->method() !== 'post') echo ' selected'; ?> ><?= __("All"); ?></option>
<?php foreach($worked_bands as $band) {
echo '<option value="' . $band . '"';
if ($this->input->post('band') == $band) echo ' selected';
echo '>' . $band . '</option>'."\n";
} ?>
</select>
</div>
</div>
<div class="mb-3 row">
<label class="col-md-2 control-label" for="mode"><?= __("Mode"); ?></label>
<div class="col-md-3">
<select id="mode" name="mode" class="form-select form-select-sm">
<option value="All" <?php if ($this->input->post('mode') == "All" || $this->input->method() !== 'mode') echo ' selected'; ?>><?= __("All"); ?></option>
<?php
foreach($modes->result() as $mode){
if ($mode->submode == null) {
echo '<option value="' . $mode->mode . '"';
if ($this->input->post('mode') == $mode->mode) echo ' selected';
echo '>'. $mode->mode . '</option>'."\n";
} else {
echo '<option value="' . $mode->submode . '"';
if ($this->input->post('mode') == $mode->submode) echo ' selected';
echo '>' . $mode->submode . '</option>'."\n";
}
}
}
?>
</select>
?>
</select>
</div>
</div>
</div>
<div class="mb-3 row">
<label class="col-md-2 control-label" for="button1id"></label>
<div class="col-md-10">
<button id="button2id" type="reset" name="button2id" class="btn btn-sm btn-warning"><?= __("Reset"); ?></button>
<button id="button1id" type="submit" name="button1id" class="btn btn-sm btn-primary"><?= __("Show"); ?></button>
<?php if ($cq_array) {
?><button type="button" onclick="load_cq_map();" class="btn btn-info btn-sm"><i class="fas fa-globe-americas"></i> <?= __("Show CQ Zone Map"); ?></button>
<?php }?>
</div>
</div>
</fieldset>
</div>
</form>
<ul class="nav nav-tabs" id="myTab" role="tablist">

View File

@@ -2704,6 +2704,7 @@ function viewEqsl(picture, callsign) {
label: lang_admin_close,
action: function (dialogItself) {
dialogItself.close();
return false; // Prevent any form submission
}
}]
});

View File

@@ -13,6 +13,16 @@ if (typeof(user_map_custom.unworked) !== 'undefined') {
unworkedColor = 'red';
}
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll('.dropdown').forEach(dd => {
dd.addEventListener('hide.bs.dropdown', function (e) {
if (e.clickEvent && e.clickEvent.target.closest('.dropdown-menu')) {
e.preventDefault(); // stop Bootstrap from closing
}
});
});
});
function load_cq_map() {
$('.nav-tabs a[href="#cqmaptab"]').tab('show');
$.ajax({
@@ -28,6 +38,8 @@ function load_cq_map() {
eqsl: +$('#eqsl').prop('checked'),
lotw: +$('#lotw').prop('checked'),
qrz: +$('#qrz').prop('checked'),
datefrom: $('#dateFrom').val(),
dateto: $('#dateTo').val(),
},
success: function(data) {
cqz = data;
@@ -180,13 +192,95 @@ function style(feature) {
}
function onClick(e) {
var marker = e.target;
displayContactsOnMap($("#cqmap"),marker.options.title, $('#band2').val(), 'All', 'All', $('#mode').val(), 'CQZone');
let marker = e.target;
displayContactsOnMap($("#cqmap"),marker.options.title, $('#band2').val(), 'All', 'All', $('#mode').val(), 'CQZone', '', $('#dateFrom').val(), $('#dateTo').val());
}
function onClick2(e) {
zoomToFeature(e);
console.log(e);
var marker = e.target;
displayContactsOnMap($("#cqmap"),marker.feature.properties.cq_zone_number, $('#band2').val(), 'All', 'All', $('#mode').val(), 'CQZone');
let marker = e.target;
displayContactsOnMap($("#cqmap"),marker.feature.properties.cq_zone_number, $('#band2').val(), 'All', 'All', $('#mode').val(), 'CQZone', '', $('#dateFrom').val(), $('#dateTo').val());
}
// Preset functionality
function applyPreset(preset) {
const dateFrom = document.getElementById('dateFrom');
const dateTo = document.getElementById('dateTo');
const today = new Date();
// Format date as YYYY-MM-DD
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
switch(preset) {
case 'today':
dateFrom.value = formatDate(today);
dateTo.value = formatDate(today);
break;
case 'yesterday':
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
dateFrom.value = formatDate(yesterday);
dateTo.value = formatDate(yesterday);
break;
case 'last7days':
const sevenDaysAgo = new Date(today);
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
dateFrom.value = formatDate(sevenDaysAgo);
dateTo.value = formatDate(today);
break;
case 'last30days':
const thirtyDaysAgo = new Date(today);
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
dateFrom.value = formatDate(thirtyDaysAgo);
dateTo.value = formatDate(today);
break;
case 'thismonth':
const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
dateFrom.value = formatDate(firstDayOfMonth);
dateTo.value = formatDate(today);
break;
case 'lastmonth':
const firstDayOfLastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);
const lastDayOfLastMonth = new Date(today.getFullYear(), today.getMonth(), 0);
dateFrom.value = formatDate(firstDayOfLastMonth);
dateTo.value = formatDate(lastDayOfLastMonth);
break;
case 'thisyear':
const firstDayOfYear = new Date(today.getFullYear(), 0, 1);
dateFrom.value = formatDate(firstDayOfYear);
dateTo.value = formatDate(today);
break;
case 'lastyear':
const lastYear = today.getFullYear() - 1;
const firstDayOfLastYear = new Date(lastYear, 0, 1);
const lastDayOfLastYear = new Date(lastYear, 11, 31);
dateFrom.value = formatDate(firstDayOfLastYear);
dateTo.value = formatDate(lastDayOfLastYear);
break;
case 'alltime':
dateFrom.value = '';
dateTo.value = '';
break;
}
}
// Reset dates function
function resetDates() {
const dateFrom = document.getElementById('dateFrom');
const dateTo = document.getElementById('dateTo');
dateFrom.value = '';
dateTo.value = '';
}