Code editor isn't saving text

Hello, I'm creating a custom configuration node which uses a multiline code editor. However, the text entered into the editor isn't saving. Based on the instructions, I have the following:

HTML element

<div id="node-config-input-pttns" style="height:20em" class="node-text-editor"></div>

Defaults

pttns: {
                value: "^https:\/\/",
            },

Editor functions:

oneditprepare: function () {
            this.editor = RED.editor.createEditor({
                id: "node-config-input-pttns",
                mode: "ace/mode/text",
                value: this.pttns ?? "",
            });
        },
        oneditsave: function () {
            const val = this.editor.getValue();
            this.pttns = val ?? "^https:\/\/";
            console.log("val | pttns", val, this.pttns);
            this.editor.destroy();
            delete this.editor;
            console.log("oneditsave", this);
        },
        oneditcancel: function () {
            this.editor.destroy();
            delete this.editor;
        },

You can see I've added a few console logs to try to debug the values. There are a few issues that I've been wracking my head trying to fix:

  1. The original value of ^https:\/\/ isn't loaded into the editor.
  2. The new value entered into the editor is picked up by getValue() and this.pttns is re-assigned locally, but logging this separately shows an empty pttns attribute.
  3. The value is not persisted inside the flow json.
  4. No errors are thrown on the client or the server.

What've I done wrong, how can I further debug this? Thanks

Show us the debug output.

Also, add a few more debug entries...

        oneditprepare: function () {
            console.log('this.pttns before creating editor', this.pttns)
            this.editor = RED.editor.createEditor({
                id: "node-config-input-pttns",
                mode: "ace/mode/text",
                value: this.pttns ?? "",
            });
        },
        oneditsave: function () {
            const val = this.editor.getValue();
            console.log("this.editor.getValue", val);
            this.pttns = val ?? "^https:\/\/";
            console.log("this.pttns", this.pttns);
            this.editor.destroy();
            delete this.editor;
            console.log("oneditsave", this);
        },
        oneditcancel: function () {
            this.editor.destroy();
            delete this.editor;
        },

Also, show us more of the beginning of the nodes HTML (ie from the beginning to just after where you have placed the defaults object)

Thanks, I've put the updated HTML file at the end of this message. Here's the input in the editor:

image

Here's the browser console (the server console shows nothing after 'Started flows'):

this.pttns before creating editor ^https://
VM1310:29 this.editor.getValue ^https://
lineTwo
VM1310:34 oneditsave {id: '3028200a0a73374a', type: 'urlAllowlist', info: undefined, users: Array(1), _config: {…}, …}

where the pttns attribute on the last object is not updated:

image

HTML File

<script type="text/javascript">
    RED.nodes.registerType("urlAllowlist", {
        category: "config",
        defaults: {
            name: {
                value: "",
                required: true,
                validate: function (v) {
                    return v && v?.length;
                },
            },
            pttns: {
                value: "^https:\/\/",
            },
        },
        label: function () {
            return this.name ?? "urlAllowlist";
        },
        oneditprepare: function () {
            console.log('this.pttns before creating editor', this.pttns)
            this.editor = RED.editor.createEditor({
                id: "node-config-input-pttns",
                mode: "ace/mode/text",
                value: this.pttns ?? "",
            });
        },
        oneditsave: function () {
            const val = this.editor.getValue();
            console.log("this.editor.getValue", val, this.editor);
            this.pttns = val ?? ".+";
            console.log("this.pttns", this.pttns);
            this.editor.destroy();
            delete this.editor;
            console.log("oneditsave", this);
        },
        oneditcancel: function () {
            this.editor.destroy();
            delete this.editor;
        },
    });
</script>

<script type="text/html" data-template-name="urlAllowlist">
    <style>
        textarea {
            width: 100%;
        }
        .form-tips {
            display: none;
        }
        .form-row:has(:is(input, textarea):focus) + .form-tips:not(:empty) {
            display: block;
            margin-bottom: 0.5em;
        }
    </style>

    <div class="form-row">
        <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-config-input-name" placeholder="urlAllowlist" />
    </div>
    <div class="form-tips"><b>ℹ️ Tip:</b> A useful name to refer to this list.</div>

    <div class="form-row">
        <label for="node-config-input-pttns"><i class="fa fa-list"></i> Patterns</label>
        <div id="node-config-input-pttns" style="height:20em" class="node-text-editor"></div>
    </div>
    <div class="form-tips">
        <b>ℹ️ Tip:</b>
        Regular expression patterns to test URLs against, one per line.
    </div>
    <div class="form-row" style="margin-top:1em;">
        <p>
            Use <a href="https://regex101.com" target="_blank"><u>regex101.com</u></a> to test
            patterns.
        </p>
    </div>
</script>

<script type="text/html" data-help-name="urlAllowlist">
    <p>
        Enter <a href="https://regex101.com" target="_blank">regular expression</a> patterns to test
        URLs against, one per line.
    </p>
</script>

2 choices.

  1. Rename the id node-config-input-pttns to something like pttns-editor

Or

  1. Add a hidden element with the id of node-config-input-pttns and set it's value in oneditsave
    $('node-config-input-pttns').val(val)

The issue is node-config-input-pttns is bound to the defaults.pttns but the element never updated. So when the form closes, the defaults.pttn is set the the val() of the element (which is never updated). So the choices are don't add the html element or set the html element value manually.

1 Like

brill! I was assuming that the binding to the node-config- ID would update when the editor was triggered, but obviously not. I went with option 1. Thank you :slight_smile:

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