# Ui\_template mvc and scope of context/flow/global stores

**URL:** <https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635>\
**Category:** Dashboard\
**Created:** [1 October 2020 16:16 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635 "2020-10-01T16:16:16Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [4 October 2020 22:06 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/21 "2020-10-04T22:06:59Z")

</div>

Sorry all I am struggling over basic stuff.

I have a checkbox based toggle button which toggles between the two states when clicked.

```auto
<md-button class="md-button remote-button3x bigger" 
    data-payload="1" 
    data-buttontype="checkbox"
    data-topic="10"
    >
    <label class="remote-button3x-switch">
        <input type="checkbox" id="10">
        <div class="remote-button3x-slider round">
            <span class="remote-button3x-on">O-N</span><span class="remote-button3x-off">O-F-F</span>
        </div>
    </label>       
</md-button>

```

I can addClass, toggleClass and removeClass using example code you provided.

How do I select and set the text content of the two classes "remote-button3x-on" and "remote-button3x-off" ?

w3s shows $("#test1").text("Hello world!"); which is not getting me anywhere.

I have added:

```auto
            case "setContent":
                $btn.text("Hello world!");
              // $btn.toggleClass(payload.value); //this calls the jquery function by name (specified in .command) on the $btn and passes in .value
                break;

```

but have no clue how to set content for class remote-button3x-on & remote-button3x-off.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 07:00 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/22 "2020-10-05T07:00:12Z")

</div>

hard to tell without seeing what kind of changes you have made in "script for all buttons with class remote-button" .  
As it states, functionality deals with elements which have defined class `remote-button`. You have created an element with class `remote-button3x`, so it will be ignored. Also you want to change content of nested element which again has different class.  
There is no magic.  
W3s shows correctly - ` $("#test1").text("Hello world!")` -\> select element with id test1 and set it's text Hello world!  
That is the basics.  
In your case it should be -\> select element with class remote-button3x-on and set it's text to Hello world!

Originally there was selector for class `.remote-button` and to find specific element, the data-topic must match with the msg.topic

```auto
var BUTTON_CLASS = ".remote-button";
...
var buttonSelector = BUTTON_CLASS + "[data-topic='" + msg.topic + "']"

```

So if your elements can not be selected, you'll need to adjust something. Even to make selector rules smarter or make your elements to follow the selector rules.

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 08:27 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/23 "2020-10-05T08:27:28Z")

</div>

Thanks. I had already altered your code to target BUTTON\_CLASS=.remote-button3x in place of .remote-button. Also all the places where you target buttontype=toggle I added equivalent code to target buttontype=checkbox and it is from here that I am stuck.

> [@hotNipi](#):
>
> ```auto
> var BUTTON_CLASS = ".remote-button";
> ...
> var buttonSelector = BUTTON_CLASS + "[data-topic='" + msg.topic + "']"
> 
> ```
> 
> So if your elements can not be selected, you'll need to adjust something. Even to make selector rules smarter or make your elements to follow the selector rules.

This is where I am now. I have tried lots of selector rules but cannot figure out how to change the content of these two spans ?

After that I need to figure out how to set the state. To isolate my attempts I have added:

```auto
            case "setContent":
                $btn.text("Hello world!");
              // $btn.toggleClass(payload.value); //this calls the jquery function by name (specified in .command) on the $btn and passes in .value
                break;

```

to processCommand().

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 08:39 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/24 "2020-10-05T08:39:53Z")

</div>

To identify what is the element you actually selected, do this. It logs out names classes for that element. If those are what you are looking for, you are good with selecting the element.

```auto
case "setContent":
console.log($btn.attr("class"));
break

```

And if that selected element is span, the `$btn.text("Hello world!");` should work fine.

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 08:52 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/25 "2020-10-05T08:52:47Z")

</div>

I get

md-button remote-button3x bigger md-button md-ink-ripple

not sure why md-button is in there twice ?

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 09:07 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/26 "2020-10-05T09:07:40Z")

</div>

> [@ozpos](#):
>
> md-button remote-button3x bigger md-button md-ink-ripple

So you have selected what is marked with red.  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/8/2828d3342873f37186b84412c270f0be7d67bae5.png)

But you want to select what is marked with yellow. So the rules must be somehow different.  
Again, the functionality is created for elements which are created in specific way. Your button is built differently. I can't still say what you need to change. Even how the button is built or the rules.

You can make the selector rule to be part of incoming payload.

```auto
var buttonSelector = BUTTON_CLASS + "[data-topic='" + msg.topic + "']"
        if(typeof msg.payload === "object" && msg.payload.selector){
            buttonSelector = msg.payload.selector 
        }

```

And send then the payload like this

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/e/fe363cba688d26c73ee78a6aff1ab0ea9365b2cf.png)  
`{"selector":".remote-button3x-on","command":"setContent","value":"HELLO"}`

Will it fit into your project logic, I can't really tell ..

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 10:24 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/27 "2020-10-05T10:24:01Z")

</div>

That looks like a wonderful idea thank you.

My project logic is to create a button with:

1. Type **toggle radio momentary**

2. Provide easy & efficient access to button **text class state**

3. Provide a level of user branding

4. Be persistent across browser refresh, node-red restarts/power failure.

Your initial example (of which I am truly grateful it has been incredibly illuminating) covered 1. completely ok,  
2. all except **text** (at the beginning I did not have a styled button that exposed the on/off text, I only had an icon example). I am in the process of trying to style a button with both.  
3. completely ok.  
4. todo.

Can I confirm that this is all I need ?

msg is `{"selector":".remote-button3x-on","command":"setContent","value":"HELLO"}`

