Get msg to uibuilder

Hi there, I'm currently facing some new challenges. I'm using uibuilder on Node Red and I've successfully created an HTML page. However, I'm struggling to figure out how to get an external msg.payload to display on my HTML page. I also don't have much experience with HTML.

My goal is to get for 1: { ChargeNr: "", Legierung: "", Length = msg.payload.P1R1Length}, .
I get also the msg.payload.P1R1Length i proofed it so .

HTML`<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" href="../uibuilder/images/node-blue.ico">
    <title>Circle Grid</title>
    <meta name="description" content="Node-RED uibuilder - Circle Grid">
    <link rel="stylesheet" type="text/css" href="./index.css" media="all">
    <script defer src="../uibuilder/uibuilder.iife.min.js"></script>
    <style>
        /* Get circles visible */
        .circle {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-color: #ccc;
            display: inline-block;
            position: absolute;
            margin: -20px 0 0 -20px;
            cursor: pointer;
        }

        .circle.green {
            background-color: #0f0;
        }

        .circle:hover {
            background-color: #aaa;
        }

        /* vertical separator */
        .separator {
            width: 2px;
            height: 190%;
            background-color: #666;
            position: absolute;
            left: 0;
            top: 0;
        }

        h1.with-subtitle {
            text-align: center;
            margin-left: -50px;
        }

        /* Add styling for the circle numbers */
        .circle-number {
            font-size: 18px;
            font-weight: bold;
            color: #333;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        /* Add styling for the vertical numbering */
        .vertical-number {
            font-size: 18px;
            font-weight: bold;
            color: #333;
            position: absolute;
            left: 0;
            text-align: right;
        }
    </style>
</head>



<body class="uib">
    <h1 class="with-subtitle">Circle Grid - uibuilder Blank Template</h1>
    <div role="doc-subtitle">Using the IIFE library.</div>
    <div id="circle-grid" style="position: relative; width: 900px; height: 450px; margin: 0 auto;">

        <!-- Add vertical numbering -->
        <div style="position: absolute; left: -80px; bottom: 0; height: 100%; width: 30px;">
        </div>
    </div>
    <script>
        // Add vertical numbering
        for (let i = 15; i >= 1; i--) {
            const verticalNumber = document.createElement('div');
            verticalNumber.className = 'vertical-number';
            verticalNumber.style.bottom = `${(15 - i) * 59.5 - 400}px`;
            verticalNumber.style.left = `35px`; // adjust the left position
            verticalNumber.textContent = `${15 - i + 1}`;
            verticalNumber.style.color = '#333'; // corrected color
            document.querySelector('#circle-grid > div').appendChild(verticalNumber);
        }
        const R3P1Laenge = msg.payload.R3P1Laenge;
    </script>
    <script>
        // Generate the circle grid
        const circleGrid = document.getElementById('circle-grid');
        const circleData = {

            
            1: { ChargeNr: "", Legierung: "", Length: 0},
            2: { ChargeNr: "", Legierung: "", Length: 0 },
            3: { ChargeNr: "", Legierung: "", Length: 0 },
            4: { ChargeNr: "", Legierung: "", Length: 0 },
            5: { ChargeNr: "", Legierung: "", Length: 0 },
            6: { ChargeNr: "", Legierung: "", Length: 0 },
            7: { ChargeNr: "", Legierung: "", Length: 0 },
            8: { ChargeNr: "", Legierung: "", Length: 0 },
            9: { ChargeNr: "", Legierung: "", Length: 0 },
            10: { ChargeNr: "", Legierung: "", Length: 0 },
            11: { ChargeNr: "", Legierung: "", Length: 0 },
            12: { ChargeNr: "", Legierung: "", Length: 0 },
            13: { ChargeNr: "", Legierung: "", Length: 0 },
            14: { ChargeNr: "12", Legierung: "12", Length: 1 },
            15: { ChargeNr: "Char15", Legierung: "Leg15", Length: 500 },


            16: { ChargeNr: "", Legierung: "", Length: 0 },
            17: { ChargeNr: "", Legierung: "", Length: 0 },
            18: { ChargeNr: "", Legierung: "", Length: 0 },
            19: { ChargeNr: "", Legierung: "", Length: 0 },
            20: { ChargeNr: "", Legierung: "", Length: 0 },
            21: { ChargeNr: "", Legierung: "", Length: 0 },
            22: { ChargeNr: "", Legierung: "", Length: 0 },
            23: { ChargeNr: "", Legierung: "", Length: 0 },
            24: { ChargeNr: "", Legierung: "", Length: 0 },
            25: { ChargeNr: "", Legierung: "", Length: 0 },
            26: { ChargeNr: "", Legierung: "", Length: 0 },
            27: { ChargeNr: "", Legierung: "", Length: 0 },
            28: { ChargeNr: "", Legierung: "", Length: 0 },
            29: { ChargeNr: "", Legierung: "", Length: 0 },
            30: { ChargeNr: "", Legierung: "", Length: 0 },
            31: { ChargeNr: "N886", Legierung: "CuCOAL79", Length: 7050 },


            32: { ChargeNr: "", Legierung: "", Length: 0 },
            33: { ChargeNr: "", Legierung: "", Length: 0 },
            34: { ChargeNr: "", Legierung: "", Length: 0 },
            35: { ChargeNr: "", Legierung: "", Length: 0 },
            36: { ChargeNr: "", Legierung: "", Length: 0 },
            37: { ChargeNr: "", Legierung: "", Length: 0 },
            38: { ChargeNr: "", Legierung: "", Length: 0 },
            39: { ChargeNr: "", Legierung: "", Length: 0 },
            40: { ChargeNr: "", Legierung: "", Length: 0 },
            41: { ChargeNr: "", Legierung: "", Length: 0 },
            42: { ChargeNr: "", Legierung: "", Length: 0 },
            43: { ChargeNr: "", Legierung: "", Length: 0 },
            44: { ChargeNr: "", Legierung: "", Length: 0 },
            45: { ChargeNr: "", Legierung: "", Length: 0 },
            46: { ChargeNr: "", Legierung: "", Length: 0 },


            47: { ChargeNr: "", Legierung: "", Length: 0 },
            48: { ChargeNr: "", Legierung: "", Length: 0 },
            49: { ChargeNr: "", Legierung: "", Length: 0 },
            50: { ChargeNr: "", Legierung: "", Length: 0 },
            51: { ChargeNr: "", Legierung: "", Length: 0 },
            52: { ChargeNr: "", Legierung: "", Length: 0 },
            53: { ChargeNr: "", Legierung: "", Length: 0 },
            54: { ChargeNr: "", Legierung: "", Length: 0 },
            55: { ChargeNr: "", Legierung: "", Length: 0 },
            56: { ChargeNr: "", Legierung: "", Length: 0 },
            57: { ChargeNr: "", Legierung: "", Length: 0 },
            58: { ChargeNr: "", Legierung: "", Length: 0 },
            59: { ChargeNr: "", Legierung: "", Length: 0 },
            60: { ChargeNr: "", Legierung: "", Length: 0 },
            61: { ChargeNr: "", Legierung: "", Length: 0 },


            62: { ChargeNr: "", Legierung: "", Length: 0 },
            63: { ChargeNr: "", Legierung: "", Length: 0 },
            64: { ChargeNr: "", Legierung: "", Length: 0 },
            65: { ChargeNr: "", Legierung: "", Length: 0 },
            66: { ChargeNr: "", Legierung: "", Length: 0 },
            67: { ChargeNr: "", Legierung: "", Length: 0 },
            68: { ChargeNr: "", Legierung: "", Length: 0 },
            69: { ChargeNr: "", Legierung: "", Length: 0 },
            70: { ChargeNr: "", Legierung: "", Length: 0 },
            71: { ChargeNr: "", Legierung: "", Length: 0 },
            72: { ChargeNr: "", Legierung: "", Length: 0 },
            73: { ChargeNr: "", Legierung: "", Length: 0 },
            74: { ChargeNr: "", Legierung: "", Length: 0 },
            75: { ChargeNr: "", Legierung: "", Length: 0 },
            76: { ChargeNr: "", Legierung: "", Length: 0 },


            77: { ChargeNr: "", Legierung: "", Length: 0 },
            78: { ChargeNr: "", Legierung: "", Length: 0 },
            79: { ChargeNr: "", Legierung: "", Length: 0 },
            80: { ChargeNr: "", Legierung: "", Length: 0 },
            81: { ChargeNr: "", Legierung: "", Length: 0 },
            82: { ChargeNr: "", Legierung: "", Length: 0 },
            83: { ChargeNr: "", Legierung: "", Length: 0 },
            84: { ChargeNr: "", Legierung: "", Length: 0 },
            85: { ChargeNr: "", Legierung: "", Length: 0 },
            86: { ChargeNr: "", Legierung: "", Length: 0 },
            87: { ChargeNr: "", Legierung: "", Length: 0 },
            88: { ChargeNr: "", Legierung: "", Length: 0 },
            89: { ChargeNr: "", Legierung: "", Length: 0 },
            90: { ChargeNr: "", Legierung: "", Length: 0 },
            91: { ChargeNr: "", Legierung: "", Length: 0 },
            92: { ChargeNr: "", Legierung: "", Length: 0 },
            93: { ChargeNr: "", Legierung: "", Length: 0 },
            94: { ChargeNr: "", Legierung: "", Length: 0 },
            95: { ChargeNr: "", Legierung: "", Length: 0 },
            96: { ChargeNr: "", Legierung: "", Length: 0 },
            97: { ChargeNr: "", Legierung: "", Length: 0 },
            98: { ChargeNr: "", Legierung: "", Length: 0 },
            99: { ChargeNr: "", Legierung: "", Length: 0 },
            100: { ChargeNr: "", Legierung: "", Length: 0 },
            101: { ChargeNr: "", Legierung: "", Length: 0 },
            102: { ChargeNr: "", Legierung: "", Length: 0 },
            103: { ChargeNr: "", Legierung: "", Length: 0 },
            104: { ChargeNr: "", Legierung: "", Length: 0 },
            105: { ChargeNr: "", Legierung: "", Length: 0 },
            106: { ChargeNr: "", Legierung: "", Length: 0 },
            107: { ChargeNr: "", Legierung: "", Length: 0 },
            108: { ChargeNr: "", Legierung: "", Length: 0 },
            109: { ChargeNr: "", Legierung: "", Length: 0 },
            110: { ChargeNr: "", Legierung: "", Length: 0 },
            111: { ChargeNr: "", Legierung: "", Length: 0 },
            112: { ChargeNr: "", Legierung: "", Length: 0 },
            113: { ChargeNr: "", Legierung: "", Length: 0 },
            114: { ChargeNr: "", Legierung: "", Length: 0 },
            115: { ChargeNr: "", Legierung: "", Length: 0 },
            116: { ChargeNr: "", Legierung: "", Length: 0 },
            117: { ChargeNr: "", Legierung: "", Length: 0 },
            118: { ChargeNr: "", Legierung: "", Length: 0 },
            119: { ChargeNr: "", Legierung: "", Length: 0 },
            120: { ChargeNr: "", Legierung: "", Length: 0 },
            121: { ChargeNr: "", Legierung: "", Length: 0 },
            122: { ChargeNr: "", Legierung: "", Length: 0 },
            123: { ChargeNr: "", Legierung: "", Length: 0 },
            124: { ChargeNr: "", Legierung: "", Length: 0 },
            125: { ChargeNr: "", Legierung: "", Length: 0 },
            126: { ChargeNr: "", Legierung: "", Length: 0 },
            127: { ChargeNr: "", Legierung: "", Length: 0 },
            128: { ChargeNr: "", Legierung: "", Length: 0 },
            129: { ChargeNr: "", Legierung: "", Length: 0 },
            130: { ChargeNr: "", Legierung: "", Length: 0 },
            131: { ChargeNr: "", Legierung: "", Length: 0 },
            132: { ChargeNr: "", Legierung: "", Length: 0 },
            133: { ChargeNr: "", Legierung: "", Length: 0 },
            134: { ChargeNr: "", Legierung: "", Length: 0 },
            135: { ChargeNr: "", Legierung: "", Length: 0 },
            136: { ChargeNr: "", Legierung: "", Length: 0 },
            137: { ChargeNr: "", Legierung: "", Length: 0 },
            138: { ChargeNr: "", Legierung: "", Length: 0 },
            139: { ChargeNr: "", Legierung: "", Length: 0 },
            140: { ChargeNr: "", Legierung: "", Length: 0 },
            141: { ChargeNr: "", Legierung: "", Length: 0 },
            142: { ChargeNr: "", Legierung: "", Length: 0 },
            143: { ChargeNr: "", Legierung: "", Length: 0 },
            144: { ChargeNr: "", Legierung: "", Length: 0 },
            145: { ChargeNr: "", Legierung: "", Length: 0 },
            146: { ChargeNr: "", Legierung: "", Length: 0 },
            147: { ChargeNr: "", Legierung: "", Length: 0 },
            148: { ChargeNr: "", Legierung: "", Length: 0 },
            149: { ChargeNr: "", Legierung: "", Length: 0 },
            150: { ChargeNr: "", Legierung: "", Length: 0 },


            151: { ChargeNr: "", Legierung: "", Length: 0 },
            152: { ChargeNr: "", Legierung: "", Length: 0 },
            153: { ChargeNr: "", Legierung: "", Length: 0 },
            154: { ChargeNr: "", Legierung: "", Length: 0 },
            155: { ChargeNr: "", Legierung: "", Length: 0 },
            156: { ChargeNr: "", Legierung: "", Length: 0 },
            157: { ChargeNr: "", Legierung: "", Length: 0 },
            158: { ChargeNr: "", Legierung: "", Length: 0 },
            159: { ChargeNr: "", Legierung: "", Length: 0 },
            160: { ChargeNr: "", Legierung: "", Length: 0 },
            161: { ChargeNr: "", Legierung: "", Length: 0 },
            162: { ChargeNr: "", Legierung: "", Length: 0 },
            163: { ChargeNr: "", Legierung: "", Length: 0 },
            164: { ChargeNr: "", Legierung: "", Length: 0 },
            165: { ChargeNr: "", Legierung: "", Length: 0 },


            166: { ChargeNr: "", Legierung: "", Length: 0 },
            167: { ChargeNr: "", Legierung: "", Length: 0 },
            168: { ChargeNr: "", Legierung: "", Length: 0 },
            169: { ChargeNr: "", Legierung: "", Length: 0 },
            170: { ChargeNr: "", Legierung: "", Length: 0 },
            171: { ChargeNr: "", Legierung: "", Length: 0 },
            172: { ChargeNr: "", Legierung: "", Length: 0 },
            173: { ChargeNr: "N113", Legierung: "JKL96", Length: 235 },
            174: { ChargeNr: "", Legierung: "", Length: 0 },
            175: { ChargeNr: "", Legierung: "", Length: 0 },
            176: { ChargeNr: "", Legierung: "", Length: 0 },
            177: { ChargeNr: "", Legierung: "", Length: 0 },
            178: { ChargeNr: "", Legierung: "", Length: 0 },
            179: { ChargeNr: "", Legierung: "", Length: 0 },
            180: { ChargeNr: "", Legierung: "", Length: 0 }
            
            
            
            
            
        };

        for (let i = 0; i < 180; i++) {
            const circle = document.createElement('div');
            circle.className = 'circle';
            circle.style.left = `${(circleGrid.offsetWidth / 2) - 420 + (Math.floor(i / 15) * 60) - 20}px`;
            circle.style.top = `${(i % 15) * 60}px`;
            circle.setAttribute('id', `circle${i + 1}`);
            circle.setAttribute('name', `Circle ${i + 1}`);

            if (circleData[i + 1]) {
                const data = circleData[i + 1];
                circle.setAttribute('data-chargenr', data.ChargeNr);
                circle.setAttribute('data-legierung', data.Legierung);
                circle.setAttribute('data-length', data.Length);
                //  if (data.ChargeNr !== "" && data.Legierung !== "" && data.Length !== 0) {
                if (data.Length !== 0) {
                    circle.classList.add('green');
                }
            } else {
                circle.setAttribute('data-chargenr', '');
                circle.setAttribute('data-legierung', '');
                circle.setAttribute('data-length', '0');
            }

            // Add a click event to the circle
            circle.onclick = function() {
                alert(`ChargeNr.: ${this.getAttribute('data-chargenr')}\nLegierung: ${this.getAttribute('data-legierung')}\nLength: ${this.getAttribute('data-length')}`);
            };

            // Add a vertical separator for every 15th circle
            if (i % 15 === 0 && i !== 0) {
                const separator = document.createElement('div');
                separator.className = 'separator';
                separator.style.left = `${parseInt(circle.style.left) - 30}px`; // adjust the left position of the separator
                circleGrid.appendChild(separator);
            }

            // Add a number to the circle
            const circleNumber = document.createElement('div');
            circleNumber.className = 'circle-number';
            circleNumber.textContent = `${Math.floor(i / 15) + 1}`;
            circle.appendChild(circleNumber);

            circleGrid.appendChild(circle);
        }
    </script>
</body>

</html>`

