[TW5] Writing to Two Separate Fields with Checkbox Input

308 views
Skip to first unread message

Secret-HQ

unread,
Jan 4, 2016, 12:09:24 PM1/4/16
to tiddl...@googlegroups.com
I know I can use the <$checkbox> macro to write a value to a field — but can I use it to write multiple values to multiple fields (of the same tiddler)?

For example, can I check a checkbox and have it set (say) completed = <<now>> AND completedon = the date of <<now>>?

Maybe by defining macros:

\define setFieldsDone()
<$action-setfield completed=<<now "YYYY-0MM-0DD hh:mm:ss">> />
<$action-setfield completedon=<<now "YYYY-0MM-0DD">> /
>
\end


\define setFieldsUndone()
<$action-setfield completed="" />
<$action-setfield completedon="" />
\end

... and then calling them with something like:

<$checkbox checked=<<setFieldsDone>> unchecked=<<setFieldsUndone>>>click me to mark this task done</$checkbox>

That code won't work, of course — but am I barking up the right tree?

Matabele

unread,
Jan 4, 2016, 1:44:43 PM1/4/16
to TiddlyWiki
Hi

Currently, action widgets can not be triggered with a checkbox widget (although some efforts have been made in this direction.)

You may, however, use a button widget. If you wish to have visual feedback of the state -- use two button widgets within two reveal widgets which toggle one another off/on.

<$reveal type="match" state="!!temp" text="set">
<$button set="!!temp" setTo="reset">
<$action-setfield ..../>
<$action-setfield ..../>
Set</$button></$reveal>

<$reveal type="match" state="!!temp" text="reset">
<$button set="!!temp" setTo="set">
<$action-setfield ..../>
<$action-setfield ..../>
Reset</$button></$reveal>

regards

Jed Carty

unread,
Jan 4, 2016, 2:23:10 PM1/4/16
to TiddlyWiki
Just as a quick addition to what Matabele said, you can also make the button look like a checkbox like this:

<$reveal type="match" state="!!temp" text="set">
<$button set="!!temp" setTo="reset" class='tc-btn-invisible'>
<$action-setfield ..../>
<$action-setfield ..../>
<input type=checkbox/></$button></$reveal>


<$reveal type="match" state="!!temp" text="reset">
<$button set="!!temp" setTo="set" class='tc-btn-invisible'>
<$action-setfield ..../>
<$action-setfield ..../>
<input type=checkbox checked/></$button></$reveal>

I think I first saw that as a suggestion from Eric. Because of how updates work, modifying a checkbox widget to trigger action widgets doesn't always act the way you expect it to. I made a bunch of prototypes for other widgets triggering action widgets (you can see them here), the keyboard widget is the only one that has made it into the core due to the unexpected update behavior in the others. Even if that is fixed, having a checkbox widget that invokes action widgets would need something like what Matabele showed in order to have different actions for checking and unchecking.

Because of all that I think that the best idea is to fake a checkbox widget using buttons if you need more complex behavior.

Eric Shulman

unread,
Jan 4, 2016, 2:37:05 PM1/4/16
to TiddlyWiki
On Monday, January 4, 2016 at 10:44:43 AM UTC-8, Matabele wrote:
Currently, action widgets can not be triggered with a checkbox widget (although some efforts have been made in this direction.)

You may, however, use a button widget. If you wish to have visual feedback of the state -- use two button widgets within two reveal widgets which toggle one another off/on.

 
If you want the $button widgets to *look* like checkboxes:

* use <$button class="tc-btn-invisible" ...> to hide the button border/background
* use <input type="checkbox"> to render a (non-functional) checkbox as the button content.

Like this:
<$reveal type="match" state="!!temp" text="set">
   <$button class="tc-btn-invisible" set="!!temp" setTo="reset">
      <$action-setfield ..../>
      <$action-setfield ..../>
     
<input type="checkbox">Set

   </$button>
</$reveal>
<$reveal type="match" state="!!temp" text="reset">
   <$button class="tc-btn-invisible" set="!!temp" setTo="set">
      <$action-setfield ..../>
      <$action-setfield ..../>
     
<input type="checkbox" checked="true">Reset
   </$button>
</$reveal>


