Ui-page dynamic class

You can give a widget a custom class "foo":


And in dev tools you can see
image

Inject ui_update = {"class": "bar"}, then you see
image

And with a ui-page, you can set a custom class "foo"


and the dev tools shows it
image

I cannot find a way via the ui control node to dynamically append a class and get .nrdb-ui-page.foo.bar

Is it me, by design or by oversight?

The class attribute on a page is simply static. a means of dynamic control was never implemented.

Please feel free to raise a feature request issue as it is a worthy feature.

In the mean time, to get past this limitation, you could add a ui-template and do this is using client-side script.

As a temporary workaround, wouldn't it be possible to set a class to the page programmatically in a template node?

Can you give an example @omrid, msg.payload -> page class? TY.

In a template node belonging to this page, get the page's DOM element and add/remove/toggle the class:

msg.type = "setClass";
msg.payload = "dark-mode";
//-------------------------

// upon receiving the msg in the template node
if (msg.type === 'setClass') // identifies the msg 
{
   // find the DOM element of the page
   const element = document.querySelector("body");

   // Manipulate the page class
   element.classList.add(msg.payload); // or classList.remove() or classList.toggle()
}

I haven't tested this yet. Let me know if it works.

i would use topic for action (add, remove, toggle) as they match up with the dom function
And use payload for the class that you want to apply/remove

also, set something msg.selector = '.page1' // target page class or page id or something

const op = msg.topic // the operation to perform e.g. add, remove, toggle
if (['add', 'remove', 'toggle'].includes(op)) {
   const element = document.querySelector(msg.selector || 'body')
   element.classList[op](msg.payload)
}

untested

Important:

Dont forget to set the ui-template class to d-none (ref) so it is not shown in your dashboard.

Also important

This code :index_pointing_up: would be typically in a watch handler watching the msg object so that when you send a msg to the ui-template, it operates

I put @omrid's code in a template <script> section and sent a message with type="setClass" and payload = "darkmode" but I don't see <body class="darkmode">

Sorry @Steve-Mcl, that all goes way over my head!

[{"id":"13c18235c926694c","type":"ui-template","z":"d1c96cf8529a5579","group":"","page":"","ui":"83289142e2632cc2","name":"class-setter","order":0,"width":0,"height":0,"head":"","format":"<template>\n    <div>\n    </div>\n</template>\n\n<script>\n    export default {\n        watch: {\n            // watch for any changes of \"count\"\n            msg: function () {\n                const m = this.msg || {}\n                const {selector, topic, payload} = m // extract interesting bits\n                console.log('got a msg with topic, payload, selector:', topic, payload, selector)\n                // if payload is something and topic is one of add, remove or toggle, its good!\n                if (payload && ['add', 'remove', 'toggle'].includes(topic)) {\n                    const element = document.querySelector(selector || 'body')\n                    element.classList[topic](payload)\n                }\n            }\n        }\n    }\n</script>\n","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"widget:ui","className":"d-none","x":910,"y":120,"wires":[[]]},{"id":"6b317a885c9e49ee","type":"inject","z":"d1c96cf8529a5579","name":"add class test to .page1","props":[{"p":"topic","vt":"str"},{"p":"payload"},{"p":"selector","v":".page1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"add","payload":"test","payloadType":"str","x":600,"y":160,"wires":[["13c18235c926694c"]]},{"id":"36b14836d14f0ae6","type":"inject","z":"d1c96cf8529a5579","name":"remove class test from .page1","props":[{"p":"topic","vt":"str"},{"p":"payload"},{"p":"selector","v":".page1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"remove","payload":"test","payloadType":"str","x":620,"y":200,"wires":[["13c18235c926694c"]]},{"id":"161cd2f7fac6b53b","type":"inject","z":"d1c96cf8529a5579","name":"toggle class test on .page1","props":[{"p":"topic","vt":"str"},{"p":"payload"},{"p":"selector","v":".page1","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"toggle","payload":"test","payloadType":"str","x":610,"y":120,"wires":[["13c18235c926694c"]]},{"id":"907bb2f87c6d201d","type":"ui-template","z":"d1c96cf8529a5579","group":"","page":"","ui":"83289142e2632cc2","name":"styles","order":0,"width":0,"height":0,"head":"","format":".test {\n    display: inline-block; \n    font-size: 30px;\n    -webkit-transform: matrix(-1, 0, 0, 1, 0, 0);\n    -moz-transform: matrix(-1, 0, 0, 1, 0, 0);\n    -o-transform: matrix(-1, 0, 0, 1, 0, 0);\n    transform: matrix(-1, 0, 0, 1, 0, 0);\n}\n","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"site:style","className":"","x":890,"y":80,"wires":[[]]},{"id":"83289142e2632cc2","type":"ui-base","name":"My Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"headerContent":"page","navigationStyle":"default","titleBarStyle":"default","notificationDisplayTime":5}]

chrome_RyfQHDWmJE

1 Like

Ahah! I had to work out to set a custom class of page1 for my page.

Thanks!