Multiple checkboxes in a tiddler that retain state

I want to create multiple checkboxes in a tiddler.

With a simple:

<$checkbox></$checkbox>

I can have multiple checkboxes in a tiddler but it does not retain the state on reload.

Something like:

<$checkbox tiddler="ExampleData" index=<<currentTiddler>> checked="selected" unchecked="" default=""> Selected?</$checkbox>

retains the state on reload. But that means I can have only one checkbox in a tiddler.

How can I append <<now YYYY0MM0DD0hh0mm0ssXXX>> to <<currentTiddler>> (something like <<currentTiddler>><<now YYYY0MM0DD0hh0mm0ssXXX>>) so the index becomes unique.

That will mean that the state will be retained and I can have multiple checkboxes in a tiddler.

1 Like

Hi deshmukh! Could you tell us what you’ll use the checkboxes for?

Are you trying to make multiple checkboxes with a ListWidget? Or are you writing the multiple checkboxes manually?

Tiddlywiki 5.2.0 (prerelease) adds a new counter variable for the ListWidget. Go to https://tiddlywiki.com/prerelease/, make a new tiddler with this text:

\define id() $(currentTiddler)$-$(cnt)$

<$list filter="box1 task2 aNewBox" counter="cnt" variable="item">

<$checkbox tiddler="ExampleData" index=<<id>> checked="selected" unchecked="" default=""> <<item>></$checkbox>

</$list>

ExampleData JSON tiddler will look like this:

{
    "MyTiddler-1": "selected",
    "MyTiddler-2": "selected",
    "MyTiddler-3": "selected"
}

You can also change the ExampleData tiddler type to application/x-tiddler-dictionary before you check any boxes, so that it uses DictionaryTiddler format instead.

Macros, like the now macro, are text substitutions that can take parameters. So the timestamp will be substituted before the widget is parsed and rendered, not at the time you click the checkbox.

1 Like

@sull-vitsy Thanks. I am still using 5.1.23. So, these features are not available to me. And no, I am not using any list widget. I am adding items manually. I use the Stamp feature on the editor toolbar when I need checkboxes.

try making a global macro (a tiddler tagged with $:/tags/macro) with this:

\define id(num) $(currentTiddler)$-$num$

and then in your tiddler:

<$checkbox tiddler="ExampleData" 
index=<<id "1">> checked="selected" unchecked="" 
default=""> Selected?</$checkbox>

It’s basically the same thing, except we manually feed the number to the id macro.

Have a great day!

Also depending on the use case you can set the checkbox state to be stored in a field on the current or any tiddler, just choose a different fieldname for each. The selection then stays with the tiddler.

Q1=yes
Q2=no
Q3=yes

First, the checkbox state reflects some value stored somewhere. In you example, you’re setting a (data tiddler) index named as the current tiddler. If you set some other index in that same tiddler, then that should also work and be reflected in any checkbox that looks at that other index.

Thus when you say “But that means I can have only one checkbox in a tiddler.” it seems you refer to currentTiddler as the same tiddler each time. Instead, you can choose some other index. You can, for example, manually specify different indexes or you can include that whole checkbox construct in a listwidget so that currentTiddler is different for each loop.

BTW, I don’t think indexes in datatiddlers accept e.g capital letters. Not sure. For sure it will not accept any arbitrary characters (e.g :). You might consider having the checkbox set fields instead of indices.

Is there a way by which instead of passing an argument every time, some random string is used instead? It would be great if that random string is the current time in YYYY0MM0DD0hh0mm0ssxxx format. Then, we can have:

<$checkbox tiddler="ExampleData" 
index=<<theuniqueid>> checked="selected" 
unchecked="" default=""> Selected?</$checkbox>

And ExampleData tiddler would carry something like:

{
    "tidA20211005143612345": "",
    "tidA20211005143612346": "",
}

I tried

\define theuniqueid $(currentTiddler)(now "YYYY0MM0DD0hh0mm0ssxxx")$

But that did not work.

Oh man, this has me stumped :smile:. I have some ideas, but I need to get on my computer first.

To clarify: do you require the exact time when the checkbox was ticked?

@sull-vitsy Thanks. And I am really sorry if my questions are too naive.

I do not need the ‘exact’ time. I was using exact time to concatenate the tiddler name to avoid any chance of having the same index — I am unlikely to be able to add text or click that fast :slight_smile:

Plus, merely looking at the index, one can figure out from where and when it has come. So, for readability, it would be better to use “YYYY-0MM-0DD 0hh:0mm:0ss xxx” format for the now widget.

On a related note, will the index value change when I uncheck the box?

