Tag picker issues

I’m designing an interface tiddler with the tag-picker macro to permit selection of an ‘include’ and ‘exclude’ list of tags with the goal of using the lists as input to a filter. Something like:

With tiddlers tagged like so:

  • placing bronze
  • placing silver
  • placing gold

I’ve encountered a few issues and wonder how they can be resolved:

  1. When clicking into the ‘tag name’ box then both tag-pickers simultaneously show a dropdown!!
  2. When a tag is selected via tag-picker it invokes the tiddler’s main dropdown list of tags to be shown!?
  3. I’d like an editable display of the ‘include’ & ‘exclude’ tag lists, just like the general tiddler functionality.
  4. How to pass the selections into the filter and fetch partial ‘include’ and ‘exclude’ matches. But O.M.G the filter syntax and documentation :face_with_head_bandage:

My pseudocode :wink:

Include <<tag-picker tagField:"incl">> Exclude <<tag-picker tagField:"excl">>

Include: {{!!incl}}

Exclude: {{!!excl}}

Matches:
<!-- Filter goes here, to give list of links to matches -->
<$list filter="[all[]search:tags[ {{!!incl}} ]] - tags[ {{!!excl}} ]">
 <$link to=<<currentTiddler>>></$link>
</$list>   

Is it possible to accomplish the goal?

Thx,
TechTangle

This is because they share the same transclusion variable, you can prevent that like this:


<$let transclusion="taglist1">
...tagpicker here..
</$let>
<$let transclusion="taglist2">
...tagpicker here..
</$let>

Top achieve what you have in mind I think my improved tagpicker macro can help you :Demos — Q&A and tools for tiddlywiki , it can filter the list of tag picked.

I included it in the complete solution bellow:

\import [[$:/core/ui/EditTemplate/tags]]
\define tag-button(classes)
	<$let button-classes='tc-btn-invisible $classes$' currentTiddler=<<tag>>>
		{{||$:/core/ui/TagPickerTagTemplate}}
	</$let>
\end
\define tagsAutoComplete()
<$list filter=<<tagsAutoCompleteFilter>> emptyMessage=<<tagsAutoCompleteEmptyMessage>> variable="listItem">
	<$list filter=<<tagsFilter>> variable="tag">
		<$list
			filter="[<tag>addsuffix<suffix>] -[<tagSelectionState>get[text]]"
			emptyMessage=<<tag-button 'tc-tag-button-selected'>>
			variable="ignore"
		>
			<<tag-button>>
		</$list>
	</$list>
