WebUI fixes

This commit is contained in:
Ricardo Guzman committed 2026-09-23 05:12:51 -03:00
1 parent 3618558b21
commit 316c746936
3 files changed
+74 -3

No files matched your search

+2
View File
@@ -62,6 +62,8 @@ ____________________________________________________
<br />
# Timeline (Versions):
- 2026-09-23 APRSPacketLib V1.0.7 update and many code cleaning with this.
- 2026-09-17 Real APRS Symbols added to map and TNC2 output as a posibility in TNC mode.
- 2026-08-16 New UI (Web) and also Live View over a Map to see Rx stations.
- 2026-08-10 CAD (Channel Activity Detection) and DIFS (Distributed Inter-Frame Space) added.
- 2026-03-25 More Boards, SDK update, OTA fix, GPS process update.
+1 -1
View File
@@ -38,7 +38,7 @@ lib_deps =
ESP32Async/AsyncTCP @ 3.4.10
ESP32Async/ESPAsyncWebServer @ 3.11.1
mikalhart/TinyGPSPlus @ 1.0.3
richonguzman/APRSPacketLib @ 1.0.6
richonguzman/APRSPacketLib @ 1.0.7
display_libs =
adafruit/Adafruit GFX Library @ 1.12.6
adafruit/Adafruit SSD1306 @ 2.5.17
+71 -2
View File
@@ -96,7 +96,7 @@ function loadSettings(settings) {
networksContainer.appendChild(networkElement);
networkCount++;
});
document.getElementById("startupDelay").value = settings.startupDelay;
document.getElementById("startupDelay").value = settings.other.startupDelay;
// APRS-IS
document.getElementById("aprs_is.active").checked = settings.aprs_is.active;
@@ -277,6 +277,8 @@ function loadSettings(settings) {
document.getElementById("ntp.server").value = settings.ntp.server;
document.getElementById("ntp.gmtCorrection").value = settings.ntp.gmtCorrection;
clampOutOfRangeInputs();
updateImage();
}
@@ -1102,4 +1104,71 @@ window.showMap = function () {
fetchMapStations();
}
}, 15000);
}
}
/* ------------------------------------------------- keeping the form submittable
* A control that fails HTML5 validation blocks the whole form, and when it sits in
* a panel that is not the visible one the browser cannot show its bubble either:
* pressing Save then does nothing at all -- no message, no request, no clue. Two
* guards against that: pull stored values back inside the allowed range on load,
* and, if validation still fails, open the section holding the offending control
* and show what is wrong.
*/
function clampOutOfRangeInputs() {
const fixed = [];
document.querySelectorAll("#configuration input[type=number]").forEach((el) => {
if (el.disabled || el.value === "") return;
const value = parseFloat(el.value);
if (isNaN(value)) return;
const min = el.min !== "" ? parseFloat(el.min) : null;
const max = el.max !== "" ? parseFloat(el.max) : null;
let clamped = value;
if (max !== null && value > max) clamped = max;
if (min !== null && value < min) clamped = min;
if (clamped !== value) {
el.value = clamped;
fixed.push((el.name || el.id) + ": " + value + " &rarr; " + clamped);
}
});
if (fixed.length) {
showToast("Stored values outside the allowed range, adjusted:<br>" + fixed.join("<br>")
+ "<br><small>Save to keep them.</small>");
}
}
let invalidFieldReported = false;
form.addEventListener("invalid", function (event) {
const el = event.target;
if (!invalidFieldReported) { // only the first one: the rest would pile up toasts
invalidFieldReported = true;
setTimeout(() => { invalidFieldReported = false; }, 500);
const section = el.closest(".panel-section");
if (section) {
const link = document.querySelector('.side-link[data-target="' + section.id + '"]');
if (link) {
link.click(); // reuses the sidebar switcher (also shows the config view)
} else {
document.querySelectorAll(".panel-section").forEach((s) => s.classList.remove("active"));
section.classList.add("active");
document.getElementById("configuration").classList.remove("d-none");
}
}
showToast("<b>" + (el.name || el.id) + "</b>: " + (el.validationMessage || "invalid value"));
setTimeout(() => {
el.focus();
el.scrollIntoView({ block: "center", behavior: "smooth" });
}, 0);
}
}, true);