Tag-picker is not working independently

When I try to use <<tag-picker tagField:foo>> I get an edit box and ‘add’ button as expected, but when I choose tags, they are not added to the edit box. If I edit the tiddler I see they are added to the field. Also, if I create new tags they are not added to the picker list
How can I make it work as expected? In my case, I want the chosen tags to be added to the field and any new one to become part of what the picker shows, and it can be via adding it to the list of tags in the wiki

And while I’m asking, how can I list a tiddler’s tags in a list of tiddlers (e.g. next to each tiddler’s title)

That’s how the tag picker is implemented in the core. You can use this one as a starting point.

https://tiddlywiki.com/#%24%3A%2Fcore%2Fui%2FEditTemplate%2Ftags

Yeah, too complex for me to parse without assistance

hmmm, Had a look at the code. … The core tag-picker macro has a bug. So there will not be a fast solution. I’ll create an issue at GitHub.

1 Like

See: [BUG] calling tag-picker macro with a tagFields=foo shows the tags field instead of foo · Issue #7461 · Jermolene/TiddlyWiki5 · GitHub

The contents of the tag input dropdown list should be configurable, and for backward-compatibility should still default to showing a list of tag values, regardless of the target tagField parameter value. This can be achieved with just a few small changes to the existing $:/core/macros/tag-picker definition:

In the main tag-picker macro definition, change

  • \define tag-picker(actions,tagField:"tags")
    to
    \define tag-picker(actions,tagField:"tags",tagFilter:"[tags[]]")
  • <$vars saveTiddler=<<currentTiddler>> palette={{$:/palette}}>
    to
    <$vars saveTiddler=<<currentTiddler>> palette={{$:/palette}} tagFilter=<<__tagFilter__>>>

Then, in the tag-picker-inner macro definition, change

  • nonSystemTagsFilter="[tags[]!is[system]search:title<userInput>sort[]]"
    to
    nonSystemTagsFilter="[subfilter<tagFilter>!is[system]search:title<userInput>sort[]]"
  • systemTagsFilter="[tags[]is[system]search:title<userInput>sort[]]"
    to
    systemTagsFilter="[subfilter<tagFilter>is[system]search:title<userInput>sort[]]"

Also, change field first-search-filter from

  • [tags[]!is[system]search:title<userInput>sort[]]
    to
    [subfilter<tagFilter>!is[system]search:title<userInput>sort[]]

and change field second-search-filter from

  • [tags[]is[system]search:title<userInput>sort[]]
    to
    [subfilter<tagFilter>is[system]search:title<userInput>sort[]]

With these changes in place, you can then write:

<<tag-picker tagField:foo tagFilter:"[get[foo]enlist-input[]]">>

to populate the dropdown list with all values currently contained within foo fields

Thank you! When I change this macro, what happens when I upgrade TW5? Will the changes be gone, do I need to remember I overwrote the shadow tiddler and sometime revert?

If I want to have these changes as part of a plugin, how do I go about doing that? That is, do I change the shadow macro and then export as part of the plugin package, or is there another mechanism where a tiddler in a plugin package overwrites a a core shadow tiddler? Something where if I disable the plugin, the changes no longer apply.

When you modify a shadow tiddler, it becomes a “real” tiddler, and overrides the shadow definition. When you upgrade the TWCore, the “real” tiddler will continue to override the shadow, even if the upgraded TWCore contains a newer version of the shadow tiddler.

Note that the changes I have outlined are 100% backward-compatible with the current TWCore shadow macro definition, so unless the TWCore adds new functionality to the macro, you can safely rely upon your modified macro to continue to perform properly even after upgrading the TWCore.

Regardless, if you want the TWCore shadow tiddler definition to be re-applied, you can either:
A) delete the modified tiddler,
or
B) rename the modified tiddler AND remove the $:/tags/Macro tag from it.

@EricShulman this or perhaps a generic tiddler-picker for list fields is a missing feature in the core and worthy of a submission.

  • Although I have versions of the Link view/editor toolbar buttons that do this
  • I have cloned the current $:/core/macros/tag-picker, made the changes you suggested and removed the unchanged macros, so a separate tiddler can be maintained. leaving the core tiddler intact.
    • As long as this new one is defined after that in the tag $:/tags/Macro it will win over the core.

