<style scoped> Appearing Not To Work In Template Node

I created a template node with a few classes, and then copied this node several times. I changed the class in one of the nodes and it affected ALL the nodes. I tried <style scoped> as per the vue documentation but this did not make any difference.

I would be grateful if someone would let me know what I have done wrong & how to fix the issue.

Can you post a simple flow to illustrate the problem?

A link to the Vue documentation might help too.

This flow just includes 2 of the template nodes I was talking about.

If you copy the <style> section from the Hourly chart over the <style> section of the Daily chart you will (hopefully) notice a radical change. (Also note that class="base-container" has been added to the first <div> in the Daily template)

If you have several of your own template nodes on a page checkout the class data in the browser console

[{"id":"9e7e786081315c45","type":"ui-template","z":"fe7296cf2a5f7fba","group":"2a9d414817265ee2","page":"","ui":"","name":"Hourly Development","order":1,"width":"2","height":"1","head":"","format":"<template>\n    <div>\n        <div class = \"chart-title\">{{chartTitle}}</div>        \n        <div class = \"chart-container\"><canvas ref=\"chart\" /></div>\n\n    </div>  \n\n</template>\n\n<script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n\n<script>\n    export default {\n        data() {\n            // define variables available component-wide\n            // (in <template> and component functions)\n            return {\n                isChartLoaded: false,\n\n                chartType: 'HBar',\n                isStacked: false,\n                \n                chartTitle: 'Hourly Energy Useage',\n\n                // Note that these are the reverse of a normal Bar chart\n                yAxisKey: 'period',                             // String value - label, 'y' is the default\n                xAxisKey: 'value',                              // Number value - data,  'x' is the default\n                seriesKey: '',                                  // '' is the default (none)\n\n                xAxisMin: 0,\n                xAxisMax: 0.5,\n\n                yAxisTitle: '',\n                xAxisTitle: '',\n\n                isLegendDisplay: false,\n                isAutoSkip: false,\n\n                dataSets: [],\n                \n            }\n        },\n\n        watch: {\n             msg: function () {\n\n                if ( Object.hasOwn(this.msg, 'ui_update') ) {\n                    \n                    this.chartTitle = this.msg.ui_update?.chartTitle ?? this.chartTitle\n                    \n                    this.yAxisKey = this.msg.ui_update?.yAxisKey ?? this.yAxisKey\n                    this.xAxisKey = this.msg.ui_update?.xAxisKey ?? this.xAxisKey\n\n                    this.yAxisMax = this.msg.ui_update?.yAxisMax ?? this.yAxisMax\n                    this.xAxisMax = this.msg.ui_update?.xAxisMax ?? this.xAxisMax\n\n                    this.yAxisKey = this.msg.ui_update?.yAxisKey ?? this.yAxisKey\n                    this.xAxisKey = this.msg.ui_update?.xAxisKey ?? this.xAxisKey\n\n                    this.yAxisTitle = this.msg.ui_update?.yAxisTitle ?? this.yAxisTitle\n                    this.xAxisTitle = this.msg.ui_update?.xAxisTitle ?? this.xAxisTitle\n\n                }              \n\n                if (this.isChartLoaded) {\n                    if (this.msg.payload !== undefined) this.onInput(this.msg)\n\n                }\n                \n            }\n        },\n    \n        computed: {\n             backgroundColours: function() {\n                let backgroundColour = [\n                                'rgba(255, 99, 132, 1.0)',\n                                'rgba(171, 199, 232, 1.0)',\n                                'rgba(255, 127, 14, 1.0)',\n                                'rgba(44, 160, 44, 1.0)',\n                                'rgba(152, 223, 158, 1.0)',\n                                'rgba(214, 39, 40, 1.0)',\n                                'rgba(255, 155, 150, 1.0)',\n                            ]\n\n                return backgroundColour\n    \n            },\n \n            borderColours: function() {\n                let borderColour = [\n                                'rgb(255, 99, 132)',\n                                'rgb(171, 199, 232)',\n                                'rgb(255, 127, 14)',\n                                'rgb(44, 160, 44)',\n                                'rgb(152, 223, 158)',\n                                'rgb(214, 39, 40)',\n                                'rgb(255, 155, 150)',\n\n                            ]\n\n                return borderColour\n    \n            },\n\n        },\n\n        methods: {\n            // Expose a method to our <template> and Vue Application\n            draw() {\n                const ctx = this.$refs.chart\n                \n                // Render the chart\n                const chart = new Chart(ctx, {\n                    type: 'bar',\n                    data: {\n                        labels: [],\n                        datasets: [{\n                            label: '',\n                            axis: 'y',\n                            data: [],\n                            backgroundColor: this.backgroundColours,\n\n                            borderColor: this.borderColors,\n\n                            borderWidth: 1,\n\n                        }]\n                    },\n\n                    options: {\n                        indexAxis: 'y',\n                        plugins: {\n                            legend: {\n                                display: this.isLegendDisplay,\n\n                            },\n    \n                        }, \n    \n                        elements: {\n                            bar: {\n                                borderWidth: 1,\n                            }\n                        },\n\n                        parsing: {\n                            xAxisKey: this.yAxisKey,\n                            yAxisKey: this.xAxisKey\n\n                        },\n\n                        maintainAspectRatio: false,             // Let the chart take the shape of the container\n                        animation: false,                       // Do not animate\n                        responsive: true,                       // - and please be responisve\n                        \n                        scales: {\n                            y: {\n                                title: {display: this.yAxisTitle ==='' ? false : true,\n                                        text: this.yAxisTitle,\n                                        align: 'center',\n                                       },\n\n                                ticks: {\n                                    autoSkip: this.isAutoSkip,  // Turn off automatic tick count calculations\n                                },\n                                stacked: this.isStacked,        // Is this a 'stacked' bar chart\n                            },\n\n                            x: {\n                                title: {display: this.xAxisTitle ==='' ? false : true,\n                                        text: this.xAxisTitle,\n                                        align: 'center',\n                                       },\n                                beginAtZero: true,\n                                min: this.xAxisMin,\n                                max: this.xAxisMax,\n                                stacked: this.isStacked,\n                            }\n                        }\n                    }\n                })\n\n                // make this available to all elements of the component\n                this.chart = chart\n            },\n\n            onInput(inputData) {\n                const chartData = inputData.payload\n                const chartTopic = (inputData?.topic) ?? ''\n                                        \n                if (Array.isArray(chartData)) {\n                    if (chartData.length === 0) {\n                        this.clearChart()\n\n                        return\n        \n                    } else {\n\n                        // Configure the dataSets property as the chart datasets and clear any data values\n                        this.dataSets = this.chart.data.datasets\n                        this.dataSets.forEach(element => element.data = [])\n\n                        // For each item in array add the data to proper dataset\n                        // Series key defaults to ''\n                        // the data has format [{seriesKey: <string>, xAxisKey: <string>, yAxisKey: <number>}, and many more of such ...]\n                        chartData.forEach(point => {\n                            let dataSetName = (this.seriesKey === 'topic') ? chartTopic : ''\n                            let x = ''\n                            let y = 0\n                            if (this.seriesKey === '' || this.seriesKey === 'topic') {\n                                ({ [this.xAxisKey]: x, [this.yAxisKey]: y } = point)\n\n                            } else {\n                                ({ [this.seriesKey]: dataSetName, [this.xAxisKey]: x, [this.yAxisKey]: y } = point)\n\n                            }\n\n                            // If an HBar chart the incoming x & y axis data is swapped on the chart\n                            if (this.chartType === 'HBar') {\n                                this.addDataPoint(dataSetName, {[this.xAxisKey]: y, [this.yAxisKey]: x})\n\n                            } else {\n                                this.addDataPoint(dataSetName, {[this.xAxisKey]: x, [this.yAxisKey]: y})\n\n                            }\n\n                        })\n\n                        this.updateChart()\n                      \n                    }\n                    \n                } else {\n                    this.send({error: `H Bar Chart requires an Array of Objects`})\n                }\n\n            },\n\n            addDataPoint(dataSetName, data) {\n                let dataSet = this.dataSets.find(chartSet => chartSet.label === dataSetName)\n                if (!dataSet) {\n                    dataSet = addDataset(dataSetName)\n    \n                    this.dataSets.push(dataSet)\n                }\n\n                dataSet.data.push(data)\n\n            },\n\n            updateChart() {\n                if (this.chart) {\n                    this.chart.data.datasets = this.dataSets\n\n                    this.chart.update()\n                }\n\n            },\n\n            clearChart() {\n                if (this.dataSets.length > 0) {\n                    this.dataSets.forEach(element => element.data = [])\n\n                    this.updateChart()\n\n                }\n\n            },\n\n            // Add a copy of the first dataset\n            addDataset(dataSetName) {\n                let dataSet = {...this.chart.data.datasets[0]}\n\n                dataSet.label = dataSetName\n\n                return dataSet\n    \n            },\n\n        },\n        \n        mounted() {\n            // Code here when the component is first loaded\n            let interval = setInterval(() => {\n                if (window.Chart) {\n                    // The chart.js is loaded, so we can now use it\n                    clearInterval(interval)\n                    \n                    this.draw()\n\n                    this.isChartLoaded = true\n                \n                }\n\n            }, 100)\n\n        },\n\n        unmounted() {\n            // Code here when the component is removed from the Dashboard\n            // i.e. when the user navigates away from the page\n        }\n        \n    }\n</script>\n\n<style scoped>\n    .chart-container {\n        height: 425px;\n        position: relative;\n        font-size: 1.4rem\n\n    }\n\n    .chart-title{\n        text-align:center;\n\n    }\n\n    .centre-text {\n        text-align: center;\n        font-size: 0.8rem; \n    }\n\n</style>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":1320,"y":1000,"wires":[[]],"info":".base-container{\r\n    width:100%;\r\n    height: 100%;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n\r\n}\r\n.chart-container{\r\n    position: relative;\r\n    margin: auto;\r\n    height: 100cqb;         /*use container query units to give full height of the container (100% of container height) */\r\n    width: 100cqi;          /*use container query units to give full width of the container (100% of container height)*/\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n}"},{"id":"84c4a8c53f4017b3","type":"ui-template","z":"fe7296cf2a5f7fba","group":"2a9d414817265ee2","page":"","ui":"","name":"Daily Development","order":2,"width":"2","height":"1","head":"","format":"<template>\n    <div  class=\"base-container\">\n        <div class = \"chart-title\">{{chartTitle}}</div>\n        <div class = \"chart-container\"><canvas ref=\"chart\"/></div>\n    </div>  \n\n</template>\n\n<script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n\n<script>\n    export default {\n        data() {\n            // define variables available component-wide\n            // (in <template> and component functions)\n            return {\n                isChartLoaded: false,\n\n                chartType: 'HBar',\n                isStacked: false,\n                \n                chartTitle: 'Daily Energy Useage',\n\n                // Note that these are the reverse of a normal Bar chart\n                yAxisKey: 'period',                             // String value - label, 'y' is the default\n                xAxisKey: 'value',                              // Number value - data,  'x' is the default\n                seriesKey: '',                                  // '' is the default (none)\n\n                xAxisMin: 0,\n                xAxisMax: 5.0,\n\n                yAxisTitle: '',\n                xAxisTitle: '',\n\n                isLegendDisplay: false,\n                isAutoSkip: false,\n\n                dataSets: [],\n                \n            }\n        },\n\n        watch: {\n             msg: function () {\n\n                if ( Object.hasOwn(this.msg, 'ui_update') ) {\n                    \n                    this.chartTitle = this.msg.ui_update?.chartTitle ?? this.chartTitle\n                    \n                    this.yAxisKey = this.msg.ui_update?.yAxisKey ?? this.yAxisKey\n                    this.xAxisKey = this.msg.ui_update?.xAxisKey ?? this.xAxisKey\n\n                    this.yAxisMax = this.msg.ui_update?.yAxisMax ?? this.yAxisMax\n                    this.xAxisMax = this.msg.ui_update?.xAxisMax ?? this.xAxisMax\n\n                    this.yAxisKey = this.msg.ui_update?.yAxisKey ?? this.yAxisKey\n                    this.xAxisKey = this.msg.ui_update?.xAxisKey ?? this.xAxisKey\n\n                    this.yAxisTitle = this.msg.ui_update?.yAxisTitle ?? this.yAxisTitle\n                    this.xAxisTitle = this.msg.ui_update?.xAxisTitle ?? this.xAxisTitle\n\n                }              \n\n                if (this.isChartLoaded) {\n                    if (this.msg.payload !== undefined) this.onInput(this.msg)\n\n                }\n                \n            }\n        },\n    \n        computed: {\n             backgroundColours: function() {\n                let backgroundColour = [\n                                'rgba(255, 99, 132, 1.0)',\n                                'rgba(171, 199, 232, 1.0)',\n                                'rgba(255, 127, 14, 1.0)',\n                                'rgba(44, 160, 44, 1.0)',\n                                'rgba(152, 223, 158, 1.0)',\n                                'rgba(214, 39, 40, 1.0)',\n                                'rgba(255, 155, 150, 1.0)',\n                            ]\n\n                return backgroundColour\n    \n            },\n \n            borderColours: function() {\n                let borderColour = [\n                                'rgb(255, 99, 132)',\n                                'rgb(171, 199, 232)',\n                                'rgb(255, 127, 14)',\n                                'rgb(44, 160, 44)',\n                                'rgb(152, 223, 158)',\n                                'rgb(214, 39, 40)',\n                                'rgb(255, 155, 150)',\n\n                            ]\n\n                return borderColour\n    \n            },\n\n        },\n\n        methods: {\n            // Expose a method to our <template> and Vue Application\n            draw() {\n                const ctx = this.$refs.chart\n                \n                // Render the chart\n                const chart = new Chart(ctx, {\n                    type: 'bar',\n                    data: {\n                        labels: [],\n                        datasets: [{\n                            label: '',\n                            axis: 'y',\n                            data: [],\n                            backgroundColor: this.backgroundColours,\n\n                            borderColor: this.borderColors,\n\n                            borderWidth: 1,\n\n                        }]\n                    },\n\n                    options: {\n                        indexAxis: 'y',\n                        plugins: {\n                            legend: {\n                                display: this.isLegendDisplay,\n\n                            },\n    \n                        }, \n    \n                        elements: {\n                            bar: {\n                                borderWidth: 1,\n                            }\n                        },\n\n                        parsing: {\n                            xAxisKey: this.yAxisKey,\n                            yAxisKey: this.xAxisKey\n\n                        },\n\n                        maintainAspectRatio: false,             // Let the chart take the shape of the container\n                        animation: false,                       // Do not animate\n                        responsive: true,                       // - and please be responisve\n                        \n                        scales: {\n                            y: {\n                                title: {display: this.yAxisTitle ==='' ? false : true,\n                                        text: this.yAxisTitle,\n                                        align: 'center',\n                                       },\n\n                                ticks: {\n                                    autoSkip: this.isAutoSkip,  // Turn off automatic tick count calculations\n                                },\n                                stacked: this.isStacked,        // Is this a 'stacked' bar chart\n                            },\n\n                            x: {\n                                title: {display: this.xAxisTitle ==='' ? false : true,\n                                        text: this.xAxisTitle,\n                                        align: 'center',\n                                       },\n                                beginAtZero: true,\n                                min: this.xAxisMin,\n                                max: this.xAxisMax,\n                                stacked: this.isStacked,\n                            }\n                        }\n                    }\n                })\n\n                // make this available to all elements of the component\n                this.chart = chart\n            },\n\n            onInput(inputData) {\n                const chartData = inputData.payload\n                const chartTopic = (inputData?.topic) ?? ''\n                                        \n                if (Array.isArray(chartData)) {\n                    if (chartData.length === 0) {\n                        this.clearChart()\n\n                        return\n        \n                    } else {\n\n                        // Configure the dataSets property as the chart datasets and clear any data values\n                        this.dataSets = this.chart.data.datasets\n                        this.dataSets.forEach(element => element.data = [])\n\n                        // For each item in array add the data to proper dataset\n                        // Series key defaults to ''\n                        // the data has format [{seriesKey: <string>, xAxisKey: <string>, yAxisKey: <number>}, and many more of such ...]\n                        chartData.forEach(point => {\n                            let dataSetName = (this.seriesKey === 'topic') ? chartTopic : ''\n                            let x = ''\n                            let y = 0\n                            if (this.seriesKey === '' || this.seriesKey === 'topic') {\n                                ({ [this.xAxisKey]: x, [this.yAxisKey]: y } = point)\n\n                            } else {\n                                ({ [this.seriesKey]: dataSetName, [this.xAxisKey]: x, [this.yAxisKey]: y } = point)\n\n                            }\n\n                            // If an HBar chart the incoming x & y axis data is swapped on the chart\n                            if (this.chartType === 'HBar') {\n                                this.addDataPoint(dataSetName, {[this.xAxisKey]: y, [this.yAxisKey]: x})\n\n                            } else {\n                                this.addDataPoint(dataSetName, {[this.xAxisKey]: x, [this.yAxisKey]: y})\n\n                            }\n\n                        })\n\n                        this.updateChart()\n                      \n                    }\n                    \n                } else {\n                    this.send({error: `H Bar Chart requires an Array of Objects`})\n                }\n\n            },\n\n            addDataPoint(dataSetName, data) {\n                let dataSet = this.dataSets.find(chartSet => chartSet.label === dataSetName)\n                if (!dataSet) {\n                    dataSet = addDataset(dataSetName)\n    \n                    this.dataSets.push(dataSet)\n                }\n\n                dataSet.data.push(data)\n\n            },\n\n            updateChart() {\n                if (this.chart) {\n                    this.chart.data.datasets = this.dataSets\n\n                    this.chart.update()\n                }\n\n            },\n\n            clearChart() {\n                if (this.dataSets.length > 0) {\n                    this.dataSets.forEach(element => element.data = [])\n\n                    this.updateChart()\n\n                }\n\n            },\n\n            // Add a copy of the first dataset\n            addDataset(dataSetName) {\n                let dataSet = {...this.chart.data.datasets[0]}\n\n                dataSet.label = dataSetName\n\n                return dataSet\n    \n            },\n\n        },\n        \n        mounted() {\n            // Code here when the component is first loaded\n            let interval = setInterval(() => {\n                if (window.Chart) {\n                    // The chart.js is loaded, so we can now use it\n                    clearInterval(interval)\n                    \n                    this.draw()\n\n                    this.isChartLoaded = true\n                \n                }\n\n            }, 100)\n\n        },\n\n        unmounted() {\n            // Code here when the component is removed from the Dashboard\n            // i.e. when the user navigates away from the page\n        }\n        \n    }\n</script>\n\n<style scoped>\n.base-container{\n    width:100%;\n    height:100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    /*container: chat / size;/*make this container available for container querys*/\n}\n.chart-container{\n    position: relative;\n    margin: auto;\n    height: 100cqb;/*use container query units to give full height of the container (100% of container height) */\n    width: 100cqi;/*use container query units to give full width of the container (100% of container height)*/\n    display: flex;\n    justify-content: center;\n    align-items: center;\n}\n\n</style>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":1310,"y":1060,"wires":[[]],"info":".base-container{\r\n    width:100%;\r\n    height: 100%;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n\r\n}\r\n.chart-container{\r\n    position: relative;\r\n    margin: auto;\r\n    height: 100cqb;         /*use container query units to give full height of the container (100% of container height) */\r\n    width: 100cqi;          /*use container query units to give full width of the container (100% of container height)*/\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n}"},{"id":"2a9d414817265ee2","type":"ui-group","name":"HBar Chart","page":"f14e4c53d983b36e","width":"4","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"f14e4c53d983b36e","type":"ui-page","name":"Scope Example","ui":"80f2e5f9dbf80780","path":"/page10","icon":"home","layout":"grid","theme":"a5bbf4397c8aa75a","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":1,"className":"","visible":true,"disabled":false},{"id":"80f2e5f9dbf80780","type":"ui-base","name":"Environment","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"showPageTitle":true,"navigationStyle":"default","titleBarStyle":"default"},{"id":"a5bbf4397c8aa75a","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094ce","bgPage":"#ffffff","groupBg":"#eeeeee","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"6px","groupBorderRadius":"5px","widgetGap":"12px","density":"default"}}]

This is the link I looked at but there are others Vue Scoped Styling

The problem can be circumvented by having different names for the classes, but that rather defeats the object pf the exercise

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