mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-20 14:27:42 +00:00
Activity filter on upcoming page #147
This commit is contained in:
+2
-1
@@ -24,7 +24,7 @@ function loadAlerts() {
|
|||||||
// Build a query string for the API, based on the filters that the user has selected.
|
// Build a query string for the API, based on the filters that the user has selected.
|
||||||
function buildQueryString() {
|
function buildQueryString() {
|
||||||
let str = "?";
|
let str = "?";
|
||||||
["dx_continent", "source"].forEach(fn => {
|
["dx_continent", "source", "sig"].forEach(fn => {
|
||||||
if (!allFilterOptionsSelected(fn)) {
|
if (!allFilterOptionsSelected(fn)) {
|
||||||
str = str + getQueryStringFor(fn) + "&";
|
str = str + getQueryStringFor(fn) + "&";
|
||||||
}
|
}
|
||||||
@@ -332,6 +332,7 @@ function loadOptions() {
|
|||||||
// Populate the filters panel
|
// Populate the filters panel
|
||||||
generateMultiToggleFilterCard("#dx_continent_options", "dx_continent", options["continents"]);
|
generateMultiToggleFilterCard("#dx_continent_options", "dx_continent", options["continents"]);
|
||||||
generateMultiToggleFilterCard("#source-options", "source", options["alert_providers"]);
|
generateMultiToggleFilterCard("#source-options", "source", options["alert_providers"]);
|
||||||
|
generateActivitiesMultiToggleFilterCard(options["sigs"]);
|
||||||
|
|
||||||
// Load URL params. These may select things from the various filter & display options, so the function needs
|
// Load URL params. These may select things from the various filter & display options, so the function needs
|
||||||
// to be called after these are set up, but if the URL params ask for "embedded mode", this will suppress
|
// to be called after these are set up, but if the URL params ask for "embedded mode", this will suppress
|
||||||
|
|||||||
@@ -135,6 +135,63 @@ function generateMultiToggleFilterCard(elementID, filterQuery, options) {
|
|||||||
$(elementID).append(`<div class="mt-1"><a href="#" onclick="toggleFilterButtons('${filterQuery}', true); return false;">All</a> <a href="#" onclick="toggleFilterButtons('${filterQuery}', false); return false;">None</a></div>`);
|
$(elementID).append(`<div class="mt-1"><a href="#" onclick="toggleFilterButtons('${filterQuery}', true); return false;">All</a> <a href="#" onclick="toggleFilterButtons('${filterQuery}', false); return false;">None</a></div>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a collapsable section for the activities filter card, and append it to the given list. The section is
|
||||||
|
// expanded by default if isExpanded is true.
|
||||||
|
function appendActivityFilterSection($list, sectionId, heading, isExapanded, buildBody) {
|
||||||
|
const collapseId = `activity-options-${sectionId}-collapse`;
|
||||||
|
const $li = $('<li class="mb-1">');
|
||||||
|
$li.append(`<button class="btn-toggle${isExapanded ? '' : ' collapsed'}" data-bs-toggle="collapse" data-bs-target="#${collapseId}" aria-expanded="${isExapanded ? 'true' : 'false'}" aria-controls="${collapseId}">${heading}</button>`);
|
||||||
|
const $body = $(`<div class="collapse filter-section-body${isExapanded ? ' show' : ''}" id="${collapseId}">`);
|
||||||
|
buildBody($body);
|
||||||
|
$li.append($body);
|
||||||
|
$list.append($li);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate activities filter card. This one is also a special case.
|
||||||
|
function generateActivitiesMultiToggleFilterCard(activity_options) {
|
||||||
|
const $list = $('<ul class="list-unstyled filter-section-list ps-0">');
|
||||||
|
|
||||||
|
appendActivityFilterSection($list, 'traditional', 'Traditional', true, $body => {
|
||||||
|
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
||||||
|
activity_options.filter(o => o["sig_type"] === "TRADITIONAL").forEach(o => {
|
||||||
|
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
||||||
|
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
||||||
|
});
|
||||||
|
$body.append(`<div class="w-100 mb-1"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-NO_SIG" value="NO_SIG" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-NO_SIG" for="filter-button-sig-NO_SIG"><i class="fa-solid fa-tower-cell"></i> General DX</label></div></div>`);
|
||||||
|
$body.append($grid);
|
||||||
|
});
|
||||||
|
|
||||||
|
appendActivityFilterSection($list, 'adventure', 'Adventure', true, $body => {
|
||||||
|
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
||||||
|
activity_options.filter(o => o["sig_type"] === "ADVENTURE").forEach(o => {
|
||||||
|
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
||||||
|
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
||||||
|
});
|
||||||
|
$body.append($grid);
|
||||||
|
});
|
||||||
|
|
||||||
|
appendActivityFilterSection($list, 'regional', 'Regional', false, $body => {
|
||||||
|
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
||||||
|
activity_options.filter(o => o["sig_type"] === "REGIONAL").forEach(o => {
|
||||||
|
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
||||||
|
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
||||||
|
});
|
||||||
|
$body.append($grid);
|
||||||
|
});
|
||||||
|
|
||||||
|
appendActivityFilterSection($list, 'event', 'Event', false, $body => {
|
||||||
|
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
||||||
|
activity_options.filter(o => o["sig_type"] === "EVENT").forEach(o => {
|
||||||
|
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
||||||
|
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
||||||
|
});
|
||||||
|
$body.append($grid);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#activity-options").append($list);
|
||||||
|
$("#activity-options").append(`<div class="mt-1"><a href="#" onclick="toggleFilterButtons('sig', true); return false;">All</a> <a href="#" onclick="toggleFilterButtons('sig', false); return false;">None</a></div>`);
|
||||||
|
}
|
||||||
|
|
||||||
// Method called when "All" or "None" is clicked
|
// Method called when "All" or "None" is clicked
|
||||||
function toggleFilterButtons(filterQuery, state) {
|
function toggleFilterButtons(filterQuery, state) {
|
||||||
$(".filter-button-" + filterQuery).each(function () {
|
$(".filter-button-" + filterQuery).each(function () {
|
||||||
|
|||||||
@@ -38,63 +38,6 @@ function setHamHFBandToggles() {
|
|||||||
filtersUpdated();
|
filtersUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a collapsable section for the activities filter card, and append it to the given list. The section is
|
|
||||||
// expanded by default if isExpanded is true.
|
|
||||||
function appendActivityFilterSection($list, sectionId, heading, isExapanded, buildBody) {
|
|
||||||
const collapseId = `activity-options-${sectionId}-collapse`;
|
|
||||||
const $li = $('<li class="mb-1">');
|
|
||||||
$li.append(`<button class="btn-toggle${isExapanded ? '' : ' collapsed'}" data-bs-toggle="collapse" data-bs-target="#${collapseId}" aria-expanded="${isExapanded ? 'true' : 'false'}" aria-controls="${collapseId}">${heading}</button>`);
|
|
||||||
const $body = $(`<div class="collapse filter-section-body${isExapanded ? ' show' : ''}" id="${collapseId}">`);
|
|
||||||
buildBody($body);
|
|
||||||
$li.append($body);
|
|
||||||
$list.append($li);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate activities filter card. This one is also a special case.
|
|
||||||
function generateActivitiesMultiToggleFilterCard(activity_options) {
|
|
||||||
const $list = $('<ul class="list-unstyled filter-section-list ps-0">');
|
|
||||||
|
|
||||||
appendActivityFilterSection($list, 'traditional', 'Traditional', true, $body => {
|
|
||||||
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
|
||||||
activity_options.filter(o => o["sig_type"] === "TRADITIONAL").forEach(o => {
|
|
||||||
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
|
||||||
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
|
||||||
});
|
|
||||||
$body.append(`<div class="w-100 mb-1"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-NO_SIG" value="NO_SIG" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-NO_SIG" for="filter-button-sig-NO_SIG"><i class="fa-solid fa-tower-cell"></i> General DX</label></div></div>`);
|
|
||||||
$body.append($grid);
|
|
||||||
});
|
|
||||||
|
|
||||||
appendActivityFilterSection($list, 'adventure', 'Adventure', true, $body => {
|
|
||||||
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
|
||||||
activity_options.filter(o => o["sig_type"] === "ADVENTURE").forEach(o => {
|
|
||||||
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
|
||||||
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
|
||||||
});
|
|
||||||
$body.append($grid);
|
|
||||||
});
|
|
||||||
|
|
||||||
appendActivityFilterSection($list, 'regional', 'Regional', false, $body => {
|
|
||||||
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
|
||||||
activity_options.filter(o => o["sig_type"] === "REGIONAL").forEach(o => {
|
|
||||||
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
|
||||||
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
|
||||||
});
|
|
||||||
$body.append($grid);
|
|
||||||
});
|
|
||||||
|
|
||||||
appendActivityFilterSection($list, 'event', 'Event', false, $body => {
|
|
||||||
const $grid = $('<div class="row row-cols-2 g-1 mb-1">');
|
|
||||||
activity_options.filter(o => o["sig_type"] === "EVENT").forEach(o => {
|
|
||||||
const domSafeName = o["name"].replace(/^[^A-Za-z0-9]+|[^\w]+/gi, "");
|
|
||||||
$grid.append(`<div class="col"><div class="form-check"><input type="checkbox" class="form-check-input filter-button-sig storeable-checkbox" id="filter-button-sig-${domSafeName}" value="${o['name']}" autocomplete="off" onClick="filtersUpdated()" checked><label class="form-check-label" id="filter-button-label-sig-${domSafeName}" for="filter-button-sig-${domSafeName}" title="${o['description']}"><i class="fa-solid ${o['icon']}"></i> ${o['name']} ${(o["region_flag"] != null) ? o['region_flag'] : ''}</label></div></div>`);
|
|
||||||
});
|
|
||||||
$body.append($grid);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#activity-options").append($list);
|
|
||||||
$("#activity-options").append(`<div class="mt-1"><a href="#" onclick="toggleFilterButtons('sig', true); return false;">All</a> <a href="#" onclick="toggleFilterButtons('sig', false); return false;">None</a></div>`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate modes filter card. This one is also a special case.
|
// Generate modes filter card. This one is also a special case.
|
||||||
function generateModesMultiToggleFilterCard(mode_options) {
|
function generateModesMultiToggleFilterCard(mode_options) {
|
||||||
const $grid = $('<div class="row row-cols-3 row-cols-md-2 row-cols-lg-3 g-1 mb-1">');
|
const $grid = $('<div class="row row-cols-3 row-cols-md-2 row-cols-lg-3 g-1 mb-1">');
|
||||||
|
|||||||
@@ -18,13 +18,15 @@
|
|||||||
<div class="row row-cols-1 row-cols-md-3 g-4">
|
<div class="row row-cols-1 row-cols-md-3 g-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{% module Template("cards/dx_continent.html", web_ui_options=web_ui_options) %}
|
{% module Template("cards/dx_continent.html", web_ui_options=web_ui_options) %}
|
||||||
|
<div class="mt-4"></div>
|
||||||
|
{% module Template("cards/duration_limit_alerts.html", web_ui_options=web_ui_options) %}
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
{% module Template("cards/activities.html", web_ui_options=web_ui_options) %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{% module Template("cards/sources.html", web_ui_options=web_ui_options) %}
|
{% module Template("cards/sources.html", web_ui_options=web_ui_options) %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
|
||||||
{% module Template("cards/duration_limit_alerts.html", web_ui_options=web_ui_options) %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user