Input type checkbox

ok, so firstly, as I said before...

I even went to the effort to provide an example of how to handle that...

... but you have ignore it and stayed with generating objects with a fixed ID.


never mind!


A solution, take it or leave it...

NOTE: I dont know what is inside data but I can see there is at least a .name and a .address property so i will use them in my example.


STEPS...

  1. Add a property for storing client side values [client side HTML] Firstly, you need somewhere for the values to be stored (at the HTML side). Add a property to the defaults. At the beginning of the HTML node script, you will have something like the below script. Add a property called dynamicOptions.
    NOTE: this is essential if you want to get your values into the server side JS
RED.nodes.registerType('mynode', {
    category: "input",
    icon: "timer.png",
    color: "#a6bbcf",
    inputs: 1,
    outputs: 1,
    defaults: {
        name: { value: "" },
        dynamicOptions: { value: [] }, //<< Add property to hold users node settings
    },
    ...,
    

  1. Setup the dynamic elements [client side HTML] Next, you need to setup the dynamic DOM elements so that you can pick up the data values and checkbox state (when the user presses the "Done" button after editing)

// At the beginning of your oneditprepare() function...
const parentDiv =  $("#dialog-form"); // <<make sure this selects YOUR nodes DIV
var inputNo = 1;


// later on in your oneditprepare() function...
data.forEach((item) => {
    var inputID = "node-input-mynode-dynamic-" + inputNo; //generate dynamic ID
    var myNewRow = $('<div class="form-row" />');
    parentDiv.append(myNewRow); 
    var myNewLabel = $(`<label for="${inputID}"><i class="fa fa-globe"></i> ${item.name}</label>`);
    var myNewInput = $(`<input type="checkbox" class="mynode-dynamic-element" id="${inputID}" data-address="${item.address}" data-name="${item.name}" />`);
    myNewRow.append(myNewLabel);
    myNewRow.append(myNewInput);
    inputNo++; 
});

↑ NOTE how the input has data-address and data-name and a specific class? The data items will be read from the element inside oneditsave and the class name helps us read ONLY our dynamic elements. It must be unique/different to other classes in node-red.


  1. Store the values when user presses DONE button [client side HTML] Now you have DOM elements with appropriate values set, when the user presses "Done" button and oneditsave is called, itterate the items by using the class name you added to the dynamic elements, gather the values, build an array of objects, and lastly set node property you created in step1
    oneditsave: function () {
        var dynamicElements = $(".mynode-dynamic-element"); // use same class name as the dynamic DOM elements have
        var dynOpts = []; //a temp array
        dynamicElements.each( function(index,el) {
            var name = $(el).data("name"); //get value of data-name from the dynamic element
            var address = $(el).data("address"); //get value of data-address from the dynamic element
            var checked = $(el).is(":checked"); //get checked true/false from the dynamic element
            //make an object
            var opt = {
                name: name,
                address: address,
                checked: checked,
            }
            dynOpts.push(opt); //add object to array;
        });
        this.dynamicOptions = dynOpts; //update the node prop `dynamicOptions`
    }



Once you have done all the client side stuff, you should be able to access config.dynamicOptions in the constructor at server side JS...


On deploy, grab values entered at client side [server side JS]
Store the dynamicOptions passed in to the contructor somewhere you can get them later.

    function myNode(config) {
        RED.nodes.createNode(this, config);
        var node = this;
        node.dynamicOptions = config.dynamicOptions; //store config values in the node for later retreival


On msg input, set payload and send [server side JS]
when a msg arrives in the on("input" function, set payload and send the msg ...

        node.on("input", function (msg, send, done) {
            send = send || function() { node.send.apply(node,arguments) }
            done = done || function(err) {
                if(err){
                    node.error(err,msg);
                }
            };

            msg.payload = node.dynamicOptions; //set payload to your dynamicOptions
            send(msg); //send it