</$list>
\end
\define tag-picker-inner(actions,tagField:"tags")
\whitespace trim
<$let 
	newTagNameInputTiddlerQualified=<<qualify "$:/temp/NewTagName/input">> 
	newTagNameSelectionTiddlerQualified=<<qualify "$:/temp/NewTagName/selected-item">> 
	fallbackTarget={{$(palette)$##tag-background}}
	colourA={{$(palette)$##foreground}}
	colourB={{$(palette)$##background}}
	storeTitle={{{ [<newTagNameInputTiddler>!match[]] ~[<newTagNameInputTiddlerQualified>] }}} 
	tagSelectionState={{{ [<newTagNameSelectionTiddler>!match[]] ~[<newTagNameSelectionTiddlerQualified>] }}}
	refreshTitle=<<qualify "$:/temp/NewTagName/refresh">>
	nonSystemTagsFilter="[tags[]] $(tagListFilter)$ +[!is[system]] -[<storyTiddler>tags[]] :filter[search:title<userInput>]+[sort[]]"
	systemTagsFilter="[tags[]] $(tagListFilter)$ +[is[system]] -[<storyTiddler>tags[]] :filter[search:title<userInput>]+[sort[]]"
	displayTagsPopup="[all[tiddlers]subfilter<systemTagsFilter>][all[tiddlers]subfilter<nonSystemTagsFilter>] +[limit[1]]"
>
<div class="tc-edit-add-tag">
	<div>
		<span class="tc-add-tag-name tc-small-gap-right">
			<$macrocall $name="keyboard-driven-input"
				tiddler=<<newTagNameTiddler>>
				storeTitle=<<storeTitle>>
				refreshTitle=<<refreshTitle>>
				selectionStateTitle=<<tagSelectionState>>
				inputAcceptActions="<$macrocall $name='add-tag-actions'
				actions=<<__actions__>>
				tagField=<<__tagField__>>/>"
				inputCancelActions=<<clear-tags-actions>>
				tag="input"
				placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}
				focus={{{ [{$:/config/AutoFocus}match[tags]then[true]] ~[[false]] }}}
				focusPopup=<<qualify "$:/state/popup/tags-auto-complete">>
				class="tc-edit-texteditor tc-popup-handle"
				tabindex=<<tabIndex>> 
				filterMinLength={{$:/config/Tags/MinLength}} 
				cancelPopups=<<cancelPopups>>
				configTiddlerFilter="[[$:/core/macros/tag-picker]]"
			/>
		</span>
		<$button
			popup=<<qualify "$:/state/popup/tags-auto-complete">>
			class="tc-btn-invisible tc-btn-dropdown"
			tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}}
			aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}
		>
			{{$:/core/images/down-arrow}}
		</$button>
		<$reveal state=<<storeTitle>> type="nomatch" text="">
			<$button
				class="tc-btn-invisible tc-small-gap tc-btn-dropdown"
				tooltip={{$:/language/EditTemplate/Tags/ClearInput/Hint}}
				aria-label={{$:/language/EditTemplate/Tags/ClearInput/Caption}}
				actions=<<delete-tag-state-tiddlers>>
			>
				{{$:/core/images/close-button}}
			</$button>
		</$reveal>
		<span class="tc-add-tag-button tc-small-gap-left">
			<$let tag={{{ [<newTagNameTiddler>get[text]] }}} currentTiddlerCSSEscaped={{{ [<saveTiddler>escapecss[]] }}}>
				<$button set=<<newTagNameTiddler>> setTo="">
					<$action-listops $tiddler=<<saveTiddler>> $field=<<__tagField__>> $subfilter="[<tag>trim[]]"/>
					$actions$
					<<delete-tag-state-tiddlers>>
					<$action-sendmessage $message="tm-focus-selector" $param=<<get-tagpicker-focus-selector>>/>
					{{$:/language/EditTemplate/Tags/Add/Button}}
				</$button>
			</$let>
		</span>
	</div>
	<$reveal
		class="tc-block-dropdown tc-block-tags-dropdown tc-block-dropdown-wrapper"
		default={{{ [subfilter<displayTagsPopup>then[]else[hide]] }}}
		state=<<qualify "$:/state/popup/tags-auto-complete">>
		tag={{{ [subfilter<displayTagsPopup>then[div]else[template]] }}}
		text=""
		type="nomatch"
	>
		<$let
			actions=<<__actions__>> 
			currentTiddler=<<tag>>
			tagField=<<__tagField__>>
			userInput={{{ [<storeTitle>get[text]] }}}
			tagsAutoCompleteFilter="[<userInput>minlength{$:/config/Tags/MinLength}limit[1]]"
			tagsAutoCompleteEmptyMessage="<div class='tc-search-results'>{{$:/language/Search/Search/TooShort}}</div>"
		>
			<$let tagsFilter=<<nonSystemTagsFilter>> suffix="-primaryList"><<tagsAutoComplete>></$let>
			<hr>
			<$let tagsFilter=<<systemTagsFilter>> suffix="-secondaryList"><<tagsAutoComplete>></$let>
		</$let>
	</$reveal>
</div>
</$let>
\end
\define pick-tag(tagField, tagListFilter)
<$messagecatcher $tm-focus-selector>
<$let
saveTiddler=<<currentTiddler>>
transclusion=<<__tagField__>>
tagListFilter=<<__tagListFilter__>>
>
<$macrocall $name="edit-tags-template" tagField=<<__tagField__>>/>
</$let>
</$messagecatcher>
\end


Include: <$macrocall $name="pick-tag" tagField="include" tagListFilter="-[<saveTiddler>get[exclude]enlist-input[]] -[<saveTiddler>get[include]enlist-input[]]"/>


Exclude: <$macrocall $name="pick-tag" tagField="exclude" tagListFilter="+[<saveTiddler>get[include]enlist-input[]tagging[]] -[<saveTiddler>get[exclude]enlist-input[]tagging[]] +[tags[]] -[<saveTiddler>get[include]enlist-input[]] "/>

Matches:
<table class="tc-max-width">
<thead><th>Tiddlers</th><th>Tags</th></thead>
<tbody>
<$list filter="[<storyTiddler>get[include]enlist-input[]tagging[]] :except[<storyTiddler>get[exclude]enlist-input[]tagging[]]-[is[system]]" variable="transclusion">
<tr>
<td><$link to=<<transclusion>> /></td><td><$list filter="[<transclusion>tags[]]"><<tag>></$list></td>
</tr>
</$list>
<tbody>

Here I use a </$messagecatcher> to prevent the focus to switch between the two tagpicker, but there is probably a better and cleaner way to do this.

Demo: Demos — Q&A and tools for tiddlywiki

You can easily add more filters in the tagListFilter attribute or in the list widget.

4 Likes

Wow, awesome, thank you :pray:

1 Like

I’d like to extend the Include / Exclude tag filter to permit selection of tiddlers between dates and then apply the tag filtering. Ideally with a programatic awareness of the earliest and latest available tiddlers in the wiki populating the pickers by default and otherwise remembering user choices.

I found this date time picker by @TW_Tones but could use help to integrate such functionality.

Can anyone help guide here? Thanks.