Hi, just at work at the moment. Will look as soon as I can.

Lets start with some structural issues:

  • You've put some scripts into the body of the HTML but you are loading uibuilder via the default "defer" in the header. The scripts will run out of order and yours will not be able to find uibuilder. Move your code into index.js and add <script defer src="./index.js"></script> after the line that loads uibuilder. Generally, keep JS code out of your HTML file.
  • Similarly, keep Style info in index.css where it is easier to manage.

There are various ways. Given that you've already got plenty of JavaScript, the "traditional" way would be to include the following to listen for msgs and update. Make sure you do the above steps first though, or at least the JS part otherwise you cannot access the msg.

    uibuilder.onChange('msg', (msg) => {
        // NOTE: Assuming the msg looks like this:
        // { nr: 1, payload: { ChargeNr: "", Legierung: "", Length: 34} }
        console.log({msg})

        // break out the data
        const nr = msg.nr
        const chargeNr = msg.payload.ChargeNr
        const legierung = msg.payload.Legierung
        const length = msg.payload.Length

        // Update the JS data
        circleData[nr] = msg.payload

        // Update the UI
        const el = $(`#circle${nr}`) // get a ref to the correct circle
        if (el) {
            el.dataset.ChargeNr = msg.payload.ChargeNr
            el.dataset.Legierung = msg.payload.Legierung
            el.dataset.Length = msg.payload.Length
        }
    })

Adding that to your JS will create a listener for messages from Node-RED and process them as they arrive. I've assumed in the code that you are only sending that particular kind of update and that each msg is only for a single circle. You can see the message structure in the comment.

So injecting this:

Would update both the data and the UI.

Please note this is not fully tested so may still need tweaking.


There are other ways to do this - for example, you could do it all from Node-RED using a uib-update node - however that would only update the UI and not the data (actually, I'm not sure why you actutally want the data as well).

1 Like

First of all Thanks for you instruction and your Time,
i´ve seperate the HTML and JS - Code and also added the <script defer ... , the code i should additional add to the JS code marked as a failure.

By "marked as failure" I assume you are getting errors in your browser? As #TotallyInformation advised I would move the script out to index.js for easier reading. It looks like you're auto generating the divs for the circles? I would put a placeholder in the main body of your HTML to attach it to for example:

<body>
<div id="container"></div>
<script type="text/javascript" src="./index.js"></script>
</body>

Then in JS use it as an anchor

var circles = document.getElementById("container");

And append the children to it
Also remember to add the uibuilder.onChange function to the end of this JS as advised above