Help to Create a Simple Combo Search Macro

I am looking for a simple combo search macro to be able

  1. Get a filter from user and list the results based on that filter
  2. Have a search box to further filter or search in the result of first step
    2.1. if enter keywords, it searches like TW standard search box
    2.2. If enter a search filter like ([prefix[Car]] it searches like $:/AdvancedSearch filter search box

My initial solution is as below

Macro code

\define temp-tiddler()  xx$:/temp/combo-search$(qualify)$
\define simple-search() :and[search[$(search-input)$]]
\define filter-search() :and$(search-input)$
\define combo-filter() $(__filter__)$$(search-terms)$ :filter[!is[missing]]


\define combo-search-list(filter, template:"$:/core/ui/ListItemTemplate")
<$edit-text tiddler=<<temp-tiddler>> tag=input default="" placeholder="enter search term or filter" class="w-75"/>

<$let lb="["
      search-input   = {{{ [<temp-tiddler>get[text]] }}} 
      search-terms  = {{{ [<search-input>prefix<lb>then<filter-search>else<simple-search>]}}}
>
    <small><$count filter=<<combo-filter>> /> matches</small>
    <$list filter=<<combo-filter>> template=<<__template__>> />
</$let>
\end

Example

<<combo-search-list "[tag[Learning]]">>

Demo

img_067_msedge

Remarks

  • Start search with [, macro will perform filter search
  • Start with any other character, macro will perform a standard search
  • If you want to search for a link where it starts with [ then use a leading space, so [[Test]] will perform a standard search not a filter search, note to the leading space
  • Macro accepts a template to show the result. See recent discussion by @TW_Tones, so it is very powerful to show anything you like as its result

Edge cases

Some history on custom search macro / search box

  1. PowerSearch from @EricShulman is very powerful and very useful for learning filters, it is among the best
  2. The first list-search was proposed by Tobias Beer
  3. Later on Shiraz introduced a nice hackable UI for list-search
  4. Another list-search was introduced by @DaveGifford
  5. @telumire introduced a modern search-list with advanced search bottom (one of the best)
  6. Tiddler Commander uses combo-search in its UI and is highly powerful
  7. CommandPalette from @soku21 has great features to selectively search in tags, title
  8. @stobot has a combo search and it is highly flexible. It allows to search from one box for system tiddlers, shadow tiddlers, and perform filter search
  9. Other … (please add…)

Help needed

I would appreciate to help

  1. make macro simpler
  2. make macro more usable
  3. make macro readable and maintainable
  4. make macro use WikiText modern syntax, instead of old
1 Like

Just to be accurate, I did not develop a list search. I use Tobias Beer’s macro.

I have only tinkered wiith it by changing the listitem template involved, so that results are displayed differently.

One limitation of this macro is that you can only search one field: you can specify whether to search titles, tags, text, etc, but only one, and never all of them. So it would be nice to have a way to search all fields and maybe distinguish different types of search results.

I doubt I will be able to help you, but I will play with yours, and look up telmire’s.

Thank you for clarification!

This is possible, just enter as below

[search:*[your keyword]]

or

[search:created,modified[your keyword]]

Yes, I meant a limitation of Tobias’ macro, not yours.

I just tried yours, and I think I am going to start using yours from now on!

1 Like

Thanks for mentioning me ! Here’s my attempt at a combo search:

<$edit-text field="search"/>

Results:

<$let search={{!!search}} containsfilter="[" isFilter="[<search>search<containsfilter>]">

<<list-links "[<search>filter<isFilter>]:map:flat[all[tiddlers+shadows]subfilter<search>]~[all[tiddlers]!is[system]search<search>]:filter[<search>minlength[3]]">>

</$let>

Note: I’ll edit my post later to improve on this


EDIT: Simpler version + support search for wikitext links

<$edit-text field="search"/>

Results:

<$let search={{!!search}} minlength="[<search>minlength[3]]">

<$list 
filter="[filter<minlength>!is[system]search<search>limit[1]]"
emptyMessage="""<<list-links "[filter<minlength>subfilter<search>]:filter[<search>!search[|]]">>"""
>
<<list-links "[search<search>!is[system]]">>
</$list>
</$let>

Combo Search with button to clear the search field + style for the search input:

Combo search.json (1.7 KB)

https://demos.tiddlyhost.com/#Combo%20search

1 Like

Quick simple and effective.

  • Thanks for the inspiration
  • Redesigning core solutions are very messy due to the keyboard widget
  • Is filter is not yet working?
  • Could open modal or popup
  • Selection could be returned to a state tiddler or field “radio”
    • or add to a list using the new checkbox listIndex
  • The ability to add an include only filter and and exclude filter in a macro parameters would be nice.

The filter is working but I want to improve/add an ui for it, will do later

I am preparing a variation on this I will share and you can plgerise if you want.

Search all or Add fiter from core filter drop down
Use as macro
Use modifyer filter eg +[sort[]]
Choose the list item template (planned)
More?

1 Like

This is another Combo Search inspired from @telumire (TiddlyTweaks — Small tweaks for TiddlyWiki) to use two different search boxes.
In this version, I used a single searchbox but with a button to switch between two modes

  • Standard/simple search
  • Filter search
\define search-tiddler() $:/temp/search-telumire$(qualify)$

\define clear-button(field)
<$reveal stateTitle=<<search-tiddler>> stateField=<<__field__>> type="nomatch" text="">
    <$button class="tc-btn-invisible" tooltip="cancel search" 
		         actions='<$action-setfield $tiddler=<<search-tiddler>> $field=<<__field__>> $value=""/>' >
        {{$:/core/images/close-button}}
    </$button>
</$reveal>
\end

\define final-search-filter() $(__filter__)$:and$(search-filter)$

\define search-ui(filter, template:"$:/core/ui/ListItemTemplate")
<!--- search UI --->
<div class="tc-advanced-search">
<b><$text text={{{ [<search-tiddler>get[search-type]] :else[[simple]] }}} /></b> search<br/>
<$edit-text tiddler=<<search-tiddler>> field={{{ [<search-tiddler>get[search-type]] :else[[simple]] }}} tag="input" default="" placeholder={{$:/showInfo/search/placeholder}} class="tc-edit-texteditor w-75"/>&nbsp;
<$macrocall $name="clear-button" field={{{ [<search-tiddler>get[search-type]] :else[[simple]] }}} />
<$button class="tc-btn-invisible" tooltip="advanced search" 
          actions='<$action-listops $tiddler=<<search-tiddler>> $field="search-type" $subfilter="+[toggle[filter],[simple]]"/>' >
    {{$:/core/images/advanced-search-button}}
</$button>
</div>

<!--- search result --->
<div>
<$let 
  simple-search-term   = {{{ [<search-tiddler>get[simple]] }}}
	filter-search-filter = {{{ [<search-tiddler>get[filter]]   "[search[]]" :and[limit[1]]      }}} 
	simple-search-filter = "[search<simple-search-term>]"
	search-type          = {{{ [<search-tiddler>get[search-type]] :else[[simple]] }}}
  search-filter        = {{{ [<search-type>match[simple]then<simple-search-filter>else<filter-search-filter>]}}} >

<small><i><$count filter=<<final-search-filter>> />&nbsp; matches</i></small>

<$list filter=<<final-search-filter>> template=<<__template__>> />
</$let>
</div>
\end

Demo

img_069_msedge

1 Like

I think the advantage of a “combo serach” is, that it automatically detects filters and behaves accordingly. So adding a button imo is a regression already and the code seems to be more complex too.

2 Likes

I think your code is easy to follow and easy to read. At the moment, we don’t have a new syntax for text substitution in the core other than the one you use.

So I think the implementation is fine. … If you need to make it more advanced, you could add the “more” dropdown from the advanced-search “Filter” tab, that shows predefined filter snippets, which would make it easier for users to work with filters.

just an idea

1 Like

Very clever solution! For me the filter part does not work.
Also note that a user may wish to look for a link like [[Test|myTest]] where it is not a filter.

I got it working with :map:flat[all[tiddlers]!is[system]subfilter<search>]

See the related Search for a phrase - #3 by TW_Tones

The version I am working on based on @telumire’s above looks like this so far, but UI improvements are neeed

  • The intention is to hide the the extra fields unless needed.
  • If you don’t use anything in search you get the result of the include filter.
    • If you do use the search field then it relates only to included items
  • It is in a macro you can preload the the values.

Ah yes, good catch ! Maybe it would be better to leave out the !is[system] to allow people to search for those, and maybe add shadows ? So this: :map:flat[all[tiddlers+shadows]subfilter<search>]

1 Like

Very interesting post! Kudos!

IMO, search in TW is fundamental. In a sense every type of filter is just a search variant.

From my point of view, it might be interesting to do a proper formal analysis of …

(1) — search strategies users already use;

(2) — a survey of the (many) solutions already created;

(3) — consideration of integrating the highlighting of search terms in results;

(4) — discussion of “live reductive search”, such as @BurningTreeC does in MCL. Meaning rather than searching all tiddlers you search only open tiddlers and hide those that don’t match;

(5) — direct support for Regular Expressions without need for passing a match string through a variable placeholder.

Just comments, TT