Input field for number/free text for openHAB UIs

may i ask you also to help with formating basicUI.
This is what i want to accomplish - i removed two divs in browser dev tools (just befor the injected iframe) and changed height value to sth smaller. Is there a way to accomplish this in textItem.html ?

image

<html class="ui-icons-enabled">

<script>
    function getParam(param) {
        var qs = (function(a) {
            if (a == "") return {};
            var b = {};
            for (var i = 0; i < a.length; ++i) {
                var p=a[i].split('=', 2);
                if (p.length == 1)
                    b[p[0]] = "";
                else
                    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
            }
            return b;
        }) (window.location.search.substr(1).split('&'));       
        return qs[param];
    }
    function httpGet(theUrl, type, round) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
    		if (this.readyState == 4 && this.status == 200) {
				if (type == "text" || !round)
					currentValue = xmlHttp.responseText;
				else {
					currentValue = xmlHttp.responseText.split(' ')[1];
					currentValue = Math.round(parseFloat(xmlHttp.responseText)) + (currentValue ? " " + currentValue : "");
				}
		    	document.getElementById('textInput').value = currentValue;
		    }
		};
        xmlHttp.open("GET", theUrl, true);
        xmlHttp.setRequestHeader("Accept", "text/plain");
        xmlHttp.send();
        return 
    }
    function httpPut(theUrl, theValue) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("PUT", theUrl, true);
        xmlHttp.setRequestHeader("Content-type", "text/plain");
        xmlHttp.setRequestHeader("Accept", "application/json");
        xmlHttp.send(theValue);
    }
    function httpPost(theUrl, theValue) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("POST", theUrl, true);
        xmlHttp.setRequestHeader("Content-type", "text/plain");
        xmlHttp.setRequestHeader("Accept", "application/json");
        xmlHttp.send(theValue);
    }
	function getValue() {
        url = "../rest/items/" + getParam('item') + "/state";
		type = getParam('type');
		round = (getParam('round') == "" || getParam('type') == 'int' || getParam('type') == 'integer') ? true : false;
        httpGet(url, type, round);
    }
	function sendValue() {
		if (getParam('command') !== 'Undefined')
			postCommand();
		else
			updateState();
	}
	function updateState() {
        url = "../rest/items/" + getParam('item') + "/state";
        httpPut(url, document.getElementById('textInput').value);
    }
	function postCommand() {
        url = "../rest/items/" + getParam('item');
        httpPost(url, document.getElementById('textInput').value);
    }
</script>

<head>
	<link rel="stylesheet" type="text/css" href="../basicui/mdl/material.min.css" />
	<link rel="stylesheet" type="text/css" href="../basicui/material-icons.css" />
	<link rel="stylesheet" type="text/css" href="../basicui/roboto.css" />
	<link rel="stylesheet" type="text/css" href="../basicui/smarthome.css" />
	<script src="../basicui/mdl/material.min.js"></script>
	
	<style>
		form {
			margin-bottom: 0;
		}
		.mdl-form__row {
			border-bottom-style: none;
			height: auto;
			padding-top: 0;
			padding-right: 0;
			padding-bottom: 0;
			padding-left: 0;
		}
	</style>
</head>
<body class="mdl-color-text--grey-700" data-icon-type="svg">
	<form action="JavaScript:sendValue()">
		<div class="mdl-form__row mdl-cell mdl-cell--6-col mdl-cell--8-col-tablet">
			<span class="mdl-form__icon" id=icon>
			</span>
			<div class="mdl-form__label" id=label>
			</div>
			<div>
				<input type="text" name="textInput" id="textInput">
			</div>
			<div>
				<input type="submit" value="Submit">
			</div>
		</div>
		<script>
			document.getElementById('label').innerHTML = getParam('label');
			document.getElementById('icon').innerHTML = "<img data-icon=line src=../icon/" + getParam('icon') + "?format=svg/>";
			document.getElementById('textInput').value = getValue();
		</script>
	</form>
</body>

Here is a corrected version that will show the values correctly.

1 Like

Unfortunately, I don’t know much about HTML and CSS. I hacked this together, and it works well for me. But I don’t know how to improve the layout much.

You can simply set height as a parameter to the Webview element, like this:

Webview url="../static/textinput.html?item=PVEtotalGS1&label=Correctie%20GS1&icon=line&round" height=1 icon=none

it’s working thank u!

oh now @Mherwege the item state is not changing corectly no whater if i put &command or not.

