KISS Macro to Create an Accordion

This is a very simple accordion in TiddlyWiki (only 15 lines)

\define accordion(filter, stateTiddler)
\define actions() <$action-setfield  $tiddler=<<__stateTiddler__>> $field=text $value={{{ [<__stateTiddler__>contains:text<currentTiddler>then[]else<currentTiddler>] }}} />
<div class="accordion">
<$list filter=<<__filter__>> >
<$button class="accordion__title" actions=<<actions>>  tag=div>
<$view field=caption/>
</$button>
<$reveal type="match" state=<<__stateTiddler__>> text=<<currentTiddler>> class="accordion__copy" tag=div>
<$transclude mode=block/>
</$reveal>
</$list>	
</div>
\end

<<accordion "[tag[bem101]]" $:/state/accordion>>

Screenshot

img_088_msedge

Demo

  1. download kiss-accordion-macro.json (3.6 KB)
  2. drop into https://tiddlywiki.com/
  3. open examples/bem101-02

Contribute

  • The state tiddler needs to be improved (some automatic value to be used)
  • Better style
  • Transition effects on opening/closing accordion

See Release 2.0 Below

8 Likes

@Mohammad Any idea why the accordion is not closing when I click the second time in this tiddler - these are dashboard tiddlers of GSD5 plug in.
But it is working in another tiddler in the same wiki.

@arunnbabu81 If the tiddlers involved have spaces in the titles, the accordion doesn’t work. The “contains” operator is treating the text field as a List field, and each separate word an an individual title.

Here’s an edit that seems to work after some quick tests:

\define accordion(filter, stateTiddler)
\define actions() <$action-setfield  $tiddler=<<__stateTiddler__>> $field=text $value={{{ [<__stateTiddler__>get[text]match<currentTiddler>then[]else<currentTiddler>] }}} />
<div class="accordion">
<$list filter=<<__filter__>> >
<$button class="accordion__title" actions=<<actions>>  tag=div>
<$view field=caption/>
</$button>
<$reveal type="match" state=<<__stateTiddler__>> text=<<currentTiddler>> class="accordion__copy" tag=div>
<$transclude mode=block/>
</$reveal>
</$list>	
</div>
\end
1 Like

@Brian_Radspinner thank you, this seem to work in my wiki also.

Instead of caption use the title doesn’t work:

<$view field="title"/>

It would be nice to use the caption or - if not there - the title - how can that be archived?
Thanks.

If you replace the following line

<$view field=caption/>

with this

<$set name="title"  filter={{{ [<currentTiddler>has[caption]get[caption]] [<currentTiddler>!has[caption]get[title]] }}}>

<$text text=<<title>> />

</$set>

It does the job.


I am not happy with my filter.

{{{ [<currentTiddler>has[caption]get[caption]] [<currentTiddler>!has[caption]get[title]] }}}

I think it can be shortened using then and else. But I could not figure out the syntax.

Thanks for feedback - but it dosn’t work

Content of open tiddler:

Please see this

https://random-2022-11-22-1669114329.tiddlyhost.com/#Modified%20example

Also I based my patch on @Brian_Radspinner code.

Thanks @talha131 - no it works. :slight_smile:

(There was an issue with the "background" in my CSS.)

1 Like

One additional question:

I’ve also a field called ‘published’ containing a date (eg. 2022.12.31) to be independent from ‘modified’ and ‘created’

How do I get the output sorted?
grafik

sort should do the job

<<accordion "[tag[bem101]!sort[published]]" $:/state/accordion>>

!sort does descending sort.

sort does ascending.

https://random-2022-11-22-1669114329.tiddlyhost.com/#Modified%20example%20with%20sort

2 Likes

This is an updated version of Accordion macro

Code

\define accordion(filter, stateTiddler:01)
<$let stateTiddler={{{ [[$:/state/accordion/$stateTiddler$]addsuffix<qualify>] }}}
      btn-actions='<$action-setfield  $tiddler=<<stateTiddler>> $field=text $value={{{ [<stateTiddler>get[text]match<currentTiddler>then[]else<currentTiddler>] }}} />' >
