\widget (custom widget) demo using eventcatcher and "not-a-bug"

In TiddlyWiki, I have often wanted to take programmatic control of the HTML <details> element. With the advent of custom widgets since 5.3.x, I’ve been thinking about trying to do that. This then, is my first pancake – $details.2

\widget $details.2(hdr-text:"Untitled", class:"")
\procedure actions()
 <$let the-state={{{ [<state>get[text]] }}}>
 <<logger actions self>>
 <$if value=<<the-state>> match=open>
  <$action-setfield $tiddler=<<state>> $value=closed/>
 </$if><$else>
  <$action-setfield $tiddler=<<state>> $value=open/>
 </$else>
 </$let>
\end actions
<$qualify name=state title={{{ [[$:/state/disclosure/details.2/]addsuffix<hdr-text>] }}}> <<logger 1 2>>
 <$eventcatcher selector=".bk-details-hdr[data-state=closed], .bk-details-hdr[data-state=open]" $click=<<actions>> stopPropogation=always>
   <div class={{{ [<class>addsuffix[ bk-details other-class]] }}}>
    <$reveal state=<<state>> type=match text="closed" default="closed">
     <div class="bk-details-hdr" data-state=closed><<hdr-text>></div>
    </$reveal>
    <$reveal state=<<state>> type=match text="open">
     <div class="bk-details-hdr open" data-state=open><<hdr-text>></div>
     <div class="bk-details-content">
      <$slot $name="ts-raw"/>
     </div>
    </$reveal>
   </div>
 </$eventcatcher>
</$qualify>
<style>
.bk-details-hdr {
 display: list-item;
}
.bk-details-hdr[data-state=closed] {
 list-style-type: disclosure-closed;
}
.bk-details-hdr[data-state=open]{
 list-style-type: disclosure-open;
}
</style>
\end

Call it with…

<$details.2 hdr-text="The header" class="d1">
This is the content
</$details.2>

<$details.2 hdr-text="Another header" class="d2">
This is some other content
</$details.2>

You may notice…

  1. It’s completely self-contained. Everything it needs is buried inside the $details.2 widget, even its basic styling (you can, of course, modify the names to suit your own wiki’s namespacing).

  2. It uses $eventcatcher to handle click events.

  3. It uses all 5.3-newness – \widget and \procedure

I used the condition plugin too which some may want to rewrite to use $reveal.

Now, about that mysterious not-a-bug in the title…

DO NOT EVER write an $eventcatcher block starting like this… :man_teacher:

<$eventcatcher $selector=".bk-details-hdr[data-state=closed], .bk-details-hdr[data-state=open]" $click=<<actions>> blah blah blah>

The eagle-eyed (@saqimtiaz ?) will have spotted the problem already. The reason I bring this up is, even though that’s a really silly (and once you’ve seen it, quite obvious) typo, the thing actually worked – it actually trapped clicks! Except

– there were no dom-* variables passed into the event handler.

That’s an hour of my life I won’t get back! :scream:

@saqimtiaz Comments?

For those struggling to see the problem: $selectorselector

3 Likes

@CodaCoder I had a go at using custom widgets to handle the details tag earlier but never polished it enough to share. It is interesting to see how you have addressed this, although I do not follow all of the reasoning (yet).

  • My solution also allows a tiddler name or variable to be give as the contents of the details widget
  • I do not use any third party solutions
  • I only use a class for apperance not visibility.

I can share here or wait untilI I publish.

Of course…


<$details.2 hdr-text={{!!my-field}}>
{{some-tiddler}}
</$details.2>

As do I.    

<$.details content="this info"/>
<$.details tiddler=some-tiddler/>

<$.details>

{{some-tiddler}}
/>

All additional parameters such as class and style are passed through to the html details tag, including open

<$.details content="this info" open/>

Of course this only sets the initial state. But the use of a state tiddler will b e back in soon.

Here is my work in progress;

\widget $.details()
<$parameters content tiddler summary="Details" hr-details-class="hr-details" $params=params >
<$genesis $type="details" 
    $names="[<params>jsonindexes[]]" 
    $values="[<params>jsonindexes[]] :map[<params>jsonget<currentTiddler>]" 
>
<summary><<summary>></summary>

<$transclude $variable=content $mode=block/>
<$slot $name="ts-raw"/>
<$transclude tiddler=<<tiddler>> mode=block/>
<$button tag=hr tooltip={{{ [[Bottom of ]addsuffix<summary>] }}} class=<<hr-details-class>>/>

</$genesis>
</$parameters>
\end $.details

Perhaps I wasn’t clear in my OP…

My “issues” with the HTML <details> element…

  1. open is a boolean attribute. This means it does not support a value. For example, if you were to use open=false the browser would (damn well should) OPEN the details element. The mere presence of open means open (disclose) the content. Its absence means “closed”.

  2. I want other things to happen when the header is clicked, right-clicked, shift-clicked etc, etc. Admittedly, I could just wrap <details> in $eventcatcher but if I’m going to do that, then why not use spans and divs, or anything to create the structure? Why be tied to the browser’s idea of what I “need”? Which is what I’ve done. And now I don’t need that pesky boolean attribute to contend with.

  2.1. I’ve never managed yet to handle boolean attributes in TW. Perhaps there is a way, but I don’t know how.

  1. The formal structure displayed in this one example is merely a design choice. I could easily have tied together a header and content section from without the hosting outer div. The <<tabs>> macro makes the same choice – notionally speaking, multiple <summary> (actually <button>) elements sitting side by side (or head to toe).

I always wanted a tabs macro that didn’t need a set of tiddlers to provide the tab content. Now I have what I need (with a little more CSS).

Anyway, it’s all good fun. I’m loving 5.3 :heart:

You were clear;

  1. The state tiddler was in my code and I removed it durring devlopment
    1.2 I designed it so the passive version “also” works
    1.3 being able to start it open or closed suits 90% of my use cases, I like it to be open or closed on my return, as set, but I understand the need.
  2. Sure, I did not design for that, but can of course
  3. Not sure I follow, but will experiment

Cant you point me to if else solution please, so I can test your example?

I love 5.3.x as well :heart_decoration: , and love sharing my learings :nerd_face:

Sure: Formulas for TiddlyWiki — spreadsheet-inspired number crunching

Ignore the wording in the link - it’ll take you to the if-else plugin (he calls it the condition plugin). To be clear, you don’t need to install the Formulas plugin.

But really, it’s easy to convert the above to $reveal… better yet, why not wait for the <%if [<filter>] %> shortcut syntax to appear?

Re point 3. I was just making the case that tabs, details and details.2 follow a similar pattern. But details.2 may not stay that way. We’ll see…