What actually are you trying to achieve in the end? It seems that the checkbox values you want to set are only to be used to reflect the state of the checkbox and that this checkbox is only to be seen in one place (because the only thing to identify the checkbox with would be via the random value you attempt to create), is that right?

Anyway, this:

…doesn’t work because it breaks several syntax rules. I’m not sure the following will work but it is at least a bit of an improvement:

\define theuniqueid() $(currentTiddler)$<<now "YYYY0MM0DD0hh0mm0ssxxx">>

Absolutely. That is what I want to achieve. I will take a minute of yours to tell you how I am planning to use it.

I have a tiddler called QuickTasks. I use it to capture several tasks that will take hardly any time to complete. But I do not want to do them now. These are transient in nature. But may crop up again after a few days. A good example is ‘Replace batteries’.

My workflow is:

QuickTasks contain:

\define theuniqueid() $(currentTiddler)$<<now "YYYY0MM0DD0hh0mm0ssxxx">>

<$checkbox tiddler="ExampleData" index=<<theuniqueid>> checked="done" unchecked="" default="">Replace Batteries</$checkbox><br>

I will just copy paste the checkbox line and edit the ‘Replace Batteries’ part. When I complete a task, I do not need to edit the tiddler. I just check that box and be done. Later on, when I have time, I will delete the lines I do not need from QuickTasks tiddler.

I know, as a workflow, it is clumsy. But this seems to work right now for me.

Hope I am clear. Please ask if something is unclear.

1 Like

And this did not produce the index we want. <<now “YYYY0MM0DD0hh0mm0ssxxx”>> appeared verbatim in the index value.

I know this isn’t related to your question, but there are some cool plugins for task management and quick tasks. See Todolist which is a simple todolist maker. You call a macro, you add tasks, you tick off checkboxes.

Projectify leans more towards project management, but it has a quick-add todo function. You just press alt+c from anywhere in your wiki and it’ll open an inbox tiddler where you can add tasks quickly.

I know, as a workflow, it is clumsy. But this seems to work right now for me.

I will have to agree with you :wink: …but maybe it is a good start until you want to improve upon it.

This should solve the evaluation problem:

\define theuniqueid() $(currentTiddler)$<<uid>>

<$vars uid=<<now "YYYY0MM0DD0hh0mm0ssXXX">> >
<$checkbox tiddler="ExampleData" index=<<theuniqueid>> checked="done" unchecked="" default="">Replace Batteries</$checkbox>
</$vars>
<br>

You can test if the following even works, i.e no separate macro:

<$checkbox tiddler="ExampleData" index=<<now "<<currentTiddler>>YYYY0MM0DD0hh0mm0ssXXX">> checked="done" unchecked="" default="">Replace Batteries</$checkbox>
<br>

@sull-vitsy It is very much related. For my use case, these plugins provide an out-of-box solutions. So, thanks for suggesting.

@twMat Thanks.

I, too, hope it will improve. In fact, solutions suggested by @sull-vitsy are way more elegant.

This does not work it creates an index value of QuickTasks<<uid>>.

<$checkbox tiddler="ExampleData" index=<<now "<<currentTiddler>>YYYY0MM0DD0hh0mm0ssXXX">> checked="done" unchecked="" default="">Replace Batteries</$checkbox>
<br>

This does not work, too. It creates index value of <<currentTiddler>>202110.....

OK, this works

\define uid() $(tid)$$(time)$

<$vars tid=<<currentTiddler>> time=<<now YYYY0MM0DD0hh0mm0ssXXX>>>
<$checkbox tiddler="ExampleData" index=<<uid>> checked="done" unchecked="" default=""> Replace Batteries</$checkbox>
</$vars><br>

You can put all of it in a macro and call it with only your “item”, e.g:

\define uid() $(tid)$$(time)$

\define aaa(item)
<$vars tid=<<currentTiddler>> time=<<now YYYY0MM0DD0hh0mm0ssXXX>>>
<$checkbox tiddler="ExampleData" index=<<uid>> checked="done" unchecked="" default=""> $item$</$checkbox>
</$vars>
\end

<<aaa "Replace batteries">>

@twMat Thank you so much. Yes. It does. The ExampleData tiddler does carry an index properly named.

But this also means that as soon as it is checked. the box gets unchecked. Time moves on. 20211006141516789 becomes 20211006141516790. So, the checkbox attached to ‘Replace Batteries’ now has a new value that is not in the index. So, it is set to default - unchecked. :slight_smile:

He he - right!

OK, so one idea might be to not name the indices with the time stamp but instead a slugified version of the very item that you check/uncheck. I.e “Replace batteries” would become “replace-batteries”. There is the slugify operator for this.

@twMat Thanks. We have the solution, it seems.

And thanks even more because during the process, you showed the use of several techniques that will come handy in many other situations also.