Button that adds and removes a tag from a tiddler

Hi, I’m currently building a button that toggles the tag $:/tags/Stylesheet on a tiddler, to activate and deactivate a ui customization. For this button I took inspiration from the button that toggles the sidebar. The code i came up with is as follows:

<$list filter="[[Tiddler123]get[tags]] +[else[$:/tags/Stylesheet]match[$:/tags/Stylesheet]]" variable="ignore">
<$button> 
<$action-setfield $tiddler="Tiddler123" tags="$:/tags/Stylesheet"/>
Set tag button
</$button>
</$list>
<$list filter="[[Tiddler123]get[tags]is[missing]] +[then[$:/tags/Stylesheet]match[$:/tags/Stylesheet]]" variable="ignore">
<$button>
<$action-deletefield $tiddler="Tiddler123" tags="$:/tags/Stylesheet"/>
Delete tag button
</$button>
</$list>

And functionally it works as intended. But it doesn’t act like the button that toggles the sidebar i.e. it does not switch between the “Set tag button” and the “Delete tag button”, but instead it always displays the “Set tag button” even when I don’t want it dispayed.

Current behavior:

Where did I did it wrong?

1 Like
[[Tiddler123]get[tags]] +[else[$:/tags/Stylesheet]match[$:/tags/Stylesheet]]

Here your filter says : “Get the content of the field tags for the tiddler Tiddler123, if the output is empty instead use $:/tags/Stylesheet, then see if either match $:/tags/Stylesheet”

  • If there are no tags, the output is $:/tags/Stylesheet
  • If there is a tag $:/tags/Stylesheet, the output is $:/tags/Stylesheet
  • If there is any other tag, the output is empty

So the content of this list widget will only be hidden if the tiddler has tags that are not “$:/tags/Stylesheet”.

By the way, what you wrote is the same as writing :

[[Tiddler123]get[tags]else[$:/tags/Stylesheet]match[$:/tags/Stylesheet]]

Instead, you could check if the tiddler is tagged with “$:/tags/Stylesheet” :

[[Tiddler123]tag[$:/tags/Stylesheet]]

But a better way would be to not use a list widget at all and use a toggle filter operator to set the stylesheet tags, because your button as it is will override every tags of the tiddlers :

<$button actions="""<$action-listops $tiddler="Tiddler123" $tags="+[toggle[$:/tags/Stylesheet]]"/>""">
Toggle stylesheet
</$button>

Then you can use a list widget if you want to change the text of the button to reflect the current state of the tiddler :

<$tiddler tiddler="Tiddler123">
<$button actions="""<$action-listops $tags="+[toggle[$:/tags/Stylesheet]]"/>""">
Turn the stylesheet 
<$list filter="[{!!title}tag[$:/tags/Stylesheet]]" emptyMessage="""on""">off</$list>
</$button>
</$tiddler>

You could also use a checkbox widget, that way you dont need to use an action widget + you get an additional visual feedback for the state of the tiddler :

<$checkbox tag="$:/tags/Stylesheet" tiddler="Tiddler123">
Enable the stylesheet
</$checkbox>
6 Likes

Thank you telumire!
Wonderfully explained, and your solution works perfectly.

1 Like

Yea, as noted, you can use a checkbox to do exactly this. Note that you can style a checkbox to look like a button, if you prefer that. (Do some googling and you’ll find loads of examples).