The checkboxes are just some static HTML, without handlers attached to them, so clicking the checkbox doesn't actually do anything... directly.  Instead, the click is actually processed by the containing <$button> widget's handler, which triggers the <$action> widgets.  One of these actions should be to toggle the value used to control the state of the <$reveal> widgets that enclose the <$button> widgets, resulting in the alternative <$button> being displayed after the value is changed. Since each button contains a static checkbox -- one checked, the other unchecked -- the effect is that clicking the button *appears* to toggle the checkbox.

enjoy,
-e

Tobias Beer

unread,
Jan 4, 2016, 2:41:01 PM1/4/16
to TiddlyWiki
Hi Eric,
 
If you want the $button widgets to *look* like checkboxes:

Thanks a lot for this example for having custom events attached to what appears to be a checkbox.

Best wishes,

Tobias. 

Scott Simmons (Secret-HQ)

unread,
Jan 10, 2016, 1:09:46 PM1/10/16
to tiddl...@googlegroups.com
>sniff<  I love you guys!

Life got in the way this week, and I didn't get a chance to read and try this until last night — but it's a clever, elegant solution.

As it turns out, you can even use a proper <$checkbox/> macro in conjunction with it to toggle tags:

<$reveal type="match" state="!!fakeCheckboxChecked" text="nope">
<$button set="!!fakeCheckboxChecked" setTo="yep" class="tc-btn-invisible">
<$action-setfield checkedtime=<
<now "YYYY-0MM-0DD hh:mm:ss">> />
<$checkbox tag="tag me tagged">Check me!</$checkbox>
</$button>
</$reveal>

Matabele

unread,
Jan 10, 2016, 9:36:53 PM1/10/16
to TiddlyWiki
Hi

Using this code:

<$reveal type="match" state="!!fake" text="nope">
<$button set="!!fake" setTo="yep" class="tc-btn-invisible">
<$action-setfield checkedtime=<
<now "YYYY-0MM-0DD hh:mm:ss">> />

<$checkbox tag="tag me tagged">Check me!</$checkbox>
</$button>
</$reveal>
<$reveal type="match" state="!!fake" text="yep">
<$button set="!!fake" setTo="nope" class="tc-btn-invisible">
<$action-setfield checkedtime="" />

<$checkbox tag="tag me tagged">Check me!</$checkbox>
</$button>
</$reveal>

{{!!checkedtime}}

The value in 'checkedtime' toggles as expected, however the checkbox's have no effect?

regards

Scott Simmons (Secret-HQ)

unread,
Jan 11, 2016, 12:36:55 AM1/11/16
to tiddl...@googlegroups.com

On Sunday, January 10, 2016 at 9:36:53 PM UTC-5, Matabele wrote:
 
The value in 'checkedtime' toggles as expected, however the checkbox's have no effect?

Hmmmm.  I could've sworn I had that working last night.  (And, like a bonehead, I've already cleared my backups and can't find the one where I thought it worked.)

Maybe I had the <$button> macro as a child of <$checkbox> rather than the other way around?  That toggles the tag on and off:

<$reveal type="match" state="!!fakeCheckboxChecked" text="nope">
<$checkbox tag="tag me tagged">
<$button set="!!fakeCheckboxChecked" setTo="yep" class="tc-btn-invisible">
<$action-setfield checkedtime=<<now "YYYY-0MM-0DD 0hh:0mm:0ss">> />
Check me!
</$button>

</$checkbox>
</$reveal>

... but it doesn't set the checkedtime field (or toggle fakeCheckboxChecked).

