How to create multiple entries in a data tiddler?

321 views
Skip to first unread message

si

unread,
Nov 10, 2019, 3:56:05 PM11/10/19
to TiddlyWiki
Hi all.

I'm struggling to figure out how to create both multiple objects in a JSONTiddler and nested objects.

Here is an example of some code to create an entry in the JSONTiddler "myData".

<$edit-text tiddler="$:/state/enter-text"/>

<$button>
<$wikify name=title-value text="<
<currentTiddler>> - <<now>>" >
<$action-setfield $tiddler=myData $index="Title" $value=<
<title-value>>/>
<$action-setfield $tiddler=myData $index="Text" $value={{$:/state/enter-text}}/>
<$action-setfield $tiddler=myData $index="Date" $value=<
<now>>/>
Save
</$wikify>
</$button>

At the moment when I press "Save" it overwrites any data already in "myData". How can I change my code so that I can click "Save" and have a new entry added to "myData" each time?

It's also not clear to me how to create nested objects so if someone could point me in right direction on that aswell I would really appreciate it!

Thanks in advance for your help. Si.

Mark S.

unread,
Nov 10, 2019, 5:24:34 PM11/10/19
to TiddlyWiki
Since you're writing to the same indexes on the same tiddler, it overwrites them.

There's no tools in TW for handling nested data tidders, but you can use

Joshua Fontany's JSON Mangler:


Then you can make $index=level1/Title, $index=level2/Title, etc. and create nested data tiddlers.

Good luck!

si

unread,
Nov 13, 2019, 2:51:24 PM11/13/19
to tiddl...@googlegroups.com
Thanks for your help, that does the trick.

In order to get a new numerical value for each level every time I press the button I have used the MathyThing plugin to increment the number in a field called "number". It's a little tenuous though because it will be easy in my use case to accidentally overwrite this number.

Do you know of a better way to this? e.g. a way to count the number of bottom level entries in the JSONTiddler and add 1 or something?

I've attached an example of what I have done.

<$edit-text tiddler="$:/state/enter-text"/>

<$button>
<$wikify name=title-value text="<<currentTiddler>> [{{!!number}}]/Title" >
<$wikify name=text-value text="<<currentTiddler>> [{{!!number}}]/Text" >
<$wikify name=date-value text="<<currentTiddler>> [{{!!number}}]/Date" >
<$action-increment $tiddler=<<currentTiddler>> $field=number $initial="0" $increment="1"/>
<$action-setfield $tiddler=myData $index=<<title-value>> $value=<<currentTiddler>>/>
<$action-setfield $tiddler=myData $index=<<text-value>> $value={{$:/state/enter-text}}/>
<$action-setfield $tiddler=myData $index=<<date-value>> $value=<<now>>/>
</$wikify>
</$wikify>
</$wikify>
Save
</$button>

Thanks again for your help.
multiple-json.html

Mark S.

unread,
Nov 13, 2019, 3:31:18 PM11/13/19
to TiddlyWiki
Joshua's site says that the improved "indexes" filter will return all paths. So

IF you have the same number of entries for each nested group, then you can divide by that number and add one to get the next number in the sequence:

<$list filter="[[myData]indexes[]count[]divide[2]add[1]]" variable="nextnum">
... do stuff
</$list>

This example assumes 2 items per group.

The problem with this approach is that you might, at some time, delete an entry. So this approach only works if you never delete entries.

A more advanced approach would require you to add a "number" field to each nested group. If you had such an index, then you could write
a macro that would run through the entries, find the highest value and add one.

hth

TonyM

unread,
Nov 13, 2019, 6:32:54 PM11/13/19
to TiddlyWiki
Mark perhaps each time you add a tiddler to the data tiddler you increment a key number and use it as the key, even in a field on the data tiddler

If you delete a tiddler it will just be a missing key.

If you use a button to add new tiddlers you can make use of the button to trigger an event to add one with the current operators (use triple curly braces) to the key/index number and set the key number field to the new value.

Tony

Mark S.

unread,
Nov 13, 2019, 7:56:54 PM11/13/19
to TiddlyWiki
Yeah. That's a good idea.

si

unread,
Nov 14, 2019, 4:18:26 PM11/14/19
to tiddl...@googlegroups.com
Tony

I'm not sure if I am understanding your suggestion correctly - do you mean something like this?:

