Meta-Bind - INPUT[ListSuggester - from a List in a note

What I’m trying to do

I have several lists in my Obsidian that I use for my InLine Fields (with classes of MetaData menu).

I am looking a way to configure Meta-Bind - INPUT[ListSuggester - to recover input fields from a note.

For example:

Having a note named: Note_List.md
with inside the following items:

  • Item_1
  • Item_2
  • Item_3
  • Item_4
  • Item_5

In my main note I have this Meta-bind code:

Blockquote

meta-bind
INPUT[multiSelect(option(Item_1, Item_1),option(Item_2, Item_2),option(Item_3, Item_3),option(Item_4, Item_4)):Status_Input]

I would like that multiSelect recovers the Items from the note Note_List.md so that, if I add other items in this note, multiSelect is already updated with the new items.

Things I have tried

I have tried to google about this, but I have note found a solution.
It looks like that meta-bind is unable to do this.
Some work-around say that you can create a note for each Item but this solution is complicated for me.

Has someone a solution for this ?

If this is simply for not having to recreate the list every time, you can just create a template for you to insert.

Just the core templates plugin would be enough, no need for templater

If you want for the main note to dynamically update the meta bind input, you can’t use a template, but you could possibly use dataviewjs to build the meta bind code block automatically.

I might look into doing a sample query later today, but I’m kind of busy right now.

Ok, I try to take a look to templates.
For now I cant figure how to do it.

Ok Holroy.
Thanks if you can code a JS.
Maybe it Could be the last solution.
Please, Let me know when you can do it.
:slightly_smiling_face:

Would 10 minutes ago be OK? :smiley: :stuck_out_tongue:

If you’re only doing this in one or a few files, you could use this as is. If not, I would consider moving it into a file of its own to be called from dv.view().

```dataviewjs
const list = dv.page("t98039 note list.md").file.lists.text
let output = `
~~~meta-bind
INPUT[multiSelect(${
  list.map(item => `option(${ item }, ${ item })`).join(",")
}):Status_Input]
~~~
`
dv.paragraph(output)
```

You would of course need to replace the file name within the call to dv.page() with your note list. And in this version I don’t do any error checking, so if some the items break the multiSelect, that’s on you!

Other than that, it seems to work just dandy. Note that if you remove any items from the list which was previously selected, they’ll still remain in the Status_Input property.

1 Like

ok, holroy,
I will study, run and test it in the next hours.

I will tell you how it works !

:sunglasses:

I couldn’t resist trying it right away.

It seems to work, but I get a blank line for now…

The code I have is this below:

dataviewjs
const list = dv.page("tag_status_input_color_list.md").file.lists.text
let output = `
~~~meta-bind
INPUT[multiSelect(${
  list.map(item => `option(${ item }, ${ item })`).join(",")
}):Status_Input]
~~~
`
dv.paragraph(output)

and the output is this below:

Cattura

And couldn’t click on the items.

What’s the content of your tag_status_input_color_list.md file?

Bonus tip: How to present code properly in a forum post

If you want to showcase either markdown, or code blocks, or dataview queries properly in a forum post, be sure to add one line before and one life after what you want to present with four backticks, ````. This will ensure that any other backticks (like in code blocks or queries) is properly shown.

They are tags:

#:red_square:_not_started
#:orange_square:_ps
#:yellow_square:_atomic
#:green_square:_finished
#:black_large_square:_archived

I tryed to change them with this list below:

1
2
3
4
5

but I have the same result …

I got it !

your code searches for a list in the file.
Actually I have in the file or lines without a list.
Is there a way to fine rows without lists ?

Those are not lists, like in the original post. So try doing:

- 🟥_not_started
- 🟧_ps
- 🟨_atomic
- 🟩_finished
- ⬛_archived

Then you’ll see something else happening! :smiley:

yes ! With lists it works !!

Unfortunately I have several notes with tags inside them.
I would like to read the rows and not lists.

Is there a way ?

Sorry for my starting mistake explaining

Then you would need to actually reading the file contents, and that’s a different beast all together. I’m not able to do that tonight, I think.

There are examples though within this forum on how to read files, and split on newlines, which would then produce the list needed to build the output based on those lines.

I try to look at.
Let me know when you are in great shape to create a new code ! :wink:

Hmm… I didn’t manage to get away…

```dataviewjs

const theFile = app.vault.getAbstractFileByPath(dv.page("t98039 only tags").file.path)
const content = await app.vault.read(theFile)
let output = `
~~~meta-bind
INPUT[multiSelect(${
  content.split("\n").map(item => `option(${ item }, ${ item })`).join(",")
}):Status_Input]
~~~
`
dv.paragraph(output)
```

I kind of don’t like to present code like this without any safety checks, so be forewarned that this might break without letting you know why. You do need to update the dv.page() to refer to a file of yours as before.

That file needs to hold nothing but the actual options, and they do need to be acceptable by meta-bind as is. As said, no safety-checks is done currently. But it do work in my very simple test…

With this code I have some errors with meta-bind.

I tryed to give your starting code about lists to Chat-Gpt and after correcting 3 times the code it gave me a code that works perfectly. :scream:

Now this code can read a file and stop reading when it finds the 2 below rows:

  • blank row
  • three dashes

The code the work perfectly is:

let filePath = "Hidden/My Lists/tag_status_input_color_list.md";
app.vault.read(app.vault.getAbstractFileByPath(filePath)).then(content => {
    const lines = content
        .split("\n")
        .map(line => line.trim());

    // Filter the rows until you find a blank row followed by '---'
    let filteredLines = [];
    for (let i = 0; i < lines.length; i++) {
        if (lines[i] === "" && lines[i + 1] === "---") break; // Interrompe la lettura
        filteredLines.push(lines[i]);
    }

    if (filteredLines.length === 0) {
        dv.span("⚠️ No valid entry found before a blank line followed by '---'");
        return;
    }

    let output = `\n\`\`\`meta-bind\nINPUT[multiSelect(${
      filteredLines.map(item => `option(${ item }, ${ item })`).join(",")
    }):Status_Input]\n\`\`\`\n`;

    dv.span(output);
});

And the beautifulness of this code is that I can change the type of meta-bind input and it works perfectly.
You can use this code with all types of input of meta-bind !!!

Thankssss holroy !!!