Compare commits

..

20 Commits

Author SHA1 Message Date
76a6480528 fix: use vdrd website as main domain
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-08-25 19:46:34 +02:00
89d9d46a81 feat: add link to real site 2024-08-25 19:46:34 +02:00
6e15ea9006 feat: Enlargen label
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-08-01 13:10:26 +00:00
7ec5de190d fix: Remove hard-coded language, allow changing
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-31 23:19:15 +02:00
63d3a44e4b feat: Style language chooser
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-31 20:45:55 +02:00
6f7cf6e873 fix: Make sure results get cleared
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-31 19:57:29 +02:00
bc7f32b57d feat: Translate result
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-31 19:51:28 +02:00
6897db4bbf feat: Add label for language switcher, hide because obvious 2024-07-31 19:48:29 +02:00
eab39d0d79 trans: fix various translation issues in active components 2024-07-31 19:38:59 +02:00
128ef795d8 trans: Translate success message 2024-07-31 19:29:33 +02:00
b7f2a3ed67 fix: use alt-i18n-key to avoid overwriting alt tag which makes retranslation impossible 2024-07-31 19:20:46 +02:00
3831b81ec2 fix: tiaki alt key 2024-07-31 19:17:35 +02:00
e2632c3934 feat: add alt text to images 2024-07-31 19:17:01 +02:00
ac2715f5f4 feat: style language switcher 2024-07-31 18:48:23 +02:00
527c5b180f trans: Add english translations 2024-07-31 18:21:43 +02:00
04027e26f1 feat: Make translations use interpolation 2024-07-31 18:15:42 +02:00
a86e1b3935 feat: Change rule to allow for smaller floors (25cm) 2024-07-31 18:15:00 +02:00
603e7738ec fix: don't try to load deprecated calculator 2024-07-31 18:04:56 +02:00
45d78a37e9 fix: restructure code so vaildator gets initialized/calculator updates only after translation are loaded 2024-07-31 15:50:46 +02:00
183c41b387 refactor: Move calculator to main js 2024-07-31 15:21:40 +02:00
7 changed files with 269 additions and 176 deletions

View File

