ctucx.git: mqtt-webui

webui for mqtt, can be used to control/display data in mqtt-topics

commit 6aad7bc7def7b24a1b05761bf204cb46620e3253
parent 527b3f597d915834933974424a0aeb6078adfc8a
Author: Leah (ctucx) <git@ctu.cx>
Date: Mon, 12 Dec 2022 23:14:37 +0100

implement number logic and css
2 files changed, 71 insertions(+), 13 deletions(-)
M
src/webui.css
|
38
++++++++++++++++++++++++++++++++++++--
M
src/webui.js
|
46
+++++++++++++++++++++++++++++++++++-----------
diff --git a/src/webui.css b/src/webui.css
@@ -28,7 +28,7 @@
 		--background-color:                #1c1c1eff;
 		--nav-background-color:            #2c2c2e4b;
 		--nav-scroll-border-color:         #ebebf52e;
-		--section-header-background-color: #2c2c2eff;
+		--section-header-background-color: #2c2c2e4b;
 		--section-background-color:        #1c1c1e4b;
 		--section-border-color:            #ebebf52e;
 		--text-color:                      #fff;

@@ -261,7 +261,6 @@ section > div .right {
 
 
 /* Button Styling*/
-
 .buttons > button:first-child {
 	border-top-left-radius: .5em;
 	border-bottom-left-radius: .5em;

@@ -284,6 +283,41 @@ section > div .right {
 }
 
 
+/* Select Styling */
+select {
+	padding: .3em .4em;
+}
+
+
+/* Number Styling*/
+.number {
+	display: flex;
+}
+.number > button:first-child {
+	border-top-left-radius: .5em;
+	border-bottom-left-radius: .5em;
+}
+
+.number > button:last-child {
+	border-top-right-radius: .5em;
+	border-bottom-right-radius: .5em;
+}
+
+.number > button {
+	background-color: var(--button-background-color);
+	color: var(--secondary-text-color);
+	padding: .5em .7em;
+	margin: 0;
+}
+
+.number > input {
+	width: 0;
+	border-radius: 0;
+	border: 0;
+	margin: 0;
+	padding: .5em .4em;
+}
+
 .loader {
 	border: 4px solid #ccc;
 	border-top: 4px solid #6c757d;
diff --git a/src/webui.js b/src/webui.js
@@ -107,11 +107,11 @@ const onMessage = (topic, message) => {
 
 				break;
 
-			// untested
 			case 'number':
 				if (isNaN(value)) return;
 
 				element.value = value;
+				element.style.width = (element.value.length + 2) + "ch";
 				element.classList.remove('working');
 				break;
 		}

@@ -246,29 +246,53 @@ const renderItem = (itemData) => {
 				element = html`<div class="buttons">${map(itemData.buttons, buttonElement)}</div>`;
 				break;
 
-			// untested
 			case 'number':
+				const keydownHandler = (event) => {
+					const element = event.target;
+
+					element.style.width = (element.value.length + 2) + "ch";
+
+					if (event.code === 'Backspace') return true;
+					if (event.code === 'Delete')    return true;
+
+					if (!(/^([.,0-9]+)$/.test(event.key))) {
+						event.preventDefault();
+						return false;
+					}
+				}
 
 				const numberHandlder = (event) => {
 					if (!client.connected)           return false;
 					if (itemData.topic.set === null) return false;
 
-					const input            = event.target.parentNode.querySelector('input');
-					let   inputValue       = Number(input.value.replace(',', '.'));
+					const input      = event.target.parentNode.querySelector('input');
+					let   inputValue = Number(input.value.replace(',', '.'));
+
+					itemData.numberMinValue  ??= 1;
+					itemData.numberMaxValue  ??= 254;
+					itemData.numberIncrement ??= 1;
+					itemData.numberDecrement ??= 1;
+
+					if (event.target.textContent === '-') {
+						if (inputValue === Number(itemData.numberMinValue)) return false;
+						inputValue = inputValue - itemData.numberDecrement;
+					}
 
-					if (element.target.textContent === '-') inputValue = inputValue - itemData.decrement ?? 1;
-					if (element.target.textContent === '+') inputValue = inputValue - itemData.increment ?? 1;
+					if (event.target.textContent === '+') {
+						if (inputValue === Number(itemData.numberMaxValue)) return false;
+						inputValue = inputValue + itemData.numberIncrement;
+					}
 
-					const transformedValue = transformMessage(inputValue, meta);
+					const transformedValue = transformMessage(inputValue, itemData);
 
-					client.publish(topic, transformedValue, itemData.mqtt);
+					client.publish(itemData.topic.set, transformedValue, itemData.mqtt);
 					input.classList.add('working');
 				}
 
 				element = html`
-					<div class="number-group">
-						<button type="button" click="${numberHandlder}">-</button>
-						<input type="text" inputmode="decimal" @change="${numberHandlder}" data-type="${itemData.type}" data-mqtt-topic="${itemData.topic.get}">
+					<div class="number">
+						<button type="button" @click="${numberHandlder}">-</button>
+						<input type="text" inputmode="decimal" @keydown="${keydownHandler}" @change="${numberHandlder}" data-type="${itemData.type}" data-mqtt-topic="${itemData.topic.get}" data-transform="${ifDefined(transform)}">
 						<button type="button" @click="${numberHandlder}">+</button>
 					</div>
 				`;