cloudlog/assets/js/sections/continents.js
Peter Goodhall 85210aa2ae Add HTMX continent component and refactor JS
Introduce an HTMX-driven continents results component and refactor the continents page/JS to load/filter results dynamically. Added Continents::component_continent_results() and a new view (continents/component_results.php) which renders the chart/table container and exposes filter params via data attributes. Updated application/views/continents/index.php to use a filter card with an HTMX-enabled form that posts to the new component endpoint and injects results into #continentResults. Reworked assets/js/sections/continents.js to centralize AJAX logic into continentsRender(), add setContinentsLoading(), handle HTMX afterSwap to initialize results, improve error/info messaging, and implement a JS reset button that triggers an HTMX submit. Overall this enables incremental loading of continent stats and simplifies the previous full-form AJAX flow.
2026-04-26 22:15:35 +01:00

182 lines
6.7 KiB
JavaScript

function setContinentsLoading(isLoading) {
$('#searchButton').prop('disabled', isLoading);
}
function continentsRender(mode, band) {
setContinentsLoading(true);
$('.alert').remove();
$.ajax({
url: base_url + 'index.php/continents/get_continents',
type: 'post',
data: {
mode: mode,
band: band,
},
dataType: 'json',
success: function (data) {
setContinentsLoading(false);
totalContinentQsos(data);
},
error: function () {
setContinentsLoading(false);
$('#continentContainer').html('<div class="alert alert-danger" role="alert">Unable to load continent statistics.</div>');
},
});
}
function totalContinentQsos(data) {
// using this to change color of legend and label according to background color
var color = ifDarkModeThemeReturn('white', 'grey');
if (data.length > 0) {
$('.continentstable > tbody').empty();
var labels = [];
var dataQso = [];
var totalQso = Number(0);
var $myTableBody = $('.continentstable > tbody');
var i = 1;
// building the rows in the table
var rowElements = data.map(function (row) {
var $row = $('<tr></tr>');
var $iterator = $('<td></td>').html(i++);
var $type = $('<td></td>').html(row.cont);
var $content = $('<td></td>').html(row.count);
$row.append($iterator, $type, $content);
return $row;
});
// finally inserting the rows
$myTableBody.append(rowElements);
$.each(data, function () {
labels.push(this.cont);
dataQso.push(this.count);
totalQso = Number(totalQso) + Number(this.count);
});
const COLORS = ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499"]
let chartStatus = Chart.getChart("continentChart"); // <canvas> id
if (chartStatus != undefined) {
chartStatus.destroy();
}
var ctx = document.getElementById("continentChart").getContext('2d');
var myChart = new Chart(ctx, {
plugins: [ChartPieChartOutlabels],
type: 'doughnut',
data: {
labels: labels,
datasets: [{
borderColor: 'rgba(54, 162, 235, 1)',
label: 'Number of QSO\'s worked',
data: dataQso,
backgroundColor: ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499"],
borderWidth: 1,
labels: labels,
}]
},
options: {
layout: {
padding: 100
},
title: {
fontColor: color,
fullSize: true,
},
responsive: false,
maintainAspectRatio: true,
plugins: {
legend: {
display: false,
labels: {
boxWidth: 15,
color: color,
font: {
size: 14,
}
},
position: 'right',
align: "middle"
},
outlabels: {
backgroundColor: COLORS,
borderColor: COLORS,
borderRadius: 2, // Border radius of Label
borderWidth: 2, // Thickness of border
color: 'white',
stretch: 10,
padding: 0,
font: {
resizable: true,
minSize: 12,
maxSize: 25,
family: Chart.defaults.font.family,
size: Chart.defaults.font.size,
style: Chart.defaults.font.style,
lineHeight: Chart.defaults.font.lineHeight,
},
zoomOutPercentage: 100,
textAlign: 'start',
backgroundColor: COLORS,
}
}
}
});
// using this to change color of csv-button if dark mode is chosen
var background = $('body').css("background-color");
if (background != ('rgb(255, 255, 255)')) {
$(".buttons-csv").css("color", "white");
}
} else {
$('#continentContainer').html('<div class="alert alert-info" role="alert">Nothing found for the selected filters.</div>');
}
}
function renderContinentsFromComponent() {
var paramsElement = document.getElementById('continentParams');
if (!paramsElement) {
return;
}
var mode = paramsElement.dataset.mode || '';
var band = paramsElement.dataset.band || '';
continentsRender(mode, band);
}
document.body.addEventListener('htmx:afterSwap', function (event) {
var target = event.detail && event.detail.target ? event.detail.target : event.target;
if (target && target.id === 'continentResults') {
renderContinentsFromComponent();
}
});
$(document).ready(function () {
// Render immediately if the results component is already present.
renderContinentsFromComponent();
$(document).on('click', '#resetButton', function () {
var form = document.getElementById('continentFiltersForm');
if (!form) {
return;
}
form.reset();
if (window.htmx) {
htmx.trigger(form, 'submit');
}
});
});