@ -1,5 +1,7 @@
# RattenheimRechner
**[rechner.vdrd.de](https://rechner.vdrd.de)**
Ein Rechner für die minimale Größe eines Rattenkäfigs nach Standard des [VdRD e.V.](https://vdrd.de)
## CI

View File

@ -62,6 +62,7 @@ ul {
label {
font-weight: bold;
word-break: break-word;
font-size: x-large;
}
.slidecontainer {
@ -199,15 +200,31 @@ input.measurement {
flex-wrap: wrap;
}
.navigation-sticky {
.top-navigation {
margin: 0;
border: none;
width: 100%;
display: flex;
}
.homebutton {
background-color: var(--secondary-light-one);
color: var(--primary-light-one);
border-bottom-right-radius: 8px;
font-weight: bold;
padding: 16px;
width: 20%;
}
.language-switcher {
background-color: var(--secondary-light-one);
color: var(--primary-light-one);
padding: 16px;
margin: 0;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
border: none;
font-weight: bold;
width: 20%;
width: 15%;
margin-left: auto;
}
@ -231,4 +248,12 @@ input.measurement {
.tooltip:hover .tooltiptext {
visibility: visible;
}
select, option {
background-color: var(--primary-light-one);
border-radius: 0.2rem;
border: none;
color: var(--text-one);
width: 100%;
}

View File

@ -1,85 +0,0 @@
const MINIMUM_BASE_AREA = 0.5;
const MINIMUM_AREA_THREE_RATS = 1.5;
const AREA_PER_ADDITIONAL_RAT = 0.25;
const MAXIMUM_FALL_HEIGHT = 0.5;
const MINIMUM_LENGTH_LONG_SIDE = 0.8;
const MINIMUM_LENGTH_SHORT_SIDE = 0.5;
const MINIMUM_FLOOR_HEIGHT = 0.3;
const FAILED_BASE_AREA = "base_area";
const FAILED_OVERALL_AREA = "overall_area";
const FAILED_FALL_HEIGHT = "fall_height";
const FAILED_NUM_RATS = "num_rats";
const FAILED_MINIMUM_LENGTH_LONG_SIDE = "length_long_side";
const FAILED_MINIMUM_LENGTH_SHORT_SIDE= "length_short_side";
const FAILED_FLOOR_HEIGHT = "floor_height"
const FAIL_CRITERIA = {
[FAILED_BASE_AREA]: `Die Mindestgrundfläche des Käfigs muss ${MINIMUM_BASE_AREA}m² (also z.B. 100x50cm) betragen.`,
[FAILED_OVERALL_AREA]: "Die Gesamtfläche im Käfig ist zu klein.",
[FAILED_FALL_HEIGHT]: `Die mögliche Fallhöhe darf nicht mehr als ${(MAXIMUM_FALL_HEIGHT * 100).toFixed(0)}cm betragen.`,
[FAILED_FLOOR_HEIGHT]: `Der Mindestabstand zwischen Ebenen muss ${(MINIMUM_FLOOR_HEIGHT * 100).toFixed(0)}cm betragen.`,
[FAILED_NUM_RATS]: "Es müssen mindestens 3 Ratten zusammenleben, Paarhaltung ist nicht artgerecht.",
[FAILED_MINIMUM_LENGTH_LONG_SIDE]: `Die lange Seite des Käfig muss mindestens ${(MINIMUM_LENGTH_LONG_SIDE * 100).toFixed(0)}cm lang sein um Rennen zu ermöglichen.`,
[FAILED_MINIMUM_LENGTH_SHORT_SIDE]: `Die kurze Seite des Käfig muss mindestens ${(MINIMUM_LENGTH_SHORT_SIDE * 100).toFixed(0)}cm lang sein.`,
};
class Dimensions {
constructor(width, depth, height) {
this.width = width;
this.depth = depth;
this.height = height;
}
toString() {
return `${this.width}x${this.depth}x${this.height}`;
}
static fromDict(data) {
const { width, depth, height } = data;
return new Dimensions(width, depth, height);
}
}
function overallAreaNeeded(numOfRats) {
if (numOfRats < 3 || numOfRats > 15) {
throw new Error("This formula works only from 3 to 15 rats");
}
return MINIMUM_AREA_THREE_RATS + (numOfRats - 3) * AREA_PER_ADDITIONAL_RAT;
}
function cageCheck(dimensions, numRats, numFullFloors) {
let failedCriteria = {};
if (numRats < 2 || numRats > 15) {
failedCriteria[FAILED_NUM_RATS] = FAIL_CRITERIA[FAILED_NUM_RATS];
}
const baseArea = dimensions.depth * dimensions.width;
if (baseArea < MINIMUM_BASE_AREA) {
failedCriteria[FAILED_BASE_AREA] = FAIL_CRITERIA[FAILED_BASE_AREA];
}
const areaNeeded = overallAreaNeeded(numRats);
if (baseArea * numFullFloors < areaNeeded) {
failedCriteria[FAILED_OVERALL_AREA] = FAIL_CRITERIA[FAILED_OVERALL_AREA];
}
if (dimensions.height / numFullFloors > MAXIMUM_FALL_HEIGHT) {
failedCriteria[FAILED_FALL_HEIGHT] = FAIL_CRITERIA[FAILED_FALL_HEIGHT];
}
if (dimensions.width < MINIMUM_LENGTH_LONG_SIDE && dimensions.depth < MINIMUM_LENGTH_LONG_SIDE) {
failedCriteria[FAILED_MINIMUM_LENGTH_LONG_SIDE] = FAIL_CRITERIA[FAILED_MINIMUM_LENGTH_LONG_SIDE];
}
if (dimensions.width < MINIMUM_LENGTH_SHORT_SIDE || dimensions.depth < MINIMUM_LENGTH_SHORT_SIDE) {
failedCriteria[FAILED_MINIMUM_LENGTH_SHORT_SIDE] = FAIL_CRITERIA[FAILED_MINIMUM_LENGTH_SHORT_SIDE];
}
if (dimensions.height / numFullFloors < MINIMUM_FLOOR_HEIGHT) {
failedCriteria[FAILED_FLOOR_HEIGHT] = FAIL_CRITERIA[FAILED_FLOOR_HEIGHT];
}
return failedCriteria;
}

View File

@ -4,7 +4,6 @@
<meta charset="UTF-8">
<title>Käfigrechner</title>
<link rel="stylesheet" href="assets/css/style.css">
<script src="assets/js/calculator.js"></script>
<link rel="apple-touch-icon" sizes="180x180" href="assets/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon/favicon-32x32.png">
@ -12,17 +11,22 @@
</head>
<body>
<div class="navigation-sticky">
<a href="https://notfellchen.org">
<b data-i18n-key="back-to-home">zurück zur Homepage</b>
</a>
</div>
<div class="top-navigation">
<div class="homebutton">
<a href="https://vdrd.de">
<b data-i18n-key="back-to-home">zurück zur Homepage</b>
</a>
</div>
<img src="img/translation-icon@2x.png" class="translation-icon" / >
<select data-i18n-switcher class="locale-switcher">
<option value="en">English</option>
<option value="de">Deutsch</option>
</select>
<div class="language-switcher">
<label aria-hidden="false" style="display: none" data-i18n-key="change-language"></label>
<select data-i18n-switcher class="locale-switcher" id="locale-switcher">
<option value="en">English</option>
<option value="de">Deutsch</option>
</select>
</div>
</div>
<div class="content">
<h1 data-i18n-key="app-name">Käfigrechner</h1>
@ -32,7 +36,7 @@
<label for="SavicSuiteRoyaleXL">
<input type="checkbox" id="SavicSuiteRoyaleXL"/>
<div class="card-photo">
<img src="assets/img/savic-xl.jpeg">
<img alt-i18n-key="alt-savic-xl" src="assets/img/savic-xl.jpeg">
</div>
<div class="info-container">
<h4><b>Savic Suite Royale XL</b></h4>
@ -45,7 +49,7 @@
<input type="checkbox" id="SavicSuiteRoyale95Double"/>
<div class="card-photo">
<div>
<img src="assets/img/savic-95-double.jpg">
<img alt-i18n-key="alt-savic-95-double" src="assets/img/savic-95-double.jpg">
</div>
<div class="info-container">
<h4><b>Savic Suite Royale 95 Double</b></h4>
@ -58,7 +62,7 @@
<label for="TiakiKleintierkäfigEtagere">
<input type="checkbox" id="TiakiKleintierkäfigEtagere"/>
<div class="card-photo">
<img src="assets/img/tiaki.jpeg">
<img alt-i18n-key="alt-tiaki" src="assets/img/tiaki.jpeg">
</div>
<div class="info-container">
<h4><b>TIAKI Kleintierkäfig Étagère</b></h4>
@ -67,7 +71,7 @@
</div>
<div class="card" id="card-ManualMeasurements">
<label for="form-cage-measurements">Käfigmaße</label>
<label data-i18n-key="cage-measurements" for="form-cage-measurements">Käfigmaße</label>
<form id="form-cage-measurements" class="form-measurements">
<div class="input-measurement">
<label for="width" data-i18n-key="width-cm">Breite (cm)</label>
@ -90,7 +94,16 @@
<div class="input-element">
<label for="numFullFloors" data-i18n-key="full-floors">Vollebenen</label>
<div class="tooltip">
<svg class="text-grey-dark" width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor"><path d="M9.00026 12.6C9.00026 12.6 9.00026 12.1224 9.00026 11.5333V8.86666C9.00026 8.57211 8.76148 8.33333 8.46693 8.33333H7.93359" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8.73346 5.26666C8.58619 5.26666 8.4668 5.38605 8.4668 5.53333C8.4668 5.68061 8.58619 5.8 8.73346 5.8C8.88074 5.8 9.00013 5.68061 9.00013 5.53333C9.00013 5.38605 8.88074 5.26666 8.73346 5.26666V5.26666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M9 17C13.4183 17 17 13.4183 17 9C17 4.58172 13.4183 1 9 1C4.58172 1 1 4.58172 1 9C1 13.4183 4.58172 17 9 17Z" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
<svg class="text-grey-dark" width="18" height="18" viewBox="0 0 18 18" fill="none"
stroke="currentColor">
<path d="M9.00026 12.6C9.00026 12.6 9.00026 12.1224 9.00026 11.5333V8.86666C9.00026 8.57211 8.76148 8.33333 8.46693 8.33333H7.93359"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M8.73346 5.26666C8.58619 5.26666 8.4668 5.38605 8.4668 5.53333C8.4668 5.68061 8.58619 5.8 8.73346 5.8C8.88074 5.8 9.00013 5.68061 9.00013 5.53333C9.00013 5.38605 8.88074 5.26666 8.73346 5.26666V5.26666"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M9 17C13.4183 17 17 13.4183 17 9C17 4.58172 13.4183 1 9 1C4.58172 1 1 4.58172 1 9C1 13.4183 4.58172 17 9 17Z"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
<span class="tooltiptext" data-i18n-key="full-floors-tooltip">Als Vollebenen zählen alle Ebenen die größer als 0.5m² sind, inklusive des Käfigbodens.</span>
</div>
<div class="ncontainer">
@ -104,16 +117,17 @@
<div class="input-element">
<div class="slidecontainer">
<label for="numRats" id="labelNumRats" data-i18n-key="number-of-rats">Anzahl an Ratten ?</label>
<label for="numRats" id="labelNumRats"></label>
<input type="range" min="3" max="15" value="4" class="slider" id="numRats">
</div>
</div>
</div>
<div class="container output-element" id="resultsDiv">
<div class="container output-element">
<strong data-i18n-key="result">Ergebnis</strong>
<div id="resultsDiv"></div>
</div>
</div>
</div>
<script src="./bundle.js"></script>

View File

@ -6,5 +6,20 @@
"width-cm": "Breite (cm)",
"depth-cm": "Tiefe (cm)",
"height-cm": "Höhe (cm)",
"full-floors-tooltip": "Als Vollebenen zählen alle Ebenen die größer als 0.5m² sind, inklusive des Käfigbodens."
"full-floors-tooltip": "Als Vollebenen zählen alle Ebenen die größer als 0.5m² sind, inklusive des Käfigbodens.",
"failed-base-area": "Die Mindestgrundfläche des Käfigs muss {{ MINIMUM_BASE_AREA }}m² (also z.B. 100x50cm) betragen.",
"failed-overall-area": "Die Gesamtfläche im Käfig ist zu klein.",
"failed-fall-height": "Die mögliche Fallhöhe darf nicht mehr als {{ maximum_fall_height }}cm betragen.",
"failed-floor-height": "Der Mindestabstand zwischen Ebenen muss {{ minimum_floor_height }}cm betragen.",
"failed-num-rats": "Es müssen mindestens 3 Ratten zusammenleben, Paarhaltung ist nicht artgerecht.",
"failed-minimum-length-long-side": "Die lange Seite des Käfig muss mindestens {{ minimum_length_long_side }}cm lang sein um Rennen zu ermöglichen.",
"failed-minimum-length-short-side": "Die kurze Seite des Käfig muss mindestens {{ minimum_length_short_side }}cm lang sein.",
"alt-savic-xl": "Bild des Käfigs Savic Suite Royal XL, ein Drahtkäfig mit vier Türen die erlauben die gesamte Vorderseite zu öffnen. Auf halber Höhe ist eine weitere Vollebene.",
"alt-savic-95-double": "Bild eines dekorierten Käfigs, des Savic Suite Royale 95 Double. Auf insgesamt vie Vollebenen sind Holz- und Papphäusschen, Hängematten, Futterschalen und mehr.",
"alt-tiaki": "Bild des Tiaki-Käfigs, ein Drahtkäfig mit vier Türen die erlauben die gesamte Vorderseite zu öffnen. Auf halber Höhe ist eine weitere Vollebene.",
"cage-measurements": "Käfigmaße",
"cage-complies-with-all-criteria": "Der Käfig erfüllt alle Kriterien!",
"cage-for-x-rats": "Käfig für {{ num_rats }} Ratten",
"change-language": "Sprache ändern",
"result": "Ergebnis"
}

View File

@ -6,5 +6,20 @@
"width-cm": "Width (cm)",
"depth-cm": "Depth (cm)",
"height-cm": "Height (cm)",
"full-floors-tooltip": "A full floor is each floor with a area greater than 0.5m², including the bottom of the cage."
"full-floors-tooltip": "A full floor is each floor with a area greater than XXm², including the bottom of the cage.",
"failed-base-area": "The base area of the cage must not be below {{ MINIMUM_BASE_AREA }}m².",
"failed-overall-area": "The overall area in the cage is to small.",
"failed-fall-height": "The possible fall height between floors must not be above {{ maximum_fall_height }}cm.",
"failed-floor-height": "The height between floors must be above {{ minimum_floor_height }}cm.",
"failed-num-rats": "Rats must live in a group of at least three rats, pairs or lone rats are not species-appropriate.",
"failed-minimum-length-long-side": "The long side of the cage must be at least {{ minimum_length_long_side }}cm long to enable running.",
"failed-minimum-length-short-side": "The short side of the cage must be at least {{ minimum_length_short_side }}cm.",
"alt-savic-xl": "A picture of a wire bar cage with four doors that allow to open the full front of the cage. In the middle of the cage is a additional full floor.",
"alt-savic-95-double": "A picture of a decorated wire bar cage with four doors that allow to open the full front of the cage. Inside there are hammocks, toys and four full floors with lots of hides",
"alt-tiaki": "A picture of a decorated wire bar cage with four doors that allow to open the full front of the cage.",
"cage-measurements": "Cage measurements",
"cage-complies-with-all-criteria": "This cage complies with all criteria!",
"cage-for-x-rats": "Cage for {{ num_rats }} rats",
"change-language": "Change language",
"result": "Result"
}

View File

@ -1,3 +1,169 @@
import i18next from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import HttpApi from "i18next-http-backend";
/////////////////
// TRANSLATION //
/////////////////
async function initI18next() {
await i18next
.use(HttpApi)
.use(LanguageDetector)
.init({
supportedLngs: ["en", "de"],
nonExplicitSupportedLngs: true,
fallbackLng: "en",
debug: true,
backend: {
loadPath: "/lang/{{lng}}.json",
},
});
}
function translatePageElements() {
// Translate content inside a tag
const translatableElements = document.querySelectorAll(
"[data-i18n-key]",
);
translatableElements.forEach((el) => {
const key = el.getAttribute("data-i18n-key");
el.innerHTML = i18next.t(key);
});
// Translate alt texts
const translatableAltTexts = document.querySelectorAll(
"[alt-i18n-key]",
);
translatableAltTexts.forEach((el) => {
const translation_key = el.getAttribute("alt-i18n-key");
el.setAttribute("alt", i18next.t(translation_key));
});
}
function bindLocaleSwitcher(initialValue) {
const switcher = document.querySelector(
"[data-i18n-switcher]",
);
switcher.value = initialValue;
switcher.onchange = (e) => {
i18next
.changeLanguage(e.target.value)
.then(translatePageElements)
.then(update);
};
}
(async function () {
await initI18next();
translatePageElements();
bindLocaleSwitcher(i18next.resolvedLanguage);
update();
})();
////////////////
// CALCULATOR //
////////////////
const MINIMUM_BASE_AREA = 0.5;
const MINIMUM_AREA_THREE_RATS = 1.5;
const AREA_PER_ADDITIONAL_RAT = 0.25;
const MAXIMUM_FALL_HEIGHT = 0.5;
const MINIMUM_LENGTH_LONG_SIDE = 0.8;
const MINIMUM_LENGTH_SHORT_SIDE = 0.5;
const MINIMUM_FLOOR_HEIGHT = 0.25;
const FAILED_BASE_AREA = "base_area";
const FAILED_OVERALL_AREA = "overall_area";
const FAILED_FALL_HEIGHT = "fall_height";
const FAILED_NUM_RATS = "num_rats";
const FAILED_MINIMUM_LENGTH_LONG_SIDE = "length_long_side";
const FAILED_MINIMUM_LENGTH_SHORT_SIDE= "length_short_side";
const FAILED_FLOOR_HEIGHT = "floor_height"
class Validator {
constructor() {
this.FAIL_CRITERIA = {
[FAILED_BASE_AREA]: i18next.t('failed-base-area', {"MINIMUM_BASE_AREA": MINIMUM_BASE_AREA}),
[FAILED_OVERALL_AREA]: i18next.t("failed-overall-area"),
[FAILED_FALL_HEIGHT]: i18next.t("failed-fall-height", {"maximum_fall_height": (MAXIMUM_FALL_HEIGHT * 100).toFixed(0)}),
[FAILED_FLOOR_HEIGHT]: i18next.t("failed-floor-height", {"minimum_floor_height": (MINIMUM_FLOOR_HEIGHT * 100).toFixed(0)}),
[FAILED_NUM_RATS]: i18next.t("failed-num-rats"),
[FAILED_MINIMUM_LENGTH_LONG_SIDE]: i18next.t("failed-minimum-length-long-side", {"minimum_length_long_side": (MINIMUM_LENGTH_LONG_SIDE * 100).toFixed(0)}),
[FAILED_MINIMUM_LENGTH_SHORT_SIDE]: i18next.t("failed-minimum-length-short-side", {"minimum_length_short_side": (MINIMUM_LENGTH_SHORT_SIDE * 100).toFixed(0)}),
};
}
overallAreaNeeded(numOfRats) {
if (numOfRats < 3 || numOfRats > 15) {
throw new Error("This formula works only from 3 to 15 rats");
}
return MINIMUM_AREA_THREE_RATS + (numOfRats - 3) * AREA_PER_ADDITIONAL_RAT;
}
cageCheck(dimensions, numRats, numFullFloors) {
let failedCriteria = {};
if (numRats < 2 || numRats > 15) {
failedCriteria[FAILED_NUM_RATS] = this.FAIL_CRITERIA[FAILED_NUM_RATS];
}
const baseArea = dimensions.depth * dimensions.width;
if (baseArea < MINIMUM_BASE_AREA) {
failedCriteria[FAILED_BASE_AREA] = this.FAIL_CRITERIA[FAILED_BASE_AREA];
}
const areaNeeded = this.overallAreaNeeded(numRats);
if (baseArea * numFullFloors < areaNeeded) {
failedCriteria[FAILED_OVERALL_AREA] = this.FAIL_CRITERIA[FAILED_OVERALL_AREA];
}
if (dimensions.height / numFullFloors > MAXIMUM_FALL_HEIGHT) {
failedCriteria[FAILED_FALL_HEIGHT] = this.FAIL_CRITERIA[FAILED_FALL_HEIGHT];
}
if (dimensions.width < MINIMUM_LENGTH_LONG_SIDE && dimensions.depth < MINIMUM_LENGTH_LONG_SIDE) {
failedCriteria[FAILED_MINIMUM_LENGTH_LONG_SIDE] = this.FAIL_CRITERIA[FAILED_MINIMUM_LENGTH_LONG_SIDE];
}
if (dimensions.width < MINIMUM_LENGTH_SHORT_SIDE || dimensions.depth < MINIMUM_LENGTH_SHORT_SIDE) {
failedCriteria[FAILED_MINIMUM_LENGTH_SHORT_SIDE] = this.FAIL_CRITERIA[FAILED_MINIMUM_LENGTH_SHORT_SIDE];
}
if (dimensions.height / numFullFloors < MINIMUM_FLOOR_HEIGHT) {
failedCriteria[FAILED_FLOOR_HEIGHT] = this.FAIL_CRITERIA[FAILED_FLOOR_HEIGHT];
}
return failedCriteria;
}
}
class Dimensions {
constructor(width, depth, height) {
this.width = width;
this.depth = depth;
this.height = height;
}
toString() {
return `${this.width}x${this.depth}x${this.height}`;
}
static fromDict(data) {
const { width, depth, height } = data;
return new Dimensions(width, depth, height);
}
}
//////////////////////////
// DOCUMENT INTERACTION //
//////////////////////////
const inputDecreaseFloorNum = document.getElementById("decreaseFloorNum");
inputDecreaseFloorNum.onclick = decreaseFloorNum;
@ -42,7 +208,6 @@ function updateCage(event) {
selectedCage.checked = true;
const cageName = selectedCage.id;
console.log(cageName);
var dim = getCageDimensions(cageName);
inputWidth.value = dim.width;
inputDepth.value = dim.depth;
@ -62,10 +227,7 @@ var labelNumRats = document.getElementById("labelNumRats");
var ratSlider = document.getElementById("numRats");
labelNumRats.innerHTML = `Anzahl an Ratten: ` + ratSlider.value;
ratSlider.oninput = function () {
labelNumRats.innerHTML = `Anzahl an Ratten: ` + this.value;
update();
}
@ -73,7 +235,6 @@ ratSlider.oninput = function () {
var fullFloorNum = document.getElementById("numFullFloors");
function getCageDimensions(cageName) {
console.log(cageName);
if (cageName == "SavicSuiteRoyaleXL") {
return new Dimensions(115, 67.5, 153);
}
@ -86,18 +247,17 @@ function getCageDimensions(cageName) {
}
function getResultFromChecks(checks) {
console.log(checks.length)
if (Object.keys(checks).length > 0) {
const ul = document.createElement('ul');
for (const key in checks) {
const li = document.createElement('li');
li.textContent = `` + checks[key];
li.textContent = ` ` + checks[key];
ul.appendChild(li);
}
return ul;
} else {
const p = document.createElement('p');
p.innerHTML = "✅ Der Käfig erfüllt alle Kriterien!"
p.innerHTML = "✅ " + i18next.t("cage-complies-with-all-criteria")
return p;
}
@ -109,17 +269,19 @@ function updateViaManualMeasurements() {
}
function update() {
labelNumRats.innerHTML = i18next.t("cage-for-x-rats", {"num_rats": ratSlider.value});
const width = inputWidth.value
const depth = inputDepth.value
const height = inputHeight.value
const dimensions = new Dimensions(width / 100, depth / 100, height / 100);
const failed_checks = cageCheck(dimensions, ratSlider.value, fullFloorNum.value);
console.log(failed_checks);
const validator = new Validator();
const failed_checks = validator.cageCheck(dimensions, ratSlider.value, fullFloorNum.value);
let resultsDiv = document.getElementById("resultsDiv");
resultsDiv.innerHTML = `<strong>Ergebnis</strong>`;
const result = getResultFromChecks(failed_checks);
resultsDiv.innerHTML = "";
resultsDiv.appendChild(result);
}
@ -139,58 +301,3 @@ function increaseFloorNum() {
input.value = value + 1;
update();
}
update();
import i18next from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import HttpApi from "i18next-http-backend";
async function initI18next() {
// We use() the backend and await it to load
// the translations from the network
await i18next
.use(HttpApi)
.use(LanguageDetector)
.init({
lng: "en",
supportedLngs: ["en", "de"],
nonExplicitSupportedLngs: true,
fallbackLng: "en",
debug: true,
backend: {
loadPath: "/lang/{{lng}}.json",
},
});
}
function translatePageElements() {
const translatableElements = document.querySelectorAll(
"[data-i18n-key]",
);
translatableElements.forEach((el) => {
const key = el.getAttribute("data-i18n-key");
el.innerHTML = i18next.t(key);
});
}
// ...
function bindLocaleSwitcher(initialValue) {
const switcher = document.querySelector(
"[data-i18n-switcher]",
);
switcher.value = initialValue;
switcher.onchange = (e) => {
i18next
.changeLanguage(e.target.value)
.then(translatePageElements);
};
}
(async function () {
await initI18next();
translatePageElements();
bindLocaleSwitcher(i18next.resolvedLanguage);
})();