<$edit-text tiddler="$:/state/enter-text" />

<$button>
<$action-setfield $tiddler=myData $index="Key Number" $value={{{ [{myData##Key Number}add[1]] }}} />
<$wikify name=title-value text="<
<currentTiddler>> [{{myData##Key Number}}]/Title" >
...
<$action-setfield $tiddler=myData $index=<
<title-value>> $value=<<currentTiddler>>/>
...
</$button>

Which gives the example result:
{
    "Key Number": 3,
    "json test [1]": {
        "Title": "json test",
        "Text": "Here is some text.",
        "Date": "21:14, 14th November 2019"
    },
    "json test [2]": {
        "Title": "json test",
        "Text": "Blah",
        "Date": "21:14, 14th November 2019"
    }
}

In my example I added an extra button to save an initial value of 1 for "Key Number". I can't think of a way to build this into my main button for creating data entries (without an initial value the first entry will be "json test []" then "json test [1]" etc...)?
multiple-json v2.html

TonyM

unread,
Nov 14, 2019, 5:36:05 PM11/14/19
to TiddlyWiki
Si,

Yes you are very close, I did not think about keeping the key value in the datatiddler json rather I would have used 
value={{{ [{myData!!lastkey}add[1]] }}}
and set myData!!lastkey

No need to have to look into the data to get the last key

Its critical that the button that creates the data item in the dattatiddler is the same one that saves the last key

Psudo code

Calculate newkey number from datatidder!!lastkey
Button to create new record
   Action Create new record actions with key = newkey number
   Action Save newkey number in lastkey field datatidder!!lastkey
end button

To set the initial value for the key to 1 (when no entry exists) try this

<$set name=new-key value=value={{{ [{myData!!lastkey}add[1]] }}} emptyValue="1">

above pseudo code

</$set>

Regards
Tony

Joshua Fontany

unread,
Dec 6, 2019, 3:23:57 PM12/6/19
to TiddlyWiki
Hey all!

Awesome to see you experimenting with my tools. There was another use-case similar to thgis that I cam up with a very interesting trick for. Let me see if I can find it...

https://groups.google.com/d/msg/tiddlywiki/REBHwjgVALA/7L1gKQ8LBAAJ

The below psuedo-example assumes you have my plugin installed to handle the nested index syntex...

The trick is to structure your data to use a zero-based index, so that your total count of indexes (of a certain prefix, which you can filter for) is one more than your last root-index#.

Tiddler title= "Test_data.json"
```
{
 "test_0": {"Title": "json test", "Text": "Blah", "Date": "21:14, 14th November 2019"},
 "test_1": {"Title": "json test", "Text": "Blah", "Date": "21:23, 15th November 2019"}
}
```

So, this would target then next "slot":

<$set name="newRoot" value={{{ [[Test_data.json]indexes[]prefix[test_]count[]addprefix[test_]] }}} emptyValue="test_0" >


<$button>
<$action-setfield $tiddler="Test_data.json" $index={{{ [<newRoot>addsuffix[/Title]] }}} $value="json test" />
<$action-setfield $tiddler="Test_data.json" $index={{{ [<newRoot>addsuffix[/Text]] }}} $value="Blah" />
<$action-setfield $tiddler="Test_data.json" $index={{{ [<newRoot>addsuffix[/Date]] }}} $value=<<now>> />

Run Test
</$button>

</$set>


Best!
Joshua Fontany

Joshua Fontany

unread,
Dec 6, 2019, 3:36:21 PM12/6/19
to TiddlyWiki
Hahahah,

You know I had to test that pseudo-example. Here's is the corrected version. Note that you have to filter the indexes[] result BY SUFFIX "/Title" to get the correct count. Makes sense now that I see it after debugging, lol.

<$set name="newRoot" value={{{ [[Test_data.json]indexes[]suffix[/Title]count[]addprefix[test_]] }}} emptyValue="test_0" >

<<newRoot>>

TonyM

unread,
Dec 6, 2019, 6:00:46 PM12/6/19
to TiddlyWiki
Joshua,

if one maintains the last item number elsewhere retrieve it and increment/save its perhaps more efficent. Of course this action needs a trigger so I have placed it at the beginning of a button that creates the new item.

Another trick is I have used this method to generate a tiddler serial number if one does not exist on a tiddler on save tiddler.

Regards
Tont

Reply all
Reply to author
Forward
0 new messages