TiddlyWiki5/editions/tw5.com/tiddlers/widgets/ActionWidgets.tid

91 wiersze
4.1 KiB
Plaintext

created: 20141008134425548
modified: 20210630163127249
tags: Widgets
title: ActionWidgets
type: text/vnd.tiddlywiki
Action widgets are a special type of widget that have no visual appearance but perform an action when triggered (such as sending a message, navigating to a tiddler, or changing the value of a tiddler). Action widgets are used in association with other widgets that trigger those actions (for example, the ButtonWidget).
The following action widgets are provided:
<<list-links "[tag[ActionWidgets]]">>
There are two ways to use action widgets:
* Placing them within an action string attribute (typically called `actions`) on the triggering widget (this is the preferred way)
* Embedding the actions within the triggering widget (an older technique that is now deprecated)
!! Using action string attributes
The action widgets are passed as a string to the `actions` attribute of the triggering widget. Usually, it is more convenient to use a macro to assign the action widgets to a variable. For example, here is a button that triggers two actions of sending different messages:
```
\define my-actions()
<$action-sendmessage $message="tm-home"/>
<$action-sendmessage $message="tm-full-screen"/>
\end
<$button actions=<<my-actions>>>
Click me!
</$button>
```
!! Directly embedding action widgets
The action widgets need not be immediate children of their triggering widget, but they must be descendents of it. The actions are performed in sequence. Here is the above example rewritten to use embedding:
```
<$button>
<$action-sendmessage $message="tm-home"/>
<$action-sendmessage $message="tm-full-screen"/>
Click me!
</$button>
```
! Action Execution Modes
<<.from-version "5.2.0">> The default behaviour of action widgets has some peculiarities that often cause confusion. There is now an improved mode that simplifies how things work, but due to BackwardsCompatibility constraints, it must be explicitly engaged in order to take advantage of it.
The peculiarities relate to the way that the results of previous action widgets are available to subsequent action widgets. By default, action widgets are refreshed before each execution which ensure that they reflect the results of previous actions. However, ordinary widgets are not updated in the same way.
In the following contrived example, a button triggers a series of actions that should result in the string `foo` being assigned to the ''text'' field of the tiddler ActionTestTiddler. However, it fails to produce the expected result because the `<$set>` widget is not refreshed with the new value of ActionTestTiddler after the execution of the first `<$action-setfield>` widget.
<$macrocall $name='wikitext-example-without-html'
src='\define actions()
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value="FOO"/>
<$set name="newvalue" value={{{ [{ActionTestTiddler}lowercase[]] }}}>
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value=<<newvalue>>/>
</$set>
\end
Current value of ActionTestTiddler: {{ActionTestTiddler}}
<$button actions=<<actions>>>
Click me
</$button>'/>
The new behaviour avoids these problems by refreshing all widgets before execution, not just action widgets. It is engaged by running the actions in a scopr that includes the variable `tv-action-refresh-policy` set to the value `always`.
This can be done within an action string, or via a local variable declaration containing the widget triggering the action.
<<.warning "Do not attempt to set `tv-action-refresh-policy` globally; the core will only work correctly with the default setting">>
The example above works as expected with the addition of `tv-action-refresh-policy`:
<$macrocall $name='wikitext-example-without-html'
src='\define tv-action-refresh-policy() always
\define actions()
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value="FOO"/>
<$set name="newvalue" value={{{ [{ActionTestTiddler}lowercase[]] }}}>
<$action-setfield $tiddler="ActionTestTiddler" $field="text" $value=<<newvalue>>/>
</$set>
\end
Current value of ActionTestTiddler: {{ActionTestTiddler}}
<$button actions=<<actions>>>
Click me
</$button>'/>