UIBUILDER - text boxes

What would be the best approach to create text boxes similar to Dashboard 2's text boxes?

textboxes

I've looked at using the 'Text Box' template in the uib-element node but it creates it within it's own card, and appears better suited to adding paragraphs of text instead of small amounts of data.

I can't see what options are available within the uib-tag node, I see that it has a button, but is there a list somewhere of what other tags exist?


Otherwise, I'm slowly learning... :laughing:

The tag node literally creates an HTML tag - ANY tag. :slight_smile:

What you are seeing in D2 is actually some monstrous HTML:

<div data-v-c88f8420="" id="nrdb-ui-group-be18b9332e179722" class="nrdb-ui-group">
    <div data-v-c88f8420=""
        class="v-card v-theme--nrdb v-card--density-default v-card--variant-outlined bg-group-background"
        style="min-height: 48px;"><!---->
        <div class="v-card__loader">
            <div class="v-progress-linear v-theme--nrdb v-locale--is-ltr" role="progressbar" aria-hidden="true"
                aria-valuemin="0" aria-valuemax="100" style="top: 0px; height: 0px; --v-progress-linear-height: 2px;">
                <!---->
                <div class="v-progress-linear__background"></div>
                <div class="v-progress-linear__buffer" style="width: 0%;"></div>
                <div class="v-progress-linear__indeterminate">
                    <div class="v-progress-linear__indeterminate long"></div>
                    <div class="v-progress-linear__indeterminate short"></div>
                </div><!---->
            </div>
        </div><!---->
        <div class="v-card-text">
            <div data-v-c9902742="" data-v-c88f8420="" class="nrdb-layout-group--grid"
                style="grid-template-columns: repeat(min(6, var(--layout-columns)), 1fr); grid-template-rows: repeat(1, minmax(var(--widget-row-height), auto));">
                <!---->
                <div data-v-c9902742="" id="nrdb-ui-widget-9d3f7a404f41e792" draggable="false"
                    class="nrdb-ui-widget nrdb-ui-text"
                    style="display: grid; grid-template-columns: minmax(0px, 1fr); grid-template-rows: repeat(0, minmax(var(--widget-row-height), auto)); grid-column-end: span min(6, var(--layout-columns));">
                    <div data-v-0db0e89c="" data-v-c9902742="" class="nrdb-ui-text nrdb-ui-text--col-center"><label
                            data-v-0db0e89c="" class="nrdb-ui-text-label">Today</label><span data-v-0db0e89c=""
                            class="nrdb-ui-text-value">3.96kW</span></div><!---->
                </div><img data-v-c9902742=""
                    src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt=""
                    style="position: absolute;">
            </div>
        </div><!----><!----><!----><span class="v-card__underlay"></span>
    </div>
</div>

Nearly all of which isn't needed just to display a text box! (yes, that is purely a single text box in a group). And now you can start to see why D2 can be slow on mobile or limited devices like Pi's.

The text box uib-element output is the simplest to use if you are going to use the no-code options. Just note that you can send HMTL as the text, not just plain text. So to get the vertical layout, you could send Solar<br>103W for example.

On the other hand, if you are prepared to get your hands "dirty" with some HTML, you will find that most of the HTML on your pages is actually static, doesn't need to be dynamic. Then all you need is something like this in the body of your HMTL:

<main>
  <section>
    <article id="solarinfo">
      Solar: <br> <span id="solarpwr"></span>
    </article>
  </section>
</main>

