Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 4 additions & 23 deletions _includes/schedule_table.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<div class="table-responsive schedule-table-wrapper" data-unit="mi">
<div class="table-responsive schedule-table-wrapper">
<table class='schedule-table table'>
{% if include.show_header %}
<thead>
<tr>
<th>Date</th>
<th class="text-end">Time</th>
<th><div class="d-flex justify-content-between">Routes<span>Distance (<button class="dist-unit-toggle" title="For the enlightened..." style="background:none;border:none;padding:0;font:inherit;text-decoration:underline dotted;cursor:pointer;">mi</button>)</span></div></th>
<th><div class="d-flex justify-content-between">Routes<span>Distance (<button type="button" class="dist-unit-toggle unit-toggle" title="For the enlightened...">mi</button>)</span></div></th>
</tr>
</thead>
{% endif %}
Expand Down Expand Up @@ -81,7 +81,7 @@
{% if plan.notes %}
<tr>
<td></td><td></td>
<td>{{ plan.notes }}</td>
<td class="text-secondary">{{ plan.notes }}</td>
</tr>
{% endif %}
{% if plan.cancelled and plan.cancelled != "" %}
Expand All @@ -108,7 +108,7 @@
{% if total_dist > 0 and run.plan.size > 1 %}
<tr class="total-dist-row">
<td></td><td></td>
<td class="text-end fw-semibold"><hr class="my-1" style="border-top-width: 2px;"/><span class="dist-value" data-mi="{{ total_dist | round: 1 }}" data-km="{{ total_dist | times: 1.609 | round: 1 }}">{{ total_dist | round: 1 }}</span></td>
<td class="text-end text-secondary pt-0"><div class="d-inline-block"><hr class="my-0 mb-1"/><span class="dist-value" data-mi="{{ total_dist | round: 1 }}" data-km="{{ total_dist | times: 1.609 | round: 1 }}" title="Total distance">{{ total_dist | round: 1 }}</span></div></td>
</tr>
{% endif %}
{% if run.cancelled and plan.cancelled != "" %}
Expand All @@ -123,22 +123,3 @@
<tfoot id="schedule-finished" style="display: none"><tr><td colspan="3">A new schedule is coming! <a href="https://github.com/raceconditionrunning/raceconditionrunning.github.io">Contribute on GitHub</a></td></tr></tfoot>
</table>
</div>
<script>
if (!window.__distToggleInit) {
// For switching between miles and kilometers.
window.__distToggleInit = true;
document.addEventListener('click', (e) => {
const btn = e.target.closest('.dist-unit-toggle');
if (!btn) {
return;
}
const wrapper = btn.closest('.schedule-table-wrapper');
const newUnit = wrapper.dataset.unit === 'km' ? 'mi' : 'km';
wrapper.dataset.unit = newUnit;
btn.textContent = newUnit;
wrapper.querySelectorAll('.dist-value').forEach((span) => {
span.textContent = span.dataset[newUnit];
});
});
}
</script>
55 changes: 55 additions & 0 deletions _includes/unit_toggle.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script>
(function() {
if (window.__unitToggleInit) return;
window.__unitToggleInit = true;

const UNITS = {
dist: { key: 'rcr-dist-unit', options: ['mi', 'km'], toggleClass: 'dist-unit-toggle' },
elev: { key: 'rcr-elev-unit', options: ['ft', 'm'], toggleClass: 'elev-unit-toggle' },
};

function getUnit(spec) {
try {
const v = localStorage.getItem(spec.key);
if (spec.options.includes(v)) return v;
} catch (e) { /* localStorage unavailable */ }
return spec.options[0];
}

function applyUnit(spec, unit, kind) {
document.querySelectorAll('.' + spec.toggleClass).forEach((btn) => {
btn.textContent = unit;
});
const selector = spec.options.map((u) => '[data-' + u + ']').join('');
document.querySelectorAll(selector).forEach((el) => {
const v = el.dataset[unit];
if (v != null) el.textContent = v;
});
document.dispatchEvent(new CustomEvent('rcr-units:change', { detail: { kind, unit } }));
}

function applyAll() {
Object.entries(UNITS).forEach(([kind, spec]) => applyUnit(spec, getUnit(spec), kind));
}

window.refreshUnits = applyAll;

applyAll();
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', applyAll);
}

document.addEventListener('click', (e) => {
const btn = e.target.closest('.dist-unit-toggle, .elev-unit-toggle');
if (!btn) return;
e.stopPropagation();
e.preventDefault();
const kind = btn.classList.contains('dist-unit-toggle') ? 'dist' : 'elev';
const spec = UNITS[kind];
const current = getUnit(spec);
const next = spec.options.find((u) => u !== current) || spec.options[0];
applyUnit(spec, next, kind);
try { localStorage.setItem(spec.key, next); } catch (e) { /* localStorage unavailable */ }
}, true);
})();
</script>
1 change: 1 addition & 0 deletions _layouts/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ <h2 class="align-self-center">Race Condition Running</h2>
{{ content }}

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.8/js/bootstrap.bundle.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
{% include unit_toggle.html %}
<script>
(function() {
const GUTTER = 8;
Expand Down
16 changes: 7 additions & 9 deletions _layouts/route.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,15 @@ <h1 title="{{ page.id }}" class="mb-0 h2">{{ page.title }}</h1>
{%- endif -%}

{%- capture stats -%}
<span title="{{ page.distance_mi | times: 1.609 | round: 1 }}km"
class="route-stats-distance text-decoration-dashed">
{{- page.distance_mi | round: 1 -}}mi
<span class="route-stats-distance">
<span data-mi="{{ page.distance_mi | round: 1 }}"
data-km="{{ page.distance_mi | times: 1.609 | round: 1 }}">{{- page.distance_mi | round: 1 -}}</span><button type="button" class="dist-unit-toggle unit-toggle" title="For the enlightened...">mi</button>
</span>
<span class="route-stats-elevation">
↑<span title="{{ page.ascent_m }}m" class="text-decoration-dashed">
{{- ascent_ft | round -}}ft
</span>
↓<span title="{{ page.descent_m }}m" class="text-decoration-dashed">
{{- descent_ft | round -}}ft
</span>
↑<span data-ft="{{ ascent_ft | round }}"
data-m="{{ page.ascent_m | round }}">{{- ascent_ft | round -}}</span><button type="button" class="elev-unit-toggle unit-toggle" title="For the enlightened...">ft</button>
↓<span data-ft="{{ descent_ft | round }}"
data-m="{{ page.descent_m | round }}">{{- descent_ft | round -}}</span><button type="button" class="elev-unit-toggle unit-toggle" title="For the enlightened...">ft</button>
</span>
{%- if page.surface -%}
<a href="{{ '/routes/?q=' | append: surface_query | relative_url }}"
Expand Down
25 changes: 21 additions & 4 deletions css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ a {
text-decoration-color: rgba(from currentcolor r g b / 0.5);
}

.unit-toggle {
background: none;
border: none;
padding: 0;
font: inherit;
color: inherit;
}
@media (scripting: enabled) {
.unit-toggle {
cursor: pointer;
text-decoration-line: underline;
text-decoration-style: dashed;
text-decoration-color: rgba(from currentcolor r g b / 0.5);
}
}

@media (pointer: coarse), (hover: none) {
:not(.maplibregl-ctrl) > [title] {
position: relative;
Expand Down Expand Up @@ -75,11 +91,12 @@ dd {
}


.past, .past a, .past a:visited {
color: #ccc;
.past {
opacity: .5;
}
.next, .next a, .next a:visited {
font-weight: bold;

.next > td, tbody.next td {
background-color: var(--bs-tertiary-bg);
}

.cancelled {
Expand Down
50 changes: 41 additions & 9 deletions pages/routes.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ <h1 class="visually-hidden">{{ page.title }}</h1>
<thead>
<tr>
<th>Route Name</th>
<th>Miles</th>
<th><button type="button" class="dist-unit-toggle unit-toggle" title="For the enlightened...">Miles</button>)</th>
<th>Dates Run</th>
</tr>
</thead>
Expand All @@ -104,7 +104,7 @@ <h1 class="visually-hidden">{{ page.title }}</h1>
{% assign dist_split = route.distance_mi | round: 1 | split: "." %}
{% assign dist_integral = dist_split[0] %}
{% assign dist_fractional = dist_split[1] | append: "0" | truncate: 1, "" %}
<td><span class="dist" title="{{ route.distance_mi | times: 1.609 | round: 1}}km">{{ dist_integral }}.{{ dist_fractional }}</span></td>
<td><span class="dist" data-mi="{{ route.distance_mi | round: 1 }}" data-km="{{ route.distance_mi | times: 1.609 | round: 1 }}">{{ dist_integral }}.{{ dist_fractional }}</span></td>
<td>
<ul class="matched-runs comma-sep">
{% for event in site.data.schedule %}
Expand All @@ -125,6 +125,8 @@ <h1 class="visually-hidden">{{ page.title }}</h1>

Tabulator.registerModule([EditModule, FormatModule, InteractionModule, MutatorModule, ResizeColumnsModule, ResizeTableModule, SortModule, SelectRowModule, FilterModule]);

const KmPerMi = 1.609
const MPerFeet = 3.28084
let searched = false
document.addEventListener("DOMContentLoaded", () => {
let table = new Tabulator("#routes table", {
Expand Down Expand Up @@ -153,13 +155,42 @@ <h1 class="visually-hidden">{{ page.title }}</h1>
return container;
}
},
{title: "Miles", field: "distance_mi", sorter: "number"},
{title: "↑ ft", field: "ascent_m", sorter: "number", formatter: cell => {
return Math.round(cell.getValue() * 3.28084);
}},
{title: "↓ ft", field: "descent_m", sorter: "number", formatter: cell => {
return Math.round(cell.getValue() * 3.28084);
}},
{title: "Distance",
titleFormatter: () => {
const unit = (localStorage.getItem('rcr-dist-unit') === 'km') ? 'km' : 'mi';
return `<button type="button" class="dist-unit-toggle unit-toggle">${unit}</button>`;
},
field: "distance_mi", sorter: "number",
formatter: cell => {
const mi = cell.getValue();
if (typeof mi !== 'number') return '';
const unit = (localStorage.getItem('rcr-dist-unit') === 'km') ? 'km' : 'mi';
return (unit === 'km' ? mi * KmPerMi : mi).toFixed(1);
}},
{title: "Ascent",
titleFormatter: () => {
const unit = (localStorage.getItem('rcr-elev-unit') === 'm') ? 'm' : 'ft';
return `↑ <button type="button" class="elev-unit-toggle unit-toggle">${unit}</button>`;
},
field: "ascent_m", sorter: "number",
formatter: cell => {
const m = cell.getValue();
if (typeof m !== 'number') return '';
const unit = (localStorage.getItem('rcr-elev-unit') === 'm') ? 'm' : 'ft';
return Math.round(unit === 'm' ? m : m * MPerFeet);
}},
{title: "Descent",
titleFormatter: () => {
const unit = (localStorage.getItem('rcr-elev-unit') === 'm') ? 'm' : 'ft';
return `↓ <button type="button" class="elev-unit-toggle unit-toggle">${unit}</button>`;
},
field: "descent_m", sorter: "number",
formatter: cell => {
const m = cell.getValue();
if (typeof m !== 'number') return '';
const unit = (localStorage.getItem('rcr-elev-unit') === 'm') ? 'm' : 'ft';
return Math.round(unit === 'm' ? m : m * MPerFeet);
}},
{title: "Surface", field: "surface_type",
mutator: function(value, data) {
if (!data.surface) return "";
Expand Down Expand Up @@ -215,6 +246,7 @@ <h1 class="visually-hidden">{{ page.title }}</h1>
layout: "fitDataTable",
data: {{ site.data.routes | jsonify}}});
table.element.classList.add("table-sm");
document.addEventListener('rcr-units:change', () => table.redraw(true));
table.on("columnsLoaded", () =>
{
table.element.querySelectorAll("input").forEach((input) => {
Expand Down
Loading