Thanks very much for doing this work @EricShulman I was about to do it myself.

  • I also created a new one with the name tiddler-picker with different parameter names and order \define tiddler-picker(fieldname:"tags",filter:"[tags[]]",actions)
    • But the placeholder and tooltips are incorrect
  • Next the ability to trigger equivalent tag pills may be nice but I think GenTags does this already.

My copy for reference and review;
tiddler-picker_macros.json (7.6 KB)

Thanks. I tried this and while the list now anchors correctly and it populates the right field, the tags don’t appear in the edit box.

The tag-picker input field is only intended for entering a new value to add to the tagField, one value at a time, and does not display the current list of all assigned values. To display the current values stored in the foo field (similar to how the tag-picker works when editing a tiddler), you can write something like this:

<$list filter="[enlist{!!foo}]">
   <$macrocall $name="tag-pill" tag=<<currentTiddler>>/>
</$list>
<<tag-picker tagField:foo tagFilter:"[get[foo]enlist-input[]]">>

Thanks, can you help with one final mystery I have? I need to use the tags in the field (foo above) plus another one as parameter to a widget attribute.
I tried $tags={{{ anothertag [enlist{!!foo}}] +[join[ ]] }}} but while the field will contain tag names with spaces as [[tag with space]], when i look a the attribute passed to the widget, the square brackets are gone. I also tried $tags={{{ anothertag [get[foo]] +[join[ ]] }}} but this seems to duplicate the field value

I needs something so that in the widget I can take the attribute value and put it as-is to the tags field of a tiddler I’m creating.

1 Like

Since the value of the foo field is already a properly formatted list (i.e., with doubled square brackets around values that contain spaces), you just need to join “anothertag” onto it (separated by a space, of course).

Thus:

$tags={{{ anothertag [{!!foo}] +[join[ ]] }}}

Note also that in your posted syntax, ...[enlist{!!foo}}]..., you had an extra closing }.

1 Like

I did have a closer look at the code. There are some more problems to be solved.

Erics solution points in the right direction, but it seems there are some more edge-cases. Eg:

  • Several instances of the tag-picker macro in the same tiddler will not work.
  • The name of the temporary input tiddler is hardcoded so every instance uses the same one
  • and probably more.

So I think the whole thing needs a bit more attention as it seems

image

1 Like

Perhaps an additional parameter allowing the state tiddler or a suffix to the state tiddler or a preset variable?

  • There are other places such as tag pills where the current state mechanism needs to improved.
  • A code pattern that ensures this is applied consistently would be nice.

For the <<tag-picker>> macro, this could be addressed in tag-picker-inner() by appending the tagField parameter value to the state tiddler title, like this:

First, construct the state tiddler title and store it in a variable (e.g., popid):

<$vars popid={{{ [[$:/state/popup/tags-auto-complete/]] [<__tagField__>] [<qualify>] +[join[]] }}}>

Then replace the 3 hard-coded instances of <<qualify "$:/state/popup/tags-auto-complete">> with references to <<popid>>

@EricShulman if I used the same tag picker macro on the same current tiddler inside the same tiddler (not likely but possible) will we still have a problem?

  • What if popid is set outside the tag picker macro when needed?
<$list filter=" filter " counter=popid>
   <<tag-picker>>
</$list>

Since the calculated popid value includes a [<qualify>] value, you can force different qualify values by wrapping the <<tag-picker>> calls within `<$let transclusion=“something”>, like this:

<$let transclusion="1"><<tag-picker tagField:"foo">></$let>
<$let transclusion="2"><<tag-picker tagField:"foo">></$let>

I forgot that recently discussed trick. Its not easy to remember.

Perhaps we could add it to https://tiddlywiki.com/#transclusion%20Variable and for that matter https://tiddlywiki.com/#transclusion%20Variable and https://tiddlywiki.com/#QualifyWidget

Another example may be a hybrid approach

<$list filter=" filter " counter=transclusion>
   <<tag-picker>>
</$list>
  • Above not complete code

This may suggest a way to resolve this for tagPills and other examples where a simple qualify is insufficient.