In need of some help - Modal text input with cancel

Hi folks,

I'm currently building a little test rig to test an assembled PCB, my manager suggested I use Code Red as I was planning on using a Raspberry pi to do all the control and UI. I had been planning on using .NET but OK I thought, I'd give it a go.

All the hardware is assembled, I've designed and built my fixture with bed of nails, I've designed and 3D printed a holder for my ST Link programmer and bracket for a little 7" touch screen for the pi . . .

I've created some test flows to prove out what I thought would be the tricky bits, like using the ST Link programmer to program the device and some serial comms stuff and string bashing . . . that's all working.

I've created my state machine to control the test sequence, it's almost ready to test, I need to finish up the wiring and then I can test and debug it . . . so it's going OK, but . . . I've not got a satisfactory way to handle the QR Code scanner input.

The scanner behaves like a keyboard, if I connect it to the pi USB and open a text input node and scan a QR code the text shows up in the input, great, but my issue is what happens if my end user clicks away from the txt input box before they scan . . . If I were doing this in LabVIEW I'd create a modal window that keeps focus and looks for a new line at the end of the string, when it sees that it sends the string through and closes. I'd also have an optional Cancel button so the user can abort the process.

I know Node Red can't do this . . . there isn't a Node to do it, perhaps it could be added to a Template, I saw this thread (How to show modal dialog in template node) but it isn't doing what I need and my Java is limited to doing some basic number crunching and string bashing.

If anyone would like to help a poor soul out I'd be grateful, or maybe just give me some pointers at what I should be looking at.

If a Modal isn't feasible then is there any way to get my QR Code txt input to keep focus until it has valid input ? I found something using a Template but couldn't get it to work (!topic/node-red/Ip6bAnh01t0)

thanks in advance. :+1:

Simon G

I've not got a satisfactory way to handle the QR Code scanner input.

did you search for qr in the flow tab?

The ui-notification offers an OK/Cancel type modal

thank heavens that Node-RED use javascript


No I didn't, but the fact that the data is coming from a Barcode/QR code scanner is incidental, the code comes through just as if it were being typed on a keyboard . . .

I looked this morning and the QR stuff seems to be about decoding an image of a QR code . . .

"Node-RED node to read QR code image", "node for decoding qr code from an image file" , "VISEO Bot Maker - Decodes a given QrCode",

. . . my barcode scanner does that for me, I just need to handle the text it generates.

:wink: I'm happy to display my ignorance for all to see, I should really have said "my java* is limited to . . ."


Correct me if i'm wrong but isn't that an output node ? I need to get a string input, with the option of a Cancel button.

Would there be a way of using a html 5 dialogue ? similar to what is shown in the "Returning a value from dialog" example. I'd want the dialog to fire as a result of my flow rather than the user having to hit a button.

Something like this would probably work but I'm not sure how to use it in Node Red . . .

<!DOCTYPE html>

<p>Click the buttons to show and/or close the dialog window.</p>

<button onclick="showDialog()">Show dialog</button>
<button onclick="closeDialog()">Close dialog</button>

<p><b>Note:</b> The dialog element is only supported in Chrome 37+, Safari 6+ and Opera 24+.</p>

<dialog id="myDialog">
<h3>Please scan the QR Code</h3>
			<p>Please do not click on the screen, the cursor must be in the box while scanning the code</p>
			<input type="text" id="return_value" value="" placeholder="Enter value" onkeypress="myFunction(event)"></dialog>
var x = document.getElementById("myDialog"); 

function showDialog() {; 

function closeDialog() { 

function myFunction(event) 
  	if (event.keyCode === 13) 


I don't want the Show dialog or Close dialog buttons I want the Dialog to show due to my flow . . .

So I guess that isn't possible either . . . next plan . . .

So I've played a little, a tiny little bit, with Mono on the pi, it seemed to work OK, so I created a modal form application in C# (don't know any C#) so strugged to do even the simplest things . . . but got there in the end, this will run on the Raspberry pi under mono, it even returns a value just like I needed.

So I created a flow to test it and can't get it to execute using the exec node . . . . I get a stack of errors thrown.

I guess I need a raspberry pi native EXE

This should get you started...

[{"id":"d7d1671e.9b2f88","type":"ui_template","z":"56fa9896.d15ed8","group":"dfb4a60f.d788f8","name":"","order":1,"width":"12","height":"7","format":"<div ng-bind-html=\"msg.payload\">\n</div>    \n    \n    \n\n<p>Click the buttons to show and/or close the dialog window.</p>\n\n<button onclick=\"showDialog()\">Show dialog</button>\n<button onclick=\"closeDialog()\">Close dialog</button>\n\n<p><b>Note:</b> The dialog element is only supported in Chrome 37+, Safari 6+ and Opera 24+.</p>\n\n<dialog id=\"myDialog\">\n<h3>Please scan the QR Code</h3>\n\t\t\t<p>Please do not click on the screen, the cursor must be in the box while scanning the code</p>\n\t\t\t<input type=\"text\" id=\"return_value\" value=\"\" placeholder=\"Enter value\" onkeypress=\"myFunction(event)\"></dialog>\n<script>\nvar theScope = scope;\nvar x = document.getElementById(\"myDialog\"); \n\nfunction showDialog() { \n; \n} \n\nfunction closeDialog() { \n  x.close(); \n} \n\nfunction myFunction(event) \n\t{\n\t    console.log(event)\n  \tif (event.keyCode === 13) \n  \t\t{\n  \t\t    var data = $(\"#return_value\").val();\n\t    console.log(\"sending value:\",data)\n\t    theScope.send({payload:data});\n        \tx.close();\n\t\t}\n  \t}\n</script>\n    \n    ","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":620,"y":140,"wires":[["afd9fd14.bf0d5"]]},{"id":"afd9fd14.bf0d5","type":"debug","z":"56fa9896.d15ed8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":770,"y":140,"wires":[]},{"id":"dfb4a60f.d788f8","type":"ui_group","z":"","name":"Barcode","tab":"48418b79.0f5834","disp":true,"width":"12","collapse":false},{"id":"48418b79.0f5834","type":"ui_tab","z":"","name":"Dashboard","icon":"dashboard","order":1}]

Copy the above flow, open your node-red, press ctrl+i, paste in the flow, deploy the flow, open the dashboard (ctrl+shift+d).

It may not be entirely what you want but it should get you started.

When the enter button is pressed (by you or the scanner) a msg will be sent to the debug window. Use the output in msg.payload to do what you need.

Thanks Steve,

I made some mods and got the dialog to open automatically when the template was triggered by an inject node . . . it's still not what I would ideally like, it doesn't retain focus so there is still scope for the user to get things wrong, the whole point of trying to use a dialog was for it to be modal and retain focus, this would mean that the user couldn't leave this text input without either scanning the QR code or clicking Cancel.

I tried coding something in Python, I could call it from a terminal window but not from an Exec node . . .

Next I've tried creating a loop with a dashboard text input and button (for the cancel), the idea being that until I get a CR terminated string, either from the text input or from the Cancel button I'll keep triggering the text input in an attempt to keep focus on it . . . but that doesn't work for a couple of reasons: the text input doesn't allow me to input a CR terminated string, and it strips it when I send it in from my QR code reader . . . plus the focus is not maintained when the loop returns back to the text input. I guess I can try a different termination character, my QR Code string, when correct, will end with a number so I could terminate with "=".

You could simply add a bit script so that when the input box loses focus, you simply set focus once more.

<script type="text/javascript">
    var element= document.getElementById('return_value');
    element.onblur= function() {
        setTimeout(function() {
        }, 0);