Multi-line text editor on the dashboard

I want to build a simple text editor on the dashboard. I thought the dashboard text input supports multi-line, but it does not. Also it would be extra sweet if it would support syntax highlight, for example if I edit shell scripts, or JSON files.

When I search for this, all the results are on the editor in the Node-Red editor itself. Feels like nobody needed this before. Any ideas how this could be done?

For a text-only multi-line input, you need a <textarea> tag which you can add to a Dashboard using the ui_template node if there isn't already a convenient node.

: The Textarea element - HTML: HyperText Markup Language | MDN (mozilla.org)

But if you want syntax highlighting, that is more complex and you will need the help of an extra library. What you need and how complex depends on whether you want people to edit the text and be able to edit code blocks like you can in the description tab in a node:

For that, you need a suitable Markdown editor. The most common library for that is Markdown-IT. Which I allow to be used on uibuilder output (you still need to load the library).

markdown-it/markdown-it: Markdown parser, done right. 100% CommonMark support, extensions, syntax plugins & high speed (github.com)

BTW, the description edit panels and similar actually use Microsoft's Monaco editor which is the web version of VScode. You could use that instead of Markdown-IT but it results in a MUCH bigger page.

2 Likes

Thanks. I may just keep is simple and use <textarea> with some javascript code to keep sending a message when the content changes, and maybe have another ui-template on the side which does the highlighted preview. Like here when I add a post/reply.
I just found this: How to use highlight.js maybe this could be useful

Ui-form allows multiple line input

1 Like

This highlight.js looks fairly simple to implement. I put this into a ui-tempate node:

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<script>
    hljs.highlightAll();
</script>

<div ng-bind-html="msg.payload"></div>
<pre><code id="highlightpreview">
#!/bin/bash

###### CONFIG
ACCEPTED_HOSTS="/root/.hag_accepted.conf"
BE_VERBOSE=false

if [ "$UID" -ne 0 ]
then
echo "Superuser rights required"
exit 2
fi

genApacheConf(){
echo -e "# Host ${HOME_DIR}$1/$2 :"
}

echo '"quoted"' | tr -d \" > text.txt
    </code></pre>

And I got this:
image

I say, a fairly decent syntax highlight.

Now I created another template node with a text area and a button. And I just wanted to replace the innerHTML of the <code id="highlightpreview"> with the text. And as soon as I add the script to this template as well, the syntax highlight does not work. Do I need to move all my <script> section into a single template node?
Also do you know how to create and event handler which does not every time the text in the textarea changes? Ideally I would also send these changes back to Node-Red as well.

@E1cid: ui-form is OK, but it only submits on the submit button press, so I can't do preview.

I forgot to add my flow:

[
    {
        "id": "0c5ac31dc4748b62",
        "type": "ui_template",
        "z": "74f191ff.db063",
        "group": "e84cebe8384622b0",
        "name": "Preview",
        "order": 1,
        "width": "12",
        "height": "10",
        "format": "<link rel=\"stylesheet\" href=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css\">\n<script src=\"//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js\"></script>\n<script>\n    hljs.highlightAll();\n</script>\n\n<div ng-bind-html=\"msg.payload\"></div>\n<pre><code id=\"highlightpreview\">\n#!/bin/bash\n\n###### CONFIG\nACCEPTED_HOSTS=\"/root/.hag_accepted.conf\"\nBE_VERBOSE=false\n\nif [ \"$UID\" -ne 0 ]\nthen\necho \"Superuser rights required\"\nexit 2\nfi\n\ngenApacheConf(){\necho -e \"# Host ${HOME_DIR}$1/$2 :\"\n}\n\necho '\"quoted\"' | tr -d \\\" > text.txt\n    </code></pre>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 2480,
        "y": 4420,
        "wires": [
            []
        ]
    },
    {
        "id": "30c334c98b3fdae4",
        "type": "ui_template",
        "z": "74f191ff.db063",
        "group": "e84cebe8384622b0",
        "name": "Textarea",
        "order": 1,
        "width": "12",
        "height": "10",
        "format": "<textarea id=\"texteditor\"  width=\"100%\" rows=\"12\" >{{msg.payload}}</textarea>\n<button type=\"button\" onclick=\"updatepreview();\">Update</button>\n\n<script>\n\n\nupdatepreview = function() {\n\n    var text = document.getElementById(\"texteditor\").value;\n    document.getElementById(\"highlightpreview\").innerHTML = text;\n    // scope.send({payload:text})\n    return;\n}\n\n    \n\n\n</script>\n\n",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 2300,
        "y": 4420,
        "wires": [
            []
        ]
    },
    {
        "id": "e84cebe8384622b0",
        "type": "ui_group",
        "name": "File Editor",
        "tab": "aa01ccb9a2401b9a",
        "order": 1,
        "disp": true,
        "width": "24",
        "collapse": false,
        "className": ""
    },
    {
        "id": "aa01ccb9a2401b9a",
        "type": "ui_tab",
        "name": "File Editor",
        "icon": "dashboard",
        "disabled": false,
        "hidden": false
    }
]

Btw, who do I make this to appear in a single line?

compact

1 Like

There is also a setting in the settings.js flowFilePretty: false, which means you don't have to select compact each time.

Actually, I meant that here in the forum (or in Guthub). Sometimes the flow is show as a single line and not expanded like in my case.

I know what you meant. You need to output from node-red as non pretty to paste here or github, The setting I pointed out means you don't have to remember each time to press compact when exporting.

2 Likes

See this latest contribution. [Announce] node-red-contrib-ui-editor

Ooh, nice - and timely :slight_smile:

I'll certainly be looking at that for inspiration for uibuilder as well :thinking:

You mean the ui-editor? Or highlight.js?

How EditorJS has been implemented for Dashboard. Certainly an editable block component is on my backlog for uibuilder. Generally, I prefer Markdown which uibuilder already supports for output but I'm always open for ideas.

Looks like it wouldn't be very hard to implement EditorJS for uibuilder. But not sure when I could get to look at it in detail. I've been learning more about draggable elements and grid layouts this week in between helping deal with a major Cyber incident and supporting our 3-org merger So time and focus has been rather minimal.

1 Like

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