Provide an implementation of suggest input for plugins to use

Use case or problem

Many plugins require an input that suggests possible values while the iser types. Usually for paths to folders, templates etc. Currently there is no API method on the Setting class for doing this.

Proposed solution

Provide a methos like the existing ones that renders a suggestion input

Current workaround (optional)

Most plugins are copy pasting a very good implementation from periodic notes. Maybe that code could just be adopted to prevent duplications

Related feature requests (optional)

3 Likes

I second this. Obsidian internally already has a custom implementation (used for example in the Templates settings), but it is not exposed. It would be enough to expose that.

1 Like

Exactly. This will save a lot of code for a lot of plugins that are currently bundling the same duplicated implementation

1 Like

+1 for this!

As of Obsidian 1.4.10, the API includes AbstractInputSuggest, which is the base class that we use internally for adding suggestions to Settings inputs.

We recommend using this instead of the implementation ripped from Periodic Notes (which uses the popperjs lib, instead of the positioning logic that Obsidian uses internally).

1 Like

I was about answer this yesterday, but I am too late. To redeem myself,here is an usage example:

import { AbstractInputSuggest, App } from 'obsidian'

export class MultiSuggest extends AbstractInputSuggest<string> {
    content: Set<string>;

    constructor(private inputEl: HTMLInputElement, content: Set<string>, private onSelectCb: (value: string) => void, app: App) {
        super(app, inputEl);
        this.content = content;
    }

    getSuggestions(inputStr: string): string[] {
        const lowerCaseInputStr = inputStr.toLocaleLowerCase();
        return [...this.content].filter((content) =>
            content.toLocaleLowerCase().contains(lowerCaseInputStr)
        );
    }

    renderSuggestion(content: string, el: HTMLElement): void {
        el.setText(content);
    }

    selectSuggestion(content: string, evt: MouseEvent | KeyboardEvent): void {
        this.onSelectCb(content);
        this.inputEl.value = "";
        this.inputEl.blur()
        this.close();
    }
}
5 Likes

Thanks for that! Very useful!

1 Like

Based on that, I’ve ended up making a class that adds suggestions to existing fields, allowing for comma separated values: https://github.com/mo-seph/obsidian-note-from-template/blob/master/src/UISupport.ts
(the AddTextSuggest class)

I still feel like I’m re-inventing the wheel a bit, as that code clearly exists in a nicer and more powerful form in the Frontmatter editor, but this does work