How to make an action happen (automatically) if a condition is met

I’m making a change to the interface and I’d like to make the sidebar open automatically if the storyriver is empty.
In fact I removed from $:/core/ui/TopBar/menu (which by default only contains the small button that changes the sidebar state by manipulating the contents of $:/state/sidebar) the $:/tags/TopBar/menu tag because I put an identical one not in the TopBar but in the EditToolbar and in the ViewToolbar.
I especially wanted to remove it from the TopBar because it interfered with other buttons if I was on mobile (usually overlapping the “close tiddler” button) Obviously, however, if no tiddler is open and the sidebar is hidden, without that button I would be stuck, so I would like the sidebar to open automatically.


I’ll stop digressing, and get to the point: I’m trying to make an action happen if a condition is met i.e. in this case to do this: <$action-setfield $tiddler="$:/state/sidebar" $field="text" $value="yes"/> if the StoryRiver is empty (I thought of checking this with this filter: [list<tv-story-list>count[]]compare:number:eq[0]])
But I don’t know how to combine the two.

<$action-setfield $tiddler="$:/state/sidebar" $field="text" $value="yes"/> Could be made into a macro, I did a bit of experimenting with various tools that I thought might help using that as a macro although I still can’t create that cause and effect relationship

Sorry for the brevity but I think it should at least give something:

You can’t, as far as I know, execute an action purely based on some state. Rather, understand that there is something that causes this state and use this for the trigger. In your case, the user closes the last tiddler.

1 Like

$action-* widgets can only be invoked in response to specific user interactions (e.g., a $button press, or an actions=... parameter on some other input control, or an $eventmanager widget). Thus, you can’t trigger an <$action-setfield> widget to modify the value of $:/state/sidebar merely in response to some condition being met.

However, there IS still a way to achieve your goal. Rather than changing the value stored in $:/state/sidebar, you can alter $:/core/ui/PageTemplate/sidebar – the TWCore shadow tiddler that contains the logic that determines when the sidebar content is to be displayed.

Replace the contents of $:/core/ui/PageTemplate/sidebar with the following:

\whitespace trim
\define config-title()
$:/config/SideBarSegments/Visibility/$(listItem)$
\end

\define showSidebar()
<$list filter="[all[shadows+tiddlers]tag[$:/tags/SideBarSegment]!has[draft.of]]" variable="listItem">
<$reveal type="nomatch" state=<<config-title>> text="hide"  tag="div">
<$transclude tiddler=<<listItem>> mode="block"/>
</$reveal>
</$list>
\end

<$scrollable fallthrough="no" class="tc-sidebar-scrollable">
<div class="tc-sidebar-header">
<$reveal state="$:/state/sidebar" type="match" text="yes" default="yes" retain="yes" animate="yes">
<<showSidebar>>
</$reveal>
<$list filter="[{$:/state/sidebar}!match[yes]then{$:/StoryList!!list}match[]]">
<<showSidebar>>
</$list>
</div>
</$scrollable>

Note:

  • Most of the above code is the same as the original TWCore shadow definition, except that I’ve refactored it to add a local macro named “showSidebar()”. This allows that part of the code to be invoked for two separate conditions.
  • The first condition is the “normal” case where $:/state/sidebar has a value of “yes”. This is the same handling as the original TWCore shadow code.
  • Then, immediately following that code is new code that invokes <<showSidebar>> when $:/state/sidebar is NOT “yes” AND the $:/StoryList!!list field is empty (your desired condition):
<$list filter="[{$:/state/sidebar}!match[yes]then{$:/StoryList!!list}match[]]">
<<showSidebar>>
</$list>

Let me know how it goes…

enjoy,
-e

4 Likes

I just want to add that @EricShulman’s approach is a smart one, but there may be other opportunities.

However, you can avoid the OT altogether by placing buttons in the $:/config/EmptyStoryMessage it would not be automatic but you can give the user choices like open sidebar, open default tiddlers and more.

  • In fact returning to the empty story could be the Wikis Home page.

With actions it is important to understand actions need triggers, typically it is a button but we have more triggers becoming available over time. This includes;

  • Any button - more on that below
  • Keyboard shortcuts
  • On drag and drop
  • Startup actions
  • Timer actions @EricShulman timer tools, Ooktech timer actions
  • Message catcher and event catcher widgets
    • in effect make use of other triggers including most click events such as on any link
  • In GitHub we have being discussing pre-save actions triggered by the save mechanism
  • inmysocks Trigger actions plugin and others (search for (tiddlywiki trigger actions)

Any button as a trigger
I have argued before now, that we have a lot of buttons already in use against which we can configure additional and conditional actions hence my proposal to make all buttons and common actions more hackable - see my POC/Demo site https://all-button-actions.tiddlyhost.com/

1 Like

Oh, thank you, that’s a good thing to know, next time I’ll know to create something like a button to do what I want. Would have been nice if it could have worked in that way (although I don’t know if it could have any implications)

Eric, I still have little understanding of how things work in general, but I have to say that your solution really looks to me as a real spark of genius.
It works perfectly. Thank you!

Interesting.
Food for thoughts here, I will definitely experiment, thanks

Experiment I did, and I have adopted your solution: it is really simple, and no need to overwrite anything. Thanks again @TW_Tones