<div class="accordion">
<$list filter=<<__filter__>> >
<$button class="accordion__title" actions=<<btn-actions>>  tag=div>
<$view field=caption><$view field=title/></$view>
</$button>
<$reveal type="match" state=<<stateTiddler>> text=<<currentTiddler>> class="accordion__content" tag=div>
<$transclude mode=block/>
</$reveal>
</$list>	
</div>      
</$let>
\end

Example

<<accordion "[tag[bem101]]">>

Screenshot

img_096_msedge

Demo

  1. Download kiss-macro-accordion.json (3.8 KB)
  2. Drag and drop into https://tiddlywiki.com/
  3. open Ex051/test

Contribute

  1. Add some animation for smooth sliding
  2. Add other colors
  3. Make it compatible with dark themes
2 Likes

What code is needed that open tiddler remains selected (highlighted)?

1 Like

Hi @StS
This is an accordion macro, so by design only one slide is displayed at a time.
For keeping open several slides (tiddlers) at a time, use details, or slider in Shiraz!

These are advanced tutorials of Shiraz using slider and details to show a searchable list of slides (collapsible section with title).

Advanced FAQ Pages - Shiraz 2.7.0

Hi @Mohammad

sorry - maybe I was not clear enough.

It is ok, that only one slider is open:

but the open slider should be highlighted in color (here shown with hover effect)
grafik

Thanks

Oh, you mean highlight selected title, try below code. Use better color and put the style inside the stylesheet tiddler.

\define accordion(filter, stateTiddler:01)
<$let stateTiddler={{{ [[$:/state/accordion/$stateTiddler$]addsuffix<qualify>] }}}
      btn-actions='<$action-setfield  $tiddler=<<stateTiddler>> $field=text $value={{{ [<stateTiddler>get[text]match<currentTiddler>then[]else<currentTiddler>] }}} />' >
<div class="accordion">
<$list filter=<<__filter__>> >
<$button class={{{[[accordion__title]] [<stateTiddler>get[text]match<currentTiddler>then[accordion_selected]] :and[join[ ]] }}} actions=<<btn-actions>>  tag=div>
<$view field=caption><$view field=title/></$view>
</$button>
<$reveal type="match" state=<<stateTiddler>> text=<<currentTiddler>> class="accordion__content" tag=div>
<$transclude mode=block/>
</$reveal>
</$list>	
</div>      
</$let>
\end

<style>
.accordion_selected {
	background-color:#ffbf00;
	color:blue;
}
.accordion__title.accordion_selected:hover{
	background-color:#ffbf00cc;	
}
</style>

<<accordion "[tag[bem101]]">>

img_106_msedge

4 Likes

Thanks @Mohammad - that’s what I was asking for. :wave:

Hello forum,
how can the current tiddler (=“Summary”) be excluded without removing the tag “test”?
grafik

This is not working:

<<accordion "[tag[test]!<currentTiddler>sort[an]]">> 

I’m using this macro:

\define accordion(filter, stateTiddler:01)
<$let stateTiddler={{{ [[$:/state/accordion/$stateTiddler$]addsuffix<qualify>] }}}
      btn-actions='<$action-setfield  $tiddler=<<stateTiddler>> $field=text $value={{{ [<stateTiddler>get[text]match<currentTiddler>then[]else<currentTiddler>] }}} />' >
<div class="accordion">
<$list filter=<<__filter__>> >
<$button class={{{[[accordion_title]] [<stateTiddler>get[text]match<currentTiddler>then[accordion_selected]] :and[join[ ]] }}} actions=<<btn-actions>>  tag=div>
<$transclude field=caption>
   <$view field=title/>
   &nbsp;
   <span style="font-size: 0.6em; color: rgb(144, 238, 144)"> 
      <$view field=erstellt/>
   </span>
</$transclude>
</$button>
<$reveal type="match" state=<<stateTiddler>> text=<<currentTiddler>> class="accordion__content" tag=div>
<$transclude mode=block/>
</$reveal>
</$list>	
</div>      
</$let>
\end

Thanks
Stefan

Use below filter

<<accordion "[tag[test]] :except[<currentTiddler>] :and[sort[an]]">> 

Thanks @Mohammad - works great :slight_smile: