Using a touchscreen to add waypoints on Node-Red-WorldMap Dashboard UI

Hello I'm building a project that requires a user to add waypoints onto a world map component through the UI using a touchscreen display. The node-red project is being run on a Raspbian OS on a Raspberry Pi 4.

When initially testing everything I was using a mouse and keyboard to add waypoints and had no trouble since it was just right-clicking on the map, entering the name of the waypoint and pressing enter. As you can see here:

However, once I switch to using a touchscreen it's not as simple. The main issue being able to enter the name of the waypoint and hit an enter key. I've tried using virtual keyboard packages such as: matchbox, florence, and onboard and the only one that seems to work is florence, but that dashboard is meant to run the browser in fullscreen kiosk mode and florence wont display above the browser.

I've also tried some chrome virtual keyboard extensions but the only that that was close to working was Native Virtual On-Screen Keyboard. It could function in fullscreen mode recognize that the waypoint name was a text input, but clicking enter was not the same as pressing enter on my keyboard.

Now I'm stuck here trying to figure out other options or if there's actually a setting that adds a button to the waypoint that would add it to the map.

Thank you for taking the time to read this.

You need to look into the section on Utility functions ---> https://github.com/dceejay/RedMap#utility-functions

This way you can create a button to submit

You can do allot with it. You can even have it send a payload without closing so you can create drop down menus that are loaded from selections! Here is a gif of how I use it to add a camera from motioneye.
Hnet-image

Here is some example code showing the use of a drop down

var menu ='<select name="dropdown" onChange=\'addToForm(this.name,this.value)\'><option value="">Select an Option</option><option value="user selected option 1">Option 1</option><option value="user selected option 2">Option 2</option></select><br/>'
menu += 'Add some data <input name="foo" onchange=\'addToForm(this.name,this.value)\'></input><br/>'
menu += 'Add more data <input name="bar" onchange=\'addToForm(this.name,this.value)\'></input><br/>'
menu += '<button name="my_form" onclick=\'feedback(this.name,"$form",null,true)\'>Submit</button>'

msg.payload = { command: { "contextmenu":menu } }
return msg;

hope this helps

oh and Tap-and-hold (long press): Equivalent to right mouse click on android. This should allow you to get the context menu up for the location you want to add a way-point for.

Thank you for the response I really appreciate the help. I'm still quite new to node-red so the example drop-down code snippet would be something I would put into a function node and then connect that to the ui_worldmap node to get the drop down?

Also I was able to solve the right-click context menu using the evdev-right-click-emulation package.

Import this flow

[
    {
        "id": "972e922f5507a5cc",
        "type": "tab",
        "label": "exampleMAP",
        "disabled": false,
        "info": ""
    },
    {
        "id": "0f03f7dedce7464f",
        "type": "worldmap",
        "z": "972e922f5507a5cc",
        "name": "",
        "lat": "",
        "lon": "",
        "zoom": "",
        "layer": "",
        "cluster": "",
        "maxage": "",
        "usermenu": "show",
        "layers": "show",
        "panit": "false",
        "panlock": "false",
        "zoomlock": "false",
        "hiderightclick": "false",
        "coords": "none",
        "showgrid": "false",
        "allowFileDrop": "false",
        "path": "/example-map",
        "mapname": "",
        "mapurl": "",
        "mapopt": "",
        "mapwms": false,
        "x": 840,
        "y": 120,
        "wires": []
    },
    {
        "id": "f363bf77c609f47d",
        "type": "worldmap in",
        "z": "972e922f5507a5cc",
        "name": "",
        "path": "/example-map",
        "events": "all",
        "x": 130,
        "y": 80,
        "wires": [
            [
                "a2235f4f4eaacea0",
                "396c37ab27050d05"
            ]
        ]
    },
    {
        "id": "ddb61c0ed1e3b237",
        "type": "function",
        "z": "972e922f5507a5cc",
        "name": "",
        "func": "var menu ='enter waypoint</br>'; \nmenu += '<input name=\"waypointValue\" onchange=\\'addToForm(this.name,this.value)\\'></input><br/>'\nmenu +='<center>'\nmenu +='<button name=\"my_form\" onclick=\\'feedback(this.name,\"$form\",null,true)\\'>Submit</button>'\nmenu +='</center>'\nmsg.payload = { command: { \"contextmenu\":menu } }\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 640,
        "y": 120,
        "wires": [
            [
                "0f03f7dedce7464f"
            ]
        ]
    },
    {
        "id": "a2235f4f4eaacea0",
        "type": "switch",
        "z": "972e922f5507a5cc",
        "name": "action: connected?",
        "property": "payload.action",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "connected",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 430,
        "y": 120,
        "wires": [
            [
                "ddb61c0ed1e3b237"
            ]
        ]
    },
    {
        "id": "de115f9821383567",
        "type": "debug",
        "z": "972e922f5507a5cc",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 80,
        "wires": []
    },
    {
        "id": "396c37ab27050d05",
        "type": "switch",
        "z": "972e922f5507a5cc",
        "name": "action: feedback?",
        "property": "payload.action",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "feedback",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 430,
        "y": 80,
        "wires": [
            [
                "de115f9821383567"
            ]
        ]
    }
]

http://your-ip-here:1880/example-map/ is where i put the example map

Screenshot from 2021-10-05 23-39-30

now you could set up some logic to auto fill the form. so if no waypoints are set it will use waypoint-01 and start counting up from there for the user as it adds them. the logic for this stuff can get pretty nutty at times.

you will need to get real close and comfy with the function node if your going to be doing big things with the world map.

I'm starting to understand this bit by bit but I can work on that flow you sent. Right now it doesn't put a waypoint but the context menu with the submit shows and returns a payload message with the object that contains the latitude, longitude, and name of the waypoint I can rework that get current location flow that I have and use it here to add onto the map.

I really appreciate the help and I'll get back to you once I'm done, thank you!

1 Like

correct it does not put it on the map :stuck_out_tongue:

I was trying to give you the minimum needed to get your brain revved up.

to add it to the map after you handle the logic coming out use a function node to create a marker.

here is a hint below showing allot of options you can use to create a marker

msg.payload = {
    "name":'The Way-point var containing the value the user gave here!',
    "layer":"waypoints",
    "lat":camLatVarHere,
    "lon":camLonVarHere,
    "icon":"fa-video-camera",
    "iconColor":"forestgreen",
    "photoUrl":"http://link-to-a-photo-here",
    "weblink":[
        {
            "name":'send user to this url #1',
            "url":'https://google.com',
            "target":"_new"
        },
        {
            "name":'send user to this url #2',
            "url":'https://nodered.org',
            "target":"_new"
        }]
};

if you get stuck ill complete the next step for you tomorrow night :heartbeat:

1 Like

I was able to get it to add the waypoint as you can see:

Although a new problem has shown up now, the chrome extension I'm using doesn't recognize this as a valid text field meaning that keyboard won't pop up. I'm not exactly sure what to do here.

This is how the extension looks like when it recognizes a valid input:

html input types might help you...
https://www.w3schools.com/html/html_form_input_types.asp

in the function node try changing it to this....

var menu ='enter waypoint</br>'; 
menu += '<input type="text" name="waypointValue" onchange=\'addToForm(this.name,this.value)\'></input><br/>'
menu +='<center>'
menu +='<button name="my_form" onclick=\'feedback(this.name,"$form",null,true)\'>Submit</button>'
menu +='</center>'
msg.payload = { command: { "contextmenu":menu } }
return msg;

its allot to take in at once. what this function node is doing is replacing the stock worldmap html with your own custom stuff. So it helps to know some html as well.

1 Like

Man all the headache this caused and you managed to fix it instantly. Changing the input type was the call.

Thank you so much for the help!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.