Using main applies a sensible width and structure (from uibuilder's default CSS). section isn't really needed but can be helpful to group things together. <article> is semantic HTML for a box if information. It is formatted that way by uibuilder's default CSS but of course, you can style it anyway you like.

With that, you can now simply use the uib-update node targeted at #solarpwr (which is the CSS selector), and you just update that specific element on the page.

This is FAR from the only way to approach this! There are even easier ways if you are happy to use HTML. For example, in the html above, simply replace the span with:

<span uib-topic="solarpwr"></span>W

And now you can simply send a msg to the uibuilder node:

{
  "topic": "solarpwr",
  "payload": 103
}

And you have a web page that is updated with simple messages.

Add in a uib-cache node before the uibuilder node, by default, it manages cache entries by msg.topic so everything "just works"™ :wink:

For the uib-tag node? There are quite a few - this may help. :smiling_face_with_sunglasses:

Yup, you can use it to dynamically add any HTML element you like.

Let me know which approach you want to take - no-code from Node-RED or starting to use HTML front-end code. So I don't keep steering you off in a different direction!

PS: Also don't forget that you can start with no-code but later capture the generated HTML and turn it into more static front-end code for maximum efficiency and maximum control - should you want to. :smiley:

PPS: The latest documentation has guides on building a more complete, rich page with HTML. Scratch that! I've just realised that I forgot to actually add the content to the 2 documentation pages! Urgh! :rofl: Well, you will find the examples here in the forum anyway, check in the uibuilder tag, I shared a grid and a dashboard (flex) layout some while back.

3 Likes

This post is inspiring me to take another look at the uibuilder, which I had put on back burner while I am slowly transitioning from DB1 to DB2, as the basic DB2 dashboard is up and ready.

3 Likes

I'm getting somewhere using uib-element nodes, and modifying them with css from chained uid-update nodes, like this;

[{"id":"ada7df8996acdd89","type":"uib-element","z":"1326aadbacf36704","g":"db18aa2d5896df30","name":"","topic":"","elementtype":"article","parent":"#more","parentSource":"","parentSourceType":"str","elementid":"tb1","elementId":"","elementIdSourceType":"str","heading":"","headingSourceType":"str","headingLevel":"h2","data":"payload","dataSourceType":"msg","position":"1","positionSourceType":"str","passthrough":false,"confData":{},"x":930,"y":1420,"wires":[["dcbe3da3fe079096"]]},{"id":"8648b7f99b0fe6cc","type":"link out","z":"1326aadbacf36704","g":"db18aa2d5896df30","name":"link out 3","mode":"link","links":["869f73c536d38982"],"x":1335,"y":1420,"wires":[]},{"id":"94b51a071dd14fa1","type":"uib-element","z":"1326aadbacf36704","g":"db18aa2d5896df30","name":"","topic":"","elementtype":"article","parent":"#more","parentSource":"","parentSourceType":"str","elementid":"tb2","elementId":"","elementIdSourceType":"str","heading":"","headingSourceType":"str","headingLevel":"h2","data":"payload","dataSourceType":"msg","position":"2","positionSourceType":"str","passthrough":false,"confData":{},"x":930,"y":1460,"wires":[["dcbe3da3fe079096"]]},{"id":"26eba994a103bc64","type":"uib-element","z":"1326aadbacf36704","g":"db18aa2d5896df30","name":"","topic":"","elementtype":"article","parent":"#more","parentSource":"","parentSourceType":"str","elementid":"tb3","elementId":"","elementIdSourceType":"str","heading":"","headingSourceType":"str","headingLevel":"h2","data":"payload","dataSourceType":"msg","position":"3","positionSourceType":"str","passthrough":false,"confData":{},"x":930,"y":1500,"wires":[["dcbe3da3fe079096"]]},{"id":"49b1423c424047a4","type":"uib-element","z":"1326aadbacf36704","g":"db18aa2d5896df30","name":"","topic":"","elementtype":"article","parent":"#more","parentSource":"","parentSourceType":"str","elementid":"tb4","elementId":"","elementIdSourceType":"str","heading":"","headingSourceType":"str","headingLevel":"h2","data":"payload","dataSourceType":"msg","position":"4","positionSourceType":"str","passthrough":false,"confData":{},"x":930,"y":1540,"wires":[["dcbe3da3fe079096"]]},{"id":"dcbe3da3fe079096","type":"uib-update","z":"1326aadbacf36704","g":"db18aa2d5896df30","name":"css","topic":"","mode":"update","modeSourceType":"update","cssSelector":"div[id^=\"tb\"].box","cssSelectorType":"str","slotSourceProp":"payload","slotSourcePropType":"msg","attribsSource":"{\"style\":\"border: 0px; padding: 1px; width: 120px;\"}","attribsSourceType":"json","slotPropMarkdown":false,"x":1130,"y":1420,"wires":[["f16fe283525b04ae"]]},{"id":"f16fe283525b04ae","type":"uib-update","z":"1326aadbacf36704","g":"db18aa2d5896df30","name":"css","topic":"","mode":"update","modeSourceType":"update","cssSelector":"article","cssSelectorType":"str","slotSourceProp":"","slotSourcePropType":"str","attribsSource":"{\"style\":\"margin: 0.1rem;\"}","attribsSourceType":"json","slotPropMarkdown":false,"x":1250,"y":1420,"wires":[["8648b7f99b0fe6cc"]]}]

...and so far I get;

Any suggestions to centre the text or improve it? See following post!

Also.. in each uib-element node I've numbered their position with numbers 1 to 4 (tb1 = 1, tb2 = 2, tb3 = 3, etc), but it doesn't seem to make any difference, and they appear in the wrong order. Fixed in following post

1 Like

Tried Julian's suggestion instead - adding this to the body;

<main>
  <section>
    <article id="solarinfo">
      Solar: <br> <span id="solarpwr"></span>
    </article>
  </section>
</main>

...and works much better, giving me many more opportunities to tweak the css.

responsive

It's now responsive, but I need to spend a bit more time closing the gap between the 'wrapped' rows. - (EDIT - Now sorted)

2 Likes

Hi Paul, sorry, I was in London with work last night so not online.

Now you've started to use HTML directly, I think you will be pleased at how quickly things will go. Same with css of course.

At the end of your GIF, you caught a CSS display thanks to the dev tools and this should start to help you with layouts.

When using flex layouts, you may want to use a layout generator such as https://loading.io/flexbox/

For a quick and dirty test, I added an id of s1 to the section tag and then used this simple CSS added to index.css for the layout - it uses nested CSS so only works on newer browsers.

#s1 {
    display:flex;
    flex-wrap: wrap;

    article {
        min-width: 5em;
        max-width: 5em;
        /* separate the articles be 1rem horizontally and vertically */
        margin: 1em;
        text-align: center;
    }
}

margin can be separated into 4 elements to control top, right, bottom, left in case you need different separation horizontally and vertically.

Note that I ALWAYS use relative lengths such as em, rem or % for everything, avoid fixed px like the plague. :slight_smile:

1 Like