Files
JIMRI/web/js/main.js
T
2026-06-17 14:00:51 +02:00

371 lines
14 KiB
JavaScript

/*
* Common JavaScript functionality for BootStrap-based servlets.
*/
var minFontSize = parseInt(10);
var maxFontSize = parseInt(48);
var nbJmri = null;
var log = new Logger();
/*
* Populate the panels menu with a list of open panels
*/
function getPanels() {
$.ajax({
url: "/panel?format=json",
data: {},
success: function (data) {
if (!Array.isArray(data)) {
data = [data];
}
$(".navbar-panel-item").remove();
if (data.length !== 0) {
$("#empty-panel-list").addClass("hidden").removeClass("show");
$.each(data, function (index, value) {
$("#navbar-panels").append("<li class=\"navbar-panel-item\"><a href=\"/panel/" + value.data.name + "\">" + value.data.userName + "</a></li>");
});
} else {
$("#empty-panel-list").addClass("show").removeClass("hidden");
}
}
});
}
function getRosterGroups() {
$.ajax({
url: "/json/rosterGroups",
data: {},
success: function (data) {
if (!Array.isArray(data)) {
data = [data];
}
$(".navbar-roster-group-item").remove();
if (data.length !== 0) {
$.each(data, function (index, value) {
$("#navbar-roster-groups").append("<li class=\"navbar-roster-group-item\"><a href=\"/roster/group/" + encodeURIComponent(value.data.name) + "\"><span class=\"badge pull-right\">" + value.data.length + "</span>" + value.data.name + "</a></li>");
});
}
}
});
}
/*
* Get list of in-use network services and hide or show elements as appropriate
*/
function getNetworkServices() {
$.ajax({
url: "/json/networkServices",
data: {},
success: function (data) {
if (!Array.isArray(data)) {
data = [data];
}
// show all hidden when service is available elements
$(".hidden-jmri_jmri-json").addClass("show").removeClass("hidden");
$(".hidden-jmri_jmri-locormi").addClass("show").removeClass("hidden");
$(".hidden-jmri_jmri-simple").addClass("show").removeClass("hidden");
$(".hidden-jmri_srcp").addClass("show").removeClass("hidden");
$(".hidden-jmri_withrottle").addClass("show").removeClass("hidden");
// hide all visible when service is available elements
$(".visible-jmri_jmri-json").addClass("hidden").removeClass("show");
$(".visible-jmri_jmri-locormi").addClass("hidden").removeClass("show");
$(".visible-jmri_jmri-simple").addClass("hidden").removeClass("show");
$(".visible-jmri_srcp").addClass("hidden").removeClass("show");
$(".visible-jmri_withrottle").addClass("hidden").removeClass("show");
if (data.length !== 0) {
$.each(data, function (index, value) {
var service = value.data.type.split(".")[0];
$(".visible-jmri" + service).addClass("show").removeClass("hidden");
$(".hidden-jmri" + service).addClass("hidden").removeClass("show");
});
}
}
});
}
/*
* Find a parameter in the URL by name
*/
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && match[1];
}
/*
* Set the title to the parameter + railroad name
* This also returns the new title should it be needed elsewhere
*/
function setTitle(value) {
var title = $("html").data("railroad");
if (value) {
title = value + " | " + title;
}
$(document).attr("title", title);
return title;
}
/*
* Set every element matching the selector to the height of the tallest element
*/
function equalHeight(selector) {
tallest = 0;
selector.each(function () {
thisHeight = $(this).height();
if (thisHeight > tallest) {
tallest = thisHeight;
}
});
selector.each(function () {
$(this).height(tallest);
});
}
/*
* Increment/Decrement the text size
*/
function setFontSize(change) {
change = parseInt(change);
size = parseInt($("body").css("fontSize").replace("px", "").trim());
if (change === 0) {
if (window.localStorage.getItem("jmri.css.font-size.body")) {
size = parseInt(window.localStorage.getItem("jmri.css.font-size.body"));
}
$("#font-size-smaller").click(function () {
setFontSize(-1);
return false;
});
$("#font-size-larger").click(function () {
setFontSize(1);
return false;
});
} else if (change === 1 && size < maxFontSize) {
size++;
$("#font-size-smaller").parent().removeClass("disabled");
} else if (change === -1 && size > minFontSize) {
size--;
$("#font-size-larger").parent().removeClass("disabled");
} else if (change === 14) {
size = 14;
$("#font-size-smaller").parent().removeClass("disabled");
$("#font-size-larger").parent().removeClass("disabled");
}
$("body").css("fontSize", size + "px");
window.localStorage.setItem("jmri.css.font-size.body", size);
$("#font-size-value").text(size + "px");
if (size >= maxFontSize) {
$("#font-size-larger").parent().addClass("disabled");
}
if (size <= minFontSize) {
$("#font-size-smaller").parent().addClass("disabled");
}
console.log("Body font size is " + $("body").css("fontSize"));
}
/*
* Allow users to fix the navbar to the browser window. First use after page
* loads should pass a null value as its parameter to read either localStorage
* or page parameters.
*
* The parameter jmri.css.navbar.fixed=0 can be appended to the URL to set the
* default value to false if it has not already been set in localStorage.
*
* @param {type} fixed true if navbar should be fixed
* @returns {undefined}
*/
function setNavbarFixed(fixed) {
if (fixed === null) {
if (window.localStorage.getItem("jmri.css.navbar.fixed") !== null) {
fixed = (parseInt(window.localStorage.getItem("jmri.css.navbar.fixed")) === 1);
}
$("#navbar-fixed-position").change(function () {
setNavbarFixed($(this).prop("checked"));
});
}
if (fixed === null) {
if (getParameterByName("jmri.css.navbar.fixed") !== null) {
fixed = (parseInt(getParameterByName("jmri.css.navbar.fixed")) === 1);
} else {
fixed = true;
}
}
if (fixed === true) {
$(".navbar").removeClass("navbar-static-top").addClass("navbar-fixed-top");
$("body").css("padding-top", "50px");
} else {
$(".navbar").removeClass("navbar-fixed-top").addClass("navbar-static-top");
$("body").css("padding-top", "0px");
}
$("#navbar-fixed-position").prop("checked", (fixed === true) ? "checked" : "");
window.localStorage.setItem("jmri.css.navbar.fixed", ((fixed === true) ? 1 : 0));
console.log("Navbar is " + ((fixed === true) ? "fixed" : "floating"));
}
/*
* Define localStorage for the retention of data if not already defined.
* From https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage#localStorage
*/
if (!window.localStorage) {
Object.defineProperty(window, "localStorage", new (function () {
var aKeys = [], oStorage = {};
Object.defineProperty(oStorage, "getItem", {
value: function (sKey) {
return sKey ? this[sKey] : null;
},
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "key", {
value: function (nKeyId) {
return aKeys[nKeyId];
},
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "setItem", {
value: function (sKey, sValue) {
if (!sKey) {
return;
}
document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
},
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "length", {
get: function () {
return aKeys.length;
},
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "removeItem", {
value: function (sKey) {
if (!sKey) {
return;
}
document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
},
writable: false,
configurable: false,
enumerable: false
});
this.get = function () {
var iThisIndx;
for (var sKey in oStorage) {
iThisIndx = aKeys.indexOf(sKey);
if (iThisIndx === -1) {
oStorage.setItem(sKey, oStorage[sKey]);
}
else {
aKeys.splice(iThisIndx, 1);
}
delete oStorage[sKey];
}
for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) {
oStorage.removeItem(aKeys[0]);
}
for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) {
aCouple = aCouples[nIdx].split(/\s*=\s*/);
if (aCouple.length > 1) {
oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]);
aKeys.push(iKey);
}
}
return oStorage;
};
this.configurable = false;
this.enumerable = true;
})());
}
//insert jquery if not available
//if (!window.jQuery) {
// console.log("inserting jQuery");
// var script = document.createElement('script');
// script.src = '/js/jquery-2.2.4.min.js'; //
// document.getElementsByTagName('head')[0].appendChild(script);
//}
//insert logger.js if not available
//if (!window.Logger) {
// var script = document.createElement('script');
// script.src = '/js/logger.js'; //
// document.getElementsByTagName('head')[0].appendChild(script);
// log.log("inserting Logger");
//}
//-----------------------------------------javascript processing starts here (main) ---------------------------------------------
// perform tasks that all BootStrap-based servlets need
$(document).ready(function () {
getNetworkServices(); // hide or show and network service specific elements
getPanels(); // complete the panels menu
getRosterGroups(); // list roster groups in menu
setFontSize(0); // get the user's prefered font size
setNavbarFixed(null); // make the navbar floating or fixed
$("#reset-local-preferences").click(function () {
window.localStorage.removeItem("jmri.css.navbar.fixed"); // remove user preference
setNavbarFixed(null); // reset to default or passed in parameter
setFontSize(14); // reset to default
return false;
});
// note: the functions and parameter names must match exactly those in jquery.jmri.js
nbJmri = $.JMRI({
open: function () {
nbJmri.getPower();
},
hello: function(data) {
nbJmri.getList("rosterGroups"); // request updates to the rosterGroups via websocket
},
rosterGroups: function (name, data) {
getRosterGroups(); // refresh the roster groups in menu
},
power: function (state) {
$('#navbar-power').data('power', state);
disabled = ($('#navbar-power button').hasClass('disabled')) ? " - Setting power disabled" : "";
switch (state) {
case nbJmri.UNKNOWN:
$('#navbar-power button').addClass('btn-warning').removeClass('btn-success').removeClass('btn-danger');
$('#navbar-power button').prop('title', "Layout power unknown" + disabled);
$('#navbar-power a').text("Layout Power Unknown");
break;
case nbJmri.POWER_ON:
$('#navbar-power button').addClass('btn-success').removeClass('btn-danger').removeClass('btn-warning');
$('#navbar-power button').prop('title', "Layout power on" + disabled);
$('#navbar-power a').text("Layout Power On");
break;
case nbJmri.POWER_OFF:
$('#navbar-power button').addClass('btn-danger').removeClass('btn-success').removeClass('btn-warning');
$('#navbar-power button').prop('title', "Layout power off" + disabled);
$('#navbar-power a').text("Layout Power Off");
break;
}
$('#navbar-power-modal-label').text($('#navbar-power a').text());
}
});
nbJmri.connect();
if ($('#navbar-power').data('power') === 'readwrite') {
$('#navbar-power').removeClass('disabled');
$('#navbar-power button').removeClass('disabled');
$('#navbar-power button').click(function (event) {
$('#navbar-power-modal').modal('show');
});
$('#navbar-power-modal-on').click(function (event) {
nbJmri.setPower(nbJmri.POWER_ON);
$('#navbar-power-modal').modal('hide');
});
$('#navbar-power-modal-off').click(function (event) {
nbJmri.setPower(nbJmri.POWER_OFF);
$('#navbar-power-modal').modal('hide');
});
$('#navbar-power a').click(function (event) {
$('#navbar-power-modal').modal('show');
});
$('#navbar-power-modal').on('show.bs.modal', function () {
$('#navbar-power-modal-label').text($('#navbar-power a').text());
$('.navbar-collapse').collapse('hide');
$('#navbar-power-modal').css("z-index", "1500");
});
}
});