Javascript in Tiddlywiki

Hello, this is most likely a fairly simple question, but I have a javascript snippet that I want to run on all tiddlers tagged with “Outline”. The snippet is below. How would I do this?

const list = document.querySelector('.collapsible-list');

list.addEventListener('click', (event) => {
  const listItem = event.target.closest('li');
  
  if (listItem) {
    const childList = listItem.querySelector('ul');
    
    if (childList) {
      listItem.classList.toggle('open');
    }
  }
});

If you told me what it does I would do it in TiddlyWiki Script.

If you expect to change a tiddler you must write according to TiddlyWiki standards. For example look at core tiddlers, and the dev site.

1 Like

It allows bullet points to be expanded and collapsed! So I can collapse level 2 and only show the first bullet level, expand the first bullet level to show the next level, etc.

There is the tree macro, defined here and Example Table of Contents: Expandable which do this for specific use cases “/” delimited titles and The table of contents, tiddlers tagged with their parents.

  • I believe others have done something similar via CSS
  • I would use nested lists to achieve the full solution.

I expect others may have a different approach, but I try and use native TiddlyWiki script except when imposible.

I recommend do this in wikitext too. Using JS will make it harder to debug if you add more things years later.

But maybe you can patch ListWidget, overwrite its render method to get super.render 's result, and add event listener to them

Or you can write a startup script like

Don’t forget to add meta data

And run setInterval on it, to check for list element every 1 second (and check whether an event listener already attach to it, by adding a CSS class to already modified element), and add event listener to it.

1 Like

Hi,

First of all, using JS in a tiddler is blocked for security reasons.

Second: TW has it’s own optimized page refresh mechanism.

So it does not make much sense to manipulate the TW UI that way. It will be overwritten by the TW refresh cycle at any times. Saving state in the DOM is not the right way to go for the long run, since with every page reload all your states will be gone.

TW stores internal state with system tiddlers. eg: $:/state/my-list-01 or something similar.

Lists in TW can be created using the list-widget and filter expressions using the filter syntax in combination with the reveal-widget, if you want to do it on your own.

But …

The easiest way to get expandable lists is using the core TOC macros. eg: Expandable or Selective Expandable.

It uses tags to define the structure.


If you need an other field you may be interested in my TocP-plugin, which uses a tiddler-field to create the structure. The default field name is: parent

1 Like

For the brave: enable-js — using inline script tags

this is a macro that enables javascript

1 Like

As you caution this should only be used in special cases and removed from published wikis. Perhaps a few more security levels could be added?

  • I thus draw it to the attention of @jeremyruston and @pmario who have an “eagle eye” on these things :nerd_face:

I do not think it appropriate for this Topic as the solution can use TiddlyWiki Script not javascript.

However if it can be done, it will be done, and in a sand boxed wiki it may be very helpful for design, learning and development work.

  • any solution developed this way should be rewritten to comply with tiddlywiki design requirements before sharing.
  • ie this tool should never be a prerequisit for the distribution of anything.

However I just want to remind people it is best to learn the tiddlywiki way rather than use js in many cases.

The greatest concern is if this makes it into the wild, , “online published wikis” and people place it online, bad actors can do a lot of damage and it could damage tiddlywiki’s reputation by accociation.

Post Script;

  • It is published on TiddlyWiki version: 5.1.7
1 Like

Hey guys,

Appreciate your responses. So to hopefully provide additional clarity, here is a codepen that demonstrates the functionality.

Since it sounds like Javascript ins’t the way to go, is there any way this could be written in Tiddlywiki script?

Yes, this could be written with nested list widgets or macros and either the html details tag / the $details plugin, and or using reveal widgets.

  • More advanced users of CSS may also find a CSS solution

To assist you however please give a TiddlyWiki example, how do you identify the content and its structure. Either share a JSON of tiddlers and use TiddlyWiki.com or set up a public tiddlyhost site (best option).

1 Like

The codepen example does not have any visual indication, that there is more info. There is no visual info if a list is expanded or folded. So as it is, imo it has very little value.

As I wrote the closest macros that work out of the box are the TOC macros using 1 tiddler per list element an using tags to define the structure. The image shows the “selective expandable” example.

Did you have a look at them?

1 Like

The issue with the table of contents macro is that it’s separate tiddlers. What I would be using the collapse/expand functionality for is the contents within a single tiddler!

OK. Then I only wanted to let you know about that possibility, so you can remember it in several month when you need it.

have fun!
mario

But what is the content of your nested lists?

What you are trying to achieve should only need a macro to generate the lists and use some CSS to make the list collapsible and you may find this CSS already in tiddlywiki.

We can help but only if we have a sample of the content you want list.

I suspect you could hack @Mohammad’s Section Editor plugin to do this, replacing the ! used for headers with *. Or, depending on your needs, it might be useful to you as-is: you’d need to write your “lists” as nested headings, but you could style them however you like with CSS.

Section Editor works with single-tiddler content, generates $:/state tiddlers to track the state of each fold, and provides clear visual indicators when a fold is open/closed. It seems pretty close to what you’re looking for, and is certainly the most “TiddlyWiki-friendly” approach I’ve encountered.

Most within-tiddler expansion solutions don’t nest well for true outline behavior.

One that does nest easily is telmiger’s details widget.

I haven’t tried to apply it automatically, however.

1 Like

On Comparison.json (1.7 KB)

Here is a sample of a bulleted list within a tiddler that I would want each bullet expandable/collapsible.

So the example you give is hard coded text using wiki text bullets. If this is in fact the content you want to change into collapsible lists you can use the core internals plugin to see the html generated (it’s just simple ul li tags).

  • You can introduce classes to each bullet with *.classname bullet text if you want, or wrapping items in div and other tags.

Now I am no CSS expert but I believe there are some CSS Only tricks to change a lnested bullet list into colapsable sections.

However since you are writing the content you could use other methods to selectively indicate collapsible content.

With a little searching I came across this, I had to rework it a little, and it is incomplete but it demonstrates a CSS only solution.

<style>
/* ''Collapsing/Expanding Nested Lists'' */
/**/
div > * > * > ul li:hover { color: red; }

div > * > * > ul ul li {
display: none;
}
div > * > * > ul:hover ul li {
display: list-item;
}
div > * > * > ul > ul:before {
content: "more...";
margin-left: -2em;
border: 1px solid #bbbbbb;
padding: 0.1em 0.2em 0.1em 0.2em;
font-size: 0.9em;
color: #999999;
background-color: #eeeeee;
}
div > * > * > ul:hover > ul:before {
display: none;
}
/**/
</style>

<div>

* #1
** #1-1
*** #1-1-1
* #2
** #2-1
*** #2-1-1
*** #2-1-2
** #2-2
*** #2-2-1
*** #2-2-2
</div>
1 Like