I could've sworn it worked last night, but now it looks like a matter of either/or.  I'll bang my head against it some more tomorrow, but smart money says I was just confused.  :(

Matabele

unread,
Jan 11, 2016, 2:02:30 AM1/11/16
to TiddlyWiki
Hi

I think something like this will do the trick:

<$reveal type="match" state="!!fake" text="nope">
<$button set="!!fake" setTo="yep" class="tc-btn-invisible">
<$action-setfield checkedtime=<
<now "YYYY-0MM-0DD hh:mm:ss">> />
<$action-listops $tags="[[tag me tagged]]"/>
<input type="checkbox">Check me!

</$button>
</$reveal>
<$reveal type="match" state="!!fake" text="yep">
<$button set="!!fake" setTo="nope" class="tc-btn-invisible">
<$action-setfield checkedtime=""/>
<$action-listops $tags="-[[tag me tagged]]"/>
<input type="checkbox" checked="true">UnCheck me!
</$button>
</$reveal>

{{!!checkedtime}}

A bit long winded -- but can't see any shortcuts.

regards

Scott Simmons (Secret-HQ)

unread,
Jan 11, 2016, 1:51:21 PM1/11/16
to tiddl...@googlegroups.com
On Monday, January 11, 2016 at 2:02:30 AM UTC-5, Matabele wrote:

I think something like this will do the trick:

Thanks, Matabele!  That does the trick in TiddlyWiki 5.1.10, all right!

In 5.1.9 (where I'd been playing around with this), it looks like the <$action-listops> macro isn't part of the core.

Just FYI, I tried using <$action-sendmessage> with tm-add-tag and tm-remove-tag, to no avail.  Clearly I'm misunderstanding/misusing that widget ... .

<$reveal type="match" state="!!fakecheckboxchecked" text="nope">
<$button set="!!fakecheckboxchecked" setTo="yep" class="tc-btn-invisible">
<$action-setfield checkedtime=<
<now "YYYY-0MM-0DD 0hh:0mm:0ss">> />
<$action-sendmessage $message="tm-add-tag" param="tag me tagged" />
<input type="checkbox" />Check me!
</$button>
</$reveal>

<$reveal type="match" state="!!fakecheckboxchecked" text="yep">
<$button set="!!fakecheckboxchecked" setTo="nope" class="tc-btn-invisible">
<$action-setfield checkedtime="" />
<$action-sendmessage $message="tm-remove-tag" param="tag me tagged" />
<input type="checkbox" checked />Uncheck me!
</$button>
</$reveal>

Thanks again for taking time to educate me on <$action-listops>!

Eric Shulman

unread,
Jan 11, 2016, 1:57:49 PM1/11/16
to TiddlyWiki
On Monday, January 11, 2016 at 10:51:21 AM UTC-8, Scott Simmons (Secret-HQ) wrote:
Thanks, Matabele!  That does the trick in TiddlyWiki 5.1.10, all right!
In 5.1.9 (where I'd been playing around with this), it looks like the <$action-listops> macro isn't part of the core.

Yup.  listops was added in 5.1.10
 

Just FYI, I tried using <$action-sendmessage> with tm-add-tag and tm-remove-tag, to no avail.  Clearly I'm misunderstanding/misusing that widget ...

Wrap your button inside a <$fieldmangler>...</$fieldmangler>.  This will catch the tm-add-tag and tm-remove-tag messages and update the tags field accordingly (adding/removing the tag from the existing tag list value).

-e

Scott Simmons (Secret-HQ)

unread,
Jan 11, 2016, 11:19:01 PM1/11/16
to TiddlyWiki
On Monday, January 11, 2016 at 1:57:49 PM UTC-5, Eric Shulman wrote:
 
Just FYI, I tried using <$action-sendmessage> with tm-add-tag and tm-remove-tag, to no avail.  Clearly I'm misunderstanding/misusing that widget ...

Wrap your button inside a <$fieldmangler>...</$fieldmangler>.  This will catch the tm-add-tag and tm-remove-tag messages and update the tags field accordingly (adding/removing the tag from the existing tag list value).

A-ha!

Knowing that is SO much more satisfying than "man, I'm doing SOMETHING wrong up in here."   :D

Thanks!

Scott Simmons (Secret-HQ)

unread,
Jan 11, 2016, 11:42:44 PM1/11/16
to TiddlyWiki
Hmmmm.

Any thoughts on the various advantages/disadvantages of using <$action-listops> vs. <$fieldmangler> and <$action-sendmessage>?

Matabele

unread,
Jan 12, 2016, 12:51:21 AM1/12/16
to tiddl...@googlegroups.com
Hi Scott

Before the introduction of the ActionListops widget in v5.1.10 -- the only option to add or remove a tag using a button were the 'tm-add-tag' and 'tm-remove-tag' messages in conjunction with an enclosing FieldMangler widget (unless it were permissible to overwrite the 'tags' field with an ActionSetfield widget.)

The ActionListops widget is not only simpler to use in simple cases (action widgets are generally more straightforward to use than widgets based on widget messaging) -- but also allow many versatile options for manipulating the 'tags' or any other list in any field or index. 

For the simple usage case of adding and removing a tag (mimicking the MangleTags functionality):

<$button>
<$action-listops tiddler="Target Tiddler" $tags="[[Tag to Add]] -[[Tag to Remove]]"/>
Tag</$button>

If the tags don't contain spaces, then the double brackets are unnecessary:

<$button>
<$action-listops $tiddler="Target Tiddler" $tags="AddTag AndAnother -RemoveTag -RemoveAnotherTag"/>
Tag</$button>

Compare with:

<$fieldmangler tiddler="Target Tiddler">
<$button>
<$action-sendmessage $message="tm-add-tag" $param="AddTag"/>
<$action-sendmessage $message="tm-add-tag" $param="AndAnother"/>
<$action-sendmessage $message="tm-remove-tag" $param="RemoveTag"/>
<$action-sendmessage $message="tm-remove-tag" $param="RemoveAnotherTag"/>
Tag</$button>
</$fieldmangler>

In some cases, a simple filter expression can allow greater brevity e.g. to clear all non-system tags (keep system tags) -- and add new tags:

<$button>
<$action-listops $tiddler="Target Tiddler" $tags="+[prefix[$:/]] MyNew Tags"/>
Tag</$button>

Therefore, an apparent advantage to learning the workings of the ActionListops widget. The downside -- new to the core; may have bugs in edge cases.

regards

Scott Simmons (Secret-HQ)

unread,
Jan 14, 2016, 1:12:52 AM1/14/16
to TiddlyWiki
VERY cool.  I had no idea you could pass filter expressions (like [prefix[$:/]]) in there!

(I'm assuming that's a typo in your previous example and should be -prefix[$:/] rather than +.)

Thanks for the explanation  As with most things Tiddly, it's opened the door to a bunch of new potential solutions to workflow issues.  ;)

Matabele

unread,
Jan 14, 2016, 1:34:37 AM1/14/16
to TiddlyWiki
Hi Scott

If you examine the logic:
-- '+[prefix[$:/]]' keeps items prefixed with '$:/" (and discards all other items)
-- and '+[!prefix[$:/]]' keeps items not prefixed with '$:/" (and discards the system tags)

regards

On Thursday, 14 January 2016 08:12:52 UTC+2, Scott Simmons (Secret-HQ) wrote

Scott Simmons (Secret-HQ)

unread,
Jan 14, 2016, 1:48:18 AM1/14/16
to TiddlyWiki
Ohhhhhh!

I was unaware of the special meaning + has in <$action-listops>.

Even cooler!  :D

Matabele

unread,
Jan 14, 2016, 2:27:31 AM1/14/16
to TiddlyWiki
Hi Scott

This isn't a special meaning -- only that the $tags= and $subfilter= attributes of the widget are set up to operate on the existing content of the target field (as additional filter runs.)

So:
<$action-listops $field="my-field" $subfilter="+[additional[filter run]]"/>

Is equivalent to:
<$action-listops $field="my-field" $filter="[list[!!my-field]] +[additional[filter run]]"/>

regards

Scott Simmons (Secret-HQ)

unread,
Jan 14, 2016, 12:35:55 PM1/14/16
to TiddlyWiki
Ah, I see now.  (I think.)

I wasn't recognizing the value of $tags as a filter expression.  Viewed in that light, the + makes a little more sense.

Though it does prep my brain to expect that any string passed in there without the + would overwrite the existing tags entirely.  I.e., if $tags="+[prefix[$:/]] MyNew Tags" works like $field="tags" filter="[list[!!tags]] +[prefix[$:/]] MyNew Tags", then why doesn't MyNew (without a +) clear the field and reset its value to MyNew only (with Tags following up and doing the same, leaving Tags the sole tag on the tiddler)?  I know it doesn't work this way, but I'd expect all the individual tag values (if they're subfilters) to require the +.

I probably just need to sit and contemplate your examples a while until it sinks in.  Thanks again for breaking <$action-listops> down for me and being so patient as I try to charge through it like a bull in a china shop.

William Jackson

unread,
Jan 14, 2016, 1:11:20 PM1/14/16
to tiddl...@googlegroups.com
Hi Scott

No problem. The filter syntax is all standard — nothing unusual for the ActionListops widget. There’s documentation on filter expressions and filter runs on tw5.com — takes a little getting used to though. I investigate filter expressions in the filter tab of advanced search — helps to see what’s going on.

regards,

William Jackson

On 14 January 2016 at 7:36:06 PM, Scott Simmons (Secret-HQ) (goo...@secret-hq.com) wrote

Reply all
Reply to author
Forward
0 new messages