```auto
var buttonSelector = BUTTON_CLASS + "[data-topic='" + msg.topic + "']"
        if(typeof msg.payload === "object" && msg.payload.selector){
            buttonSelector = msg.payload.selector 
            $(buttonSelector).text(msg.value);
        }

```

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 10:31 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/28 "2020-10-05T10:31:29Z")

</div>

> [@ozpos](#):
>
> ```auto
> if(typeof msg.payload === "object" && msg.payload.selector){
> buttonSelector = msg.payload.selector 
> $(buttonSelector).text(msg.value);
> }
> 
> ```

That gives you the option to target any element if you know the name of it's class or id.  
`"selector":".remote-button3x-on"` selects element with class `remote-button3x-on`  
`"selector":"#my-element"` selects element with id `my-element`

So basically you have freedom to select anything. What you will do with selected element, it's up to you. As far you are doing what is possible in terms of html, jquery, css ....

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 10:35 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/29 "2020-10-05T10:35:06Z")

</div>

would this select all buttons with class=.remote-button3x-on ?

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 10:35 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/30 "2020-10-05T10:35:27Z")

</div>

Of course. 🙂

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 10:47 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/31 "2020-10-05T10:47:48Z")

</div>

The button I need to select is defined in msg.topic. I cannot figure out the selector that does both.

A useful broadcast type use case however.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 10:58 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/32 "2020-10-05T10:58:37Z")

</div>

As the main selector rule looks button uniqueness from data-topic, I think it will be reasonable to use same logic..

```auto
var buttonSelector = BUTTON_CLASS + "[data-topic='" + msg.topic + "']"
if(typeof msg.payload === "object" && msg.payload.selector){
            buttonSelector = msg.payload.selector + "[data-topic='" + msg.topic + "']"
}

```

And in your buttons the elements you'll need to reach must also have data-topic defined.

```auto
...
<div class="remote-button3x-slider round">
     <span class="remote-button3x-on" data-topic="10">

```

there is more ways to do it of course but ...

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 11:11 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/33 "2020-10-05T11:11:54Z")

</div>

A nice place to explore selector tricks [http://www-db.deis.unibo.it/courses/TW/DOCS/w3schools/jquery/trysel.asp.html](http://www-db.deis.unibo.it/courses/TW/DOCS/w3schools/jquery/trysel.asp.html)

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 11:30 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/34 "2020-10-05T11:30:36Z")

</div>

> [@hotNipi](#):
>
> `msg.payload.selector + "[data-topic='" + msg.topic + "']"`

I see. It is no problem adding data-topic="10" to the span classes but... what ?

I suppose it is not so good if a user has to make many edits to "data-topic='x'" in order to make the instance unique.

Just a thing that is niggling me a bit. If I can select the button uniquely through

```auto
        var buttonSelector = BUTTON_CLASS + "[data-topic='" + msg.topic + "']" 
        var $btn = $(buttonSelector);//get the button

```

Why can I not select from within the context of $btn the '.remote-button-3x-on' class text ?

Also I thought I saw a w3s example of something where if one had

class='class1-subclass1' and class='class1-subclass2' ...

that there was a group selector syntax like |- (read or) so what is returned are all elements whose class name ends with '-subclassX' but within 'class1' scope ?

I really struggle with my description sorry.

Is something like this possible:  
If you can do this $(".remote-button3x-on", this) can I do something akin to  
$(".remote-button3x-on", $btnscope) ?

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 12:35 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/35 "2020-10-05T12:35:59Z")

</div>

Yes you can use the jquery find() to find elements inside the button  
`var someElement = $btn.find(msg.payload.selector)`

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 12:45 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/36 "2020-10-05T12:45:03Z")

</div>

At a cost I suppose. I am trying to avoid unnecessary uses of 'find' since I can predict the html structure so I tried to use something like $(_this_).children(".remote-button3x-on") where _this_ is the $btn selected with BUTTON\_CLASS + "[data-topic='" + msg.topic + "']"

But I get $(...).children is not a function in the console.  
**Edit:** Sorry found a typo. It actually returns undefined.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 12:53 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/37 "2020-10-05T12:53:46Z")

</div>

> [@hotNipi](#):
>
> $btn.find(msg.payload.selector)

works well. I cant see any cost issue here..??

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 13:03 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/38 "2020-10-05T13:03:01Z")

</div>

Is the find done within the context of the button ?

Unfortunately it returns undefined.

Any idea what; ARIA: Attribute " aria-label ", required for accessibility is doing in my console ?

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [5 October 2020 13:05 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/39 "2020-10-05T13:05:37Z")

</div>

do console.log(msg.payload.seletor) and see if it is correct thing to search in the button.

> **[ARIA2: Identifying a required field with the aria-required property |...](https://www.w3.org/TR/WCAG20-TECHS/ARIA2.html)**

---

<div class="post-metadata">

**Author:** ![ozpos](https://avatars.discourse-cdn.com/v4/letter/o/278dde/32.png) [@ozpos](https://discourse.nodered.org/u/ozpos)\
**Post date:** [5 October 2020 13:12 UTC](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635/40 "2020-10-05T13:12:37Z")

</div>

```auto
var spanSelectorOn = ".remote-button3x-on"; 
var $spanOn = $($btn).find(spanSelectorOn);//get the span
console.log("$spanOn=" + $spanOn.attr("text"));

returns undefined

console.log("$spanOn=" + $spanOn.text);

returns:-
$spanOn=function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)}

```

which is beyond me I am sorry to say.

[Previous page](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635.md?page=1)

[Next page](https://discourse.nodered.org/t/ui-template-mvc-and-scope-of-context-flow-global-stores/33635.md?page=3)
