Suggester without restriction to the suggested values

I am looking for a suggester that does not restrict the user to the suggested values. Means: the user should be able to type in their own value like in Quick Switcher.

The APIs of Templater and QuickAdd offer a suggester but unfortunately with the mentioned restriction: the user cannot type in their own values.

Is there an “unrestricted” suggester somewhere in Obsidian or in its plugins?

You could fake it in Templater using a suggester and a prompt like so:

<%*
let choice = tp.system.suggester(['Yes','No','User Defined'],['Yes','No','User Defined']);
if (choice == 'User Defined')
{
   choice = tp.system.prompt('Other choice');
}
-%>

Basically this just adds an option to the suggester list that will trigger prompting for an open value when picked. It’s not as nice as having it all in a single integrated widget, but it will get the job done.

4 Likes

You could do it like this. Listen for the Enter key in the input field, and if no results are found perform your own function:

export class YourModal extends SuggestModal {
  constructor () {
    this.inputEl.addEventListener("keyup", ({key}) => {
      if (key === 'Enter' && this.inputEl.value && !this.getSuggestions(this.inputEl.value).length) {
        // No results found, so you can now do something with the user inputted value
        console.log(this.inputEl.value)
      }
    })
  }
}
2 Likes

@AlanG That’s awesome!

It seems like this would allow for the creation of a template on the fly. For example, the suggester appears asking for what category the new note is in, but this note doesn’t fit the available suggested categories, so a new category is typed in. This is used to create a folder of the correct name in the correct place. It also automatically creates a new Templater Folder Template for that folder based on a standard template. Of course, in this new template and the newly created note, the value for the category field would be set to the entered value.

I realize that, in this example, creating this plugin or Templater script would require a lot of effort only to create something that doesn’t take very long to do manually and won’t be performed very often. However in certain use cases, it could be a real time saver. I am also really interested in whether doing something like this would even be possible via Templater or only via plugin. I have never even experimented with creating a plugin, but thanks to your link to the documentation, I could see myself giving it a try and some potentially very useful possibilities.

Thanks for the inspiration! Very cool!

This almost always turns out to be the case when automating a task :joy:

But it’s also a perfect opportunity to learn how to create a simple plugin, so I say go for it! I wrote one plugin to perform a very specific task, and now I’m at 5 and counting… You can really supercharge your Obsidian experience.

2 Likes

Thanks! I might give it a try. Or at least start wading in the waters with a purpose. Usually that’s the best way to learn anyways.

Part of me thought that it might be possible using strictly using Templater scripts. I had been reading about an interesting setup here, https://zachyoung.dev/blog/folder-templates-with-quick-switcher, that I was going to try out. Part of that setup is probably what inspired my thought in the first place.

Anyways, I appreciated the graphic. I have probably spent more time learning about scripting for 3d animation than the actual time I have saved via my own scripts. In the end, sometimes it’s not just about the time saved, but the scope of the things you would even consider setting sights on, and also the ability to just tweak someone else’s solution. And for that reason, I think I will try to build a little plugin.

1 Like

Thank you very much for the suggestion!

I was hoping not to have to write an own plugin for this feature. But apparently, I have to. :sweat_smile:

It would take me a while, as it would be my first one. Currently, I am helping myself out by using the Shell commands plugin calling dmenu and channeling the output back to Obsidian. But that combination is a kind of broken architecture.

Just a quick check:
In the doc page referenced by you I see the event handler onNoSuggestion . Maybe that one could be utilized for my use case? In a more direct way than registering a lower level keyup event listener?

Come on, it’ll be fun :sweat_smile:

I didn’t know Typescript before I wrote my first plugin, but I watched this Udemy course and found he was quite a good teacher (should be about $10, don’t get it if not on sale).

That gets called every keystroke if there is no matching suggestion. So you will be firing off a lot more events than you want as you type the final input string. Better to wait for the Enter key, or even add your own custom button to the modal if you like.

1 Like

Haha, that you’re saying after posting the diagram “I should write a program automating it!”?! :wink:

I think I’ll start small at first and just make a pull request to an existing plugin like Templater.

So, just to double check that I got everything right:

I would create a new class based on Templater’s SuggesterModal:

export class LiberalSuggesterModal<T> extends SuggesterModal<T> {
    constructor(
        private text_items: string[] | ((item: T) => string),
        private items: T[],
        placeholder: string,
        limit?: number,
        stringToItem?: (s: string) => T
    ) {
        super(text_items, items, placeholder, limit);
        this.inputEl.addEventListener("keyup", ({key}) => {
            let currentInput = this.inputEl.value;
            if (key === 'Enter' && currentInput && !this.getSuggestions(currentInput).length) {
                // No matching suggestion found, so just return the inputted value
                if (this.stringToItem instanceof Function) {
                    this.resolve(this.stringToItem(currentInput));
                } else {
                    this.resolve(currentInput);
                }
      }
    }
}

Plus the Templater framework stuff to expose it in Templater API. Right?

Not sure I can help you there sorry. I was using Obsidian’s SuggestModal. I have no idea how Templater’s SuggesterModal class works.

A plugin doesn’t have to be complicated. Here’s one of mine which is 48 lines in total:

https://github.com/alangrainger/obsidian-folder-notes/blob/main/main.ts

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.