Routine for creating a list

Hi all

I am trying to improve my understanding of Tiddlywiki by creating a routine for creating a list. I know there are many examples of simple lists but this is a learning exercise!

I have a list of items in a tiddler called Data.

* item1
* item2

I have also created a tiddler with some code to add a new item to the list in Data.

<style> input.testclass { border-top:none; border-left:none; border-right:none; color: grey; outline: none; border-bottom-width:thin;width:95%;}</style>

<$edit-text field="temp-input" placeholder="Add new entry here" default="" tag="input" class="testclass"/>
<$button class="tc-btn-invisible tc-tiddlylink" tooltip="Add entry">
<$action-setfield $tiddler="Data" $value={{{ [{Data!!text}addsuffix[* ]addsuffix{!!temp-input}] }}}/>
{{$:/core/images/new-button}}
</$button> 

{{Data}}

The problem I have is how to get the new entry to appear on a new line and maintain the list formatting.

Advice would be very much appreciated.

Cheers, Rob

Hi Rob, Very nice for a learning exercise.

There are 2 problems, which are possible to solve.

a) actioins inside the button body
b) Adding a line-break character at the end of the new element in Data tiddler

add a)
The content inside of the button widget body is only updated, once when the button-widget is drawn.
So in your case it does not update the $value={{{ transclusion. So it needs to be added to the button actions-parameter.

add b)
In the $value= assignment you read the existing content of the Data-tiddler and you add the new text. That’ right. – But you also need to add a line-feed control character. The problem with LF is, that it needs to be a binary-value. That’s why a charcode Operator exists

Here is the fixed code, that I did reformat a bit for easier readability.

\procedure enterActions()
<$action-setfield $tiddler="Data"
  $value={{{ [{Data!!text}addsuffix[* ]addsuffix{!!temp-input}addsuffix<.lf>] }}}
/>
\end

\function .lf() [charcode[10]]

<style> input.testclass { border-top:none; border-left:none; border-right:none; color: grey; outline: none; border-bottom-width:thin;width:95%;}</style>

<$edit-text field="temp-input"
  placeholder="Add new entry here"
  default=""
  tag="input"
  class="testclass"
/>
<$button actions=<<enterActions>>
  class="tc-btn-invisible tc-tiddlylink"
  tooltip="Add entry"
>
  {{$:/core/images/new-button}}
</$button> 

{{Data}}

I did add a function \function .lf() [charcode[10]] … which defines the binary representation of the line-feed character. Be aware of the leading . dot in the .lf function name. It is used to indicate that it is a function. It can be added using addsuffix<.lf> in the \procedure enterActions() – Which is also new.

The button-widget now uses actions=<<enterActions>>, which IMO also makes it easier to read. Using it that way, the action is refreshed, whenever the button is clicked. So it will read the actual content of the Data-tiddler.


If you want to get rid of the temp-input value if the + button is clicked, you can delete the temp-tiddler using the action-deletetiddler widget

BUT I leaf that example for you to solve. Hint: You can add it to the enterActions() procedure. It’s plural for a reason :wink:

BUT but but – Make sure you have a backup of your code. action-deletetiddler can be destructive, if the tiddler title parameter is wrong.

2 Likes

Thank you so much for your reply, @pmario . The code enhancements and the commentary have helped my understanding enormously.

I have taken it a bit further by

  1. adding a routine to delete the input field content using $action-setfield
  2. adding a routine to trigger the actions on pressing the ENTER key, with thanks to @etardiff How to make enter submit a text box

I am reproducing my amended code below for the benefit of others.

\procedure enterActions()
<$action-setfield $tiddler="List/data"
  $value={{{ [{List/data!!text}addsuffix<.lf>addsuffix[* ]addsuffix{!!temp-input}] }}}
/>
<$action-setfield $field="temp-input"/>
\end

\function .lf() [charcode[10]]

<style> input.testclass 
{ 
border-top:none; 
border-left:none; 
border-right:none; 
color: grey; 
outline: none; 
border-bottom-width:thin;
width:95%;
}
</style>

<$keyboard key="Enter" actions=<<enterActions>> >
<$edit-text field="temp-input"
  placeholder="Add new entry here"
  default=""
  tag="input"
  class="testclass"
/>
</$keyboard>
<$button actions=<<enterActions>>
  class="tc-btn-invisible tc-tiddlylink"
  tooltip="Add entry"
>
  {{$:/core/images/new-button}}
</$button> 

{{List/data}}

Data storage location: [[List/data]]

Thanks to everyone on this forum for being so helpful

Cheers, Rob

4 Likes

At the risk of making too much noise about a thread that is marked solved, I am taking the liberty to ask a question.

When reading the quoted part, I don’t get the feeling that this is a question about managing a list of items. To me it rather looks like a question of modifying a string - albeit a multiline one, yet still a string - the value of the text field of the Data tiddler. While I admit the example above can be a hypothetical one, I still have to ask: what is the real informational load of item1 and item2? Is it, by any chance, big enough to make item1 and item2 worthy to be considered tiddlers rather than strings? If this was true, you could create one tiddler for each item, collect and order them as you wish by using a filter, and generate a list (that will autoupdate itself whenever you add/remove/change item tiddlers) by using said filter in a <$list> widget. You wouldn’t have to micromanage wikitext markup (like you do in the example above) at all.

An argument that pushed me towards thinking about the scenario above is a best practice advice from here Grok TiddlyWiki — Build a deep, lasting understanding of TiddlyWiki

Many new users of TiddlyWiki start by creating what experienced users would consider monster tiddlers, containing pages-long bulleted lists, lots of headings and subheadings, and so on. As such, a good rule of thumb, when you’re getting started, is to create more tiddlers than you think you should .

But perhaps I’m taking this too literally and it does not apply to your use case?

PS: I clearly don’t pretend to be an "experienced user"™, I’m rather the opposite of that