Item 'RadiatorAC1_WorkdaysSchedule' received command 00:00/12°C 09:00/15°C 11:30/15°C 12:30/15°C 17:30/19°C 22:00/19°C
2022-10-07 21:29:02.497 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'RadiatorAC1_WorkdaysSchedule' predicted to become NULL

 Webview label="Dni robocze" url="../static/textInput.html?item=RadiatorAC1_WorkdaysSchedule&type=text&label=DzienRoboczy" height=1 icon=none
                Webview label="Dni wolne" url="../static/textInput.html?item=RadiatorAC1_HolidaysSchedule&type=text&label=DzienWolny" height=1 icon=none

@Jacek_Kaczmarczyk Did you try with a simpler string? It seems to go wring between receiving the command and the item update. This may be unrelated to the sitemap element.

ok/
1/ if the value is NULL it gives always :
Item ‘RadiatorAC1_WorkdaysSchedule’ received command test
2022-10-07 21:47:45.220 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item ‘RadiatorAC1_WorkdaysSchedule’ predicted to become NULL
2/ if the value is string it works right away and i can change this value

it’s the same when i am doing it from java script
items.getItem(‘RadiatorAC1_WorkdaysSchedule’).sendCommand(“test”)

so the problem is not in your inputhtml :slight_smile:
edit

the inputhtml script after rermoving &command still is sendindg a sendCommand instead of postUpdate

of i commented out

 function sendValue() {
        //if (getParam('command') !== 'Undefined')
        //    postCommand();
        //else
            updateState();
    }

items are updated and postCommand is send, so i thing the problem is in ‘if (getParam(‘command’) !== ‘Undefined’)’

Indeed, there was an error in this check.

This version should do better, and make the presence/absence of the command parameter work as documented.

<html class='ui-icons-enabled'>

<script>
    function getParam(param) {
        var qs = (function(a) {
            if (a == '') return {};
            var b = {};
            for (var i = 0; i < a.length; ++i) {
                var p=a[i].split('=', 2);
                if (p.length == 1)
                    b[p[0]] = '';
                else
                    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, ' '));
            }
            return b;
        }) (window.location.search.substr(1).split('&'));       
        return qs[param];
    }
    function httpGet(theUrl, type, round) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
    		if (this.readyState == 4 && this.status == 200) {
				if (type == 'text' || !round)
					currentValue = xmlHttp.responseText;
				else {
					currentValue = xmlHttp.responseText.split(' ')[1];
					currentValue = Math.round(parseFloat(xmlHttp.responseText)) + (currentValue ? ' ' + currentValue : '');
				}
		    	document.getElementById('textInput').value = currentValue;
		    }
		};
        xmlHttp.open('GET', theUrl, true);
        xmlHttp.setRequestHeader('Accept', 'text/plain');
        xmlHttp.send();
        return 
    }
    function httpPut(theUrl, theValue) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open('PUT', theUrl, true);
        xmlHttp.setRequestHeader('Content-type', 'text/plain');
        xmlHttp.setRequestHeader('Accept', 'application/json');
        xmlHttp.send(theValue);
    }
    function httpPost(theUrl, theValue) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open('POST', theUrl, true);
        xmlHttp.setRequestHeader('Content-type', 'text/plain');
        xmlHttp.setRequestHeader('Accept', 'application/json');
        xmlHttp.send(theValue);
    }
	function getValue() {
        url = '../rest/items/' + getParam('item') + '/state';
		type = getParam('type');
		round = (getParam('round') == '' || getParam('type') == 'int' || getParam('type') == 'integer') ? true : false;
        httpGet(url, type, round);
    }
	function sendValue() {
		if (getParam('command') == '')
			postCommand();
		else
			updateState();
	}
	function updateState() {
        url = '../rest/items/' + getParam('item') + '/state';
        httpPut(url, document.getElementById('textInput').value);
    }
	function postCommand() {
        url = '../rest/items/' + getParam('item');
        httpPost(url, document.getElementById('textInput').value);
    }
</script>

<head>
	<link rel='stylesheet' type='text/css' href='../basicui/mdl/material.min.css' />
	<link rel='stylesheet' type='text/css' href='../basicui/material-icons.css' />
	<link rel='stylesheet' type='text/css' href='../basicui/roboto.css' />
	<link rel='stylesheet' type='text/css' href='../basicui/smarthome.css' />
	<script src='../basicui/mdl/material.min.js'></script>
	
	<style>
		form {
			margin-bottom: 0;
		}
		.mdl-form__row {
			border-bottom-style: none;
			height: auto;
			padding-top: 0;
			padding-right: 0;
			padding-bottom: 0;
			padding-left: 0;
		}
	</style>
