I can't recover the info in the js file

#1

Hi, I'm deploying a node with and array like a default property but when I try to deploy the node I can't access to the info in the js file (I have a empty array there).

This is the definition:

defaults:{
            name: {value:""},
            ...
            fiware_attrs_array: {value:[  ]},
        },

Oneditprepare and oneditsave:

oneditprepare: function(){

            var node = this;
            $("#node-input-fiware_attrs_array").editableList({
                addItem: function(container, i, attr){
                    if (node.fiware_attrs_array.length > 0){
                        for(var x=0; x < this.fiware_attrs_array.length; x++){
                            var item = this.item[x];
                            console.log(item);
                        }
                    }else if (node.fiware_attrs_array.length == 0){
                        var newItem = $('<li>', {for:"node-input-attr"+i}).appendTo(container);
                        var name = $('<input/>', {id:"node-input-attr-name"+i, type: "text"}).appendTo(newItem);
                        var type = $('<input/>', {id:"node-input-attr-type"+i, type: "text"}).appendTo(newItem);
                        var value = $('<input/>', {id:"node-input-attr-value"+i, type: "text"}).appendTo(newItem);
                    }
                },
                removeItem: function(container){

                },
                sortable: true,
                removable: true
            });
        },
        oneditsave: function(){
            var attrs = $("#node-input-fiware_attrs_array").editableList('items');
            var node = this;
            var array = [];
            attrs.each(function(i){
                var attr = $(this);
                var attrName = attr.find('#node-input-attr-name'+i).val();
                var attrType = attr.find('#node-input-attr-type'+i).val();
                var attrValue = attr.find('#node-input-attr-value'+i).val();
                var newAttr = {};
                newAttr['name'] = attrName;
                newAttr['type'] = attrType;
                newAttr['value'] = attrValue;
                array.push(newAttr);
            });
            node.fiware_attrs_array = array;
            console.log("Attributes: " + JSON.stringify(node.fiware_attrs_array));
        }

And the html element:

<div class="form-row node-input-fiware_attrs_array_row">
        <ol id="node-input-fiware_attrs_array">
    </div>
0 Likes

#2

Hi Jose (@trujillo),

First of all I think you have rewrite your oneditprepare, because otherwise I couldn't display any loaded values:

        oneditprepare: function(){
            var node = this;
            
            // Specify an editableList, add all its available functions (addItem, ...)
            $("#node-input-fiware_attrs_array").editableList({
                addItem: function(container, i, attr){
                    // Create a new row
                    var newItem = $('<li>', {for:"node-input-attr"+i}).appendTo(container);
                    
                    // Show 3 input fields in the new row
                    var nameInput = $('<input/>', {id:"node-input-attr-name"+i, type: "text"}).appendTo(newItem);
                    var typeInput = $('<input/>', {id:"node-input-attr-type"+i, type: "text"}).appendTo(newItem);
                    var valueInput = $('<input/>', {id:"node-input-attr-value"+i, type: "text"}).appendTo(newItem);
                    
                    // Show the specified values in those 3 input fields
                    nameInput.val(attr.name);
                    typeInput.val(attr.type);
                    valueInput.val(attr.value);
                },
                removeItem: function(container){

                },
                sortable: true,
                removable: true
            });
            
            // Fill the editableList with all data from the fiware_attrs_array available in this node
            for(var i = 0; i < this.fiware_attrs_array.length; i++) {
                var attr = this.fiware_attrs_array[i];
                $("#node-input-fiware_attrs_array").editableList('addItem',{name:attr.name, type:attr.type, value:attr.value});
            }
        },

However then there is still your original question, why the array isn't being passed to the server. Very weird. I have used something similar already a couple of times, but here it indeed doesn't work.

And it is even not functioning in the client itself:

  1. I change the values on the config screen:

    image

  2. When I press the 'Done' button, the array seems to be correctly stored inside the node (in oneditsave):

    image

  3. But when I open the config screen again, the array entry is messed up (in oneditprepare):

    image

I assume it must be something very stupid, but I cannot see at the moment what is wrong :woozy_face:
Bart

0 Likes

#3

Don't use node-input-fiware_attrs_array as the id of the editableList.

The editor will be looking for an input with that id to get the updated value from.... which it cannot do as it's a editableList.

As you are doing all the work to populate and save the list in your onedit* functions, you can give the <ol> element any id you want... Just not the one you are using.

0 Likes

#4

Thanks @knolleary,
Had been looking at Jose's code over-and-over again, but hadn't noticed that the editableList element had the same id as the array in the node. Damn ...

@trujillo,
When I change the editableList id to e.g. "node-input-editablelist", then the array indeed survives reopening the config screen. And it also arrives at the server side when deploying:

Here is my test code (with {name:'a', type:'b', value:'c'} as default test value):

<script type="text/javascript">
    RED.nodes.registerType('test-array',{
        category: 'performance',
        color: '#E9967A',
        defaults: {
            name: {value:""},
            fiware_attrs_array: {value:[ {name:'a', type:'b', value:'c'} ]}              
        },        
        inputs:1,
        outputs:1,
        icon: "fluid.png",
        label: function() {
            return this.name||"Array";
        },
        oneditprepare: function(){
            var node = this;
            
            // Specify an editableList, add all its available functions (addItem, ...)
            $("#node-input-editablelist").editableList({
                addItem: function(container, i, attr){
                    // Create a new row
                    var newItem = $('<li>', {for:"node-input-attr"+i}).appendTo(container);
                    
                    // Show 3 input fields in the new row
                    var nameInput = $('<input/>', {id:"node-input-attr-name"+i, type: "text"}).appendTo(newItem);
                    var typeInput = $('<input/>', {id:"node-input-attr-type"+i, type: "text"}).appendTo(newItem);
                    var valueInput = $('<input/>', {id:"node-input-attr-value"+i, type: "text"}).appendTo(newItem);
                    
                    // Show the specified values in those 3 input fields
                    nameInput.val(attr.name);
                    typeInput.val(attr.type);
                    valueInput.val(attr.value);
                },
                removeItem: function(container){

                },
                sortable: true,
                removable: true
            });
            
            // Fill the editableList with all data from the fiware_attrs_array available in this node
            for(var i = 0; i < this.fiware_attrs_array.length; i++) {
                var attr = this.fiware_attrs_array[i];
                $("#node-input-editablelist").editableList('addItem',{name:attr.name, type:attr.type, value:attr.value});
            }
        },
        oneditsave: function(){
            var attrs = $("#node-input-editablelist").editableList('items');
            var node = this;
            var array = [];
            attrs.each(function(i){
                var attr = $(this);
                var attrName = attr.find('#node-input-attr-name'+i).val();
                var attrType = attr.find('#node-input-attr-type'+i).val();
                var attrValue = attr.find('#node-input-attr-value'+i).val();
                var newAttr = {};
                newAttr['name'] = attrName;
                newAttr['type'] = attrType;
                newAttr['value'] = attrValue;
                array.push(newAttr);
            });
            node.fiware_attrs_array = array;
        }
    });
</script>

<script type="text/x-red" data-template-name="test-array">
    <div class="form-row node-input-editablelist-row">
        <ol id="node-input-editablelist">
    </div>
    </br>
    <div class="form-row">
        <label for="node-input-name"><i class="icon-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
</script>
0 Likes