</head>
<body class='mdl-color-text--grey-700' data-icon-type='svg'>
	<form action='JavaScript:sendValue()'>
		<div class='mdl-form__row mdl-cell mdl-cell--6-col mdl-cell--8-col-tablet'>
			<span class='mdl-form__icon' id=icon>
			</span>
			<div class='mdl-form__label' id=label>
			</div>
			<div>
				<input type='text' name='textInput' id='textInput'>
			</div>
			<div>
				<input type='submit' value='Submit'>
			</div>
		</div>
		<script>
			document.getElementById('label').innerHTML = getParam('label');
			document.getElementById('icon').innerHTML = '<img data-icon=line src=../icon/' + getParam('icon') + '?format=svg/>';
			document.getElementById('textInput').value = getValue();
		</script>
	</form>
</body>

Hi, get the first Script and tried to manage it to run on actual OH3 v3.3.0 stable. Was not possible first, I changed some things and it runs now.
This is the html file textInput.html (in OPENHAB_DIR\config\html)

<html>
<script language="JavaScript">
    function getParam(param)
    {
        var qs = (function(a) {
            if (a == "") return {};
            var b = {};
            for (var i = 0; i < a.length; ++i)
            {
                var p=a[i].split('=', 2);
                if (p.length == 1)
                    b[p[0]] = "";
                else
                    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
            }
            return b;
        })(window.location.search.substr(1).split('&'));       
        return qs[param]
    }
    function checkInput(id)
    {
        var x=document.getElementById(id).value;
        if (isNaN(x)) 
        {   document.getElementById(id).value = ""
            return false;
        }
        else
        {   return true;
        }
    }
    function resetInput(id)
    {
        document.getElementById(id).value = ""
    }
    function httpGetAsync(theUrl)
    {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", theUrl, false); // true for asynchronous 
        xmlHttp.send(null);
    }
    function sendValue() {
        if (checkInput('textInput')) {
            url = "http://ip-address:8080/basicui/CMD?" + getParam('item') + "=" + document.getElementById('textInput').value
            httpGetAsync(url)
            resetInput('textInput')
        } else {
            resetInput('textInput')
        }
    }
</script>
<form>
     <img src="http://ip-address:8080/icon/text?format=svg&anyFormat=true" height="20">Value:<input name="textInput" id="textInput" type="number" step="1" onChange="sendValue()">
</form>
</html>

This is the part of sitemap:

your code goes here
Webview url="http://ip-address:8080/static/textInput.html?item=ItemID" height=3

Here is my version that is a combination of the previous reply and some of the earlier versions where the label next to the input box can be passed dynamically from the sitemap. Also the input text is properly encoded for the request query string. Previous versions did not have this preventing characters such as , / ? : @ & = + $ * # from being sent.

HTML file textInput.html (in OPENHAB_DIR\conf\html)

<html>
<script>
    function getParam(param) {
        var qs = (function(a) {
            if (a == "") return {};
            var b = {};
            for (var i = 0; i < a.length; ++i) {
                var p=a[i].split('=', 2);
                if (p.length == 1)
                    b[p[0]] = "";
                else
                    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
            }
            return b;
        })(window.location.search.substr(1).split('&'));
        return qs[param];
    }

    function resetInput(id) {
        document.getElementById(id).value = "";
    }

    function httpGetAsync(theUrl) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", theUrl, false); // true for asynchronous
        xmlHttp.send(null);
    }

    function sendValue() {
        if (document.getElementById('textInput').value) {
            inputStr = encodeURIComponent(document.getElementById('textInput').value);

            httpGetAsync("http://" + location.host + "/basicui/CMD?" + getParam('item') + "=" + inputStr);
            resetInput('textInput');
        } else {
            resetInput('textInput');
        }
    }
</script>
<body onload="document.getElementById('textLabel').innerHTML = getParam('label');">
    <form action="javascript:sendValue()">
        <div>
            <span id="textLabel"></span>
            <input type="text" name="textInput" id="textInput">
            <input type="submit" value="Submit">
        </div>
    </form>
</body>
</html>

sitemap entry:

Webview url="/static/textinput.html?item=ItemID&label=Search" height=3 icon="zoom"

OH4 sitemaps now support an input field that can be used in BasicUI and the Android app. See documentation.

1 Like

Does anyone know when the functionality of input fields will be available for iOS?