[New plugin] Modal form - integrate forms into QuickAdd, templater, etc

Ciao Danilo,

I’m here again to ask for your help. I’ve been using your fantastic Modal Form Plugin for a few months now, and it has solved many problems for me. I can’t thank you enough for that.

Now I have a question:

I would like to use tables to enter multiple data points. Let me explain: I open my form and, under the “item code” field, which is a dataview type field, I show all the item codes contained within a directory that includes all the notes for the item codes. Each note reports, besides the item code, also the weight and the selling price.

So, from the form, by choosing an item code, I would like the other two values (weight and selling price) to be automatically assigned to the respective properties of the new note we are about to create.

Do you think it is possible to implement this functionality?

Thank you very much in advance for your help!

Were you ever able @Cyberpunk to resolve this? I have the exact same setup, where I currently use this approach in a Templater template that I’m trying to convert to a Modal Form.

I now get the following error:

CleanShot 2024-07-24 at 14.01.34@2x

Hi @danielo515, first of all, thank you for this very promising plugin.

Can you please provide an example of how to prefill a Select field? Previously you posted the following code snippet

<%* 
const modalForm = app.plugins.plugins.modalforms.api;
const result = await modalForm.openForm('simple', {values:{
	list:['1984','Hello'],
	name: 'Fedever',
	number: 55
	}});
%>

In my tests, I’m unable to populate the values for the list. I also see no difference in having a Static list with or without any predefined options in the form definition.

I think all is needed to do what you want is to have the dataview source have access to the current form data, that way you can decide what to query and what to display. Will that work?

The values provided to modal-form for a list are not for the options to choose from, are a default set of already chosen values for multi-select lists.
The only way to populate the list options is either providing them as a fixed list when creating the form, or using dataview as source and build the list inside the dataview code snippet.
Does that make sense? If not, please give me the details of what you are trying to accomplish and I will try to give you an example of how that can be done

Release notes for 1.51.0

Hidden fields

This release introduces the concept of hidden fields.
The intended usage of this feature is to provide values to the form that are not visible to the user.
This has some applications such as:

  • providing variables to the form-runtime that your dataview functions can use
  • having certain fields deactivated using the conditional without any user interaction
  • having certain values be part of the generated result, and used in the templates

I bet the community will be able to figure out some other interesting use-cases.
The reason I like this approach to much is a) because it is a web standard (this is common practice to communicate between backend and frontend in forms) and b) it plays nicely with all the existing form mechanisms without having to complicate the logic at all: formatting the output, reading the value from dataview functions, conditional rendering other fields, etc.

Hope you like it and find it useful.

2 Likes

Release notes for 1.52.0

Markdown block

This release introduces a new input, the “markdown block”.
Just like the existing “document block” this is not a real input, but more a building block for richer forms.
The definition is expected to contain a function body returning a markdown string. This markdown string will then be rendered
into the form and the user filling it will be able to see it.

To illustrate with an example, imagine a simple form with a single text input, we can define a markdown block with this content:

return `# hello
- line 1
- ${form.text}
- ![[image.png]]`

Have you noticed the image syntax? Yes, images are supported too.
This is how it looks once rendered:

Updates to the existing document block

Both Markdown block and document block now have access to the dataview API (along with the form data itself).
This allows to build much complex and data packed information panels.
To access the dataview API, you do normally just like in any other place using a special variable named dv.
For example, and continuing with the markdown example, we could render a list of all the people (in markdown) using dataview
like this:

return dv.markdownList(
    dv.pages('#person').map(x => x.file.name)
)

That will render something like this:
Screenshot 2024-09-29 at 20.32.35

1 Like

Release notes for 1.53.0

Introducing Image Input

This release introduces a brand new input type: the image input! This new component allows you to upload images directly through your forms, automatically saving them to your vault.
I’m particularly excited about this new feature because I already have a lot of usecases for it on my daily life (I like to keep a record of the restaurants I visit and the meals I eat there).
The possibilities it opens are big and I’m really excited about seeing what new and more visual experiences you can create using it.
I also think that having a specialized way of adding images to your notes/templates is better than the obsidian way in a lot of situations.

What’s New

The image input is a powerful new addition to our form inputs family that lets you:

  • Save images directly to your vault
  • Preview the image
  • Atomically define where each image will be saved for each input
  • Use templates for file naming with date/time placeholders

Here’s how it looks in action:

There is also a new helper in the FormResult object that simplifies the creation of markdown links to the image.
For example, if you have a field called image in your form result, you can use it like this in your templates:

<% result.image.link %>

Using the Image Input

Adding an image input to your form is very straightforward using the FormBuilder. Here’s an example screenshot:

The configuration has two main settings:

  • filenameTemplate: Define how your files will be named. You can use placeholders like {{date}}, {{time}}, or {{datetime}}.
  • saveLocation: Specify where in your vault the image will be saved. Don’t worry if the folder doesn’t exist - it will be created automatically!

Drawbacks

As with every first version of every new feature, there is an important drawback:
the image input is eager to save the image.
This means that the image will be saved as soon as you select it, even if the form is not submitted, or if you pick a different image.
This is a tradeoff that simplified the implementation and makes some scenarios simpler , like using the image in a markdown block or in other dynamic inputs.

It is also worth mentioning that the value you get in the form result is not a TFile directly but a wrapped TFile object.
This is because a lot of places assume it is safe to just serialize the form results to JSON, which is not the case for the TFile object.
The wrapped TFile object has direct access to the most essential properties of the file, like path, name, basename, and extension.
The wrapped TFile is also available through the TFile property in the wrapping class FileProxy.

Here is an example of how you can use the wrapped TFile object:

const result = await MF.openForm("my-form");
// assuming your image input is called "image"
const file = result.image.value.TFile;
- ctime: <% file.stat.ctime %>
- mtime: <% file.stat.mtime %>
- size: <% file.stat.size %>

Check other release notes in the blog:
https://danielorodriguez.com/obsidian-modal-form/blog/

2 Likes

Release notes for 1.56.0

Templates now support Templater syntax!

Modal Form 1.56.0 enhances its templates feature with Templater support!
I’m particularly excited about this integration because, with a little addition we are greatly improving not only the usability of this plugin, but also Templater.
Now binding a particular form to a complex template is easier than ever, knowing the fields available in the template also becomes a lot easier and I think the overall experience is greatly improved.

What’s New

The Templater integration adds the following capabilities to form templates:

  • Use Templater syntax (<% %>) inside form templates
  • Process dates, files, and system information through Templater
  • Automatic processing of Templater syntax after form variables are replaced

Here’s a little example combining both syntaxes:

---
created: <% tp.date.now() %>
---

Dear {{name}},

Meeting scheduled for <% tp.date.now("MMMM Do, YYYY") %>
Location: {{location}}

Best regards,
{{signature}}

How it Works

The template processing now happens in two stages:

  1. First, Modal Form replaces all form variables (the {{variable}} syntax)
  2. Then, if Templater is available, it processes any Templater syntax in the resulting text

Retry Functionality

Getting templater templates right at the first try can be hard, that’s why we added a retry option when templater processing part fails.
If something goes wrong during templater processing , Modal Form now provides a retry modal where you can try to fix the template and try again.:

This makes it easier to fix any issues without losing your form data and gives you an insight on how te template is processed.

Check out the templates documentation for more details and examples of how to use this new feature.

1 Like

Hi, ty for this addon. i am struggling to understand how to leverage the output of the modal in a quickadd capture.

  • i just want to capture some data in the modal pop up
  • format that data into a templater string
  • return that string to quick add capture so i can add it to the end of a note

is there a documentation link that shows how to do this? at the end i was going through doing something like this in my quick add capture window:

js quickadd
  const modalForm = app.plugins.plugins.modalforms.api;
  const result = await modalForm.openForm("watching_a_show");
  resstring = "- watching [[" + result.get("show")+ "]]";
  return resstring;

which works and is doable but i wanted to attempt to leverage all of the tools in their proper format.

i think my real question is: is there a way to access the resolved templater string without the requirement for creating a new file?

First of all many thanks for this great template. My question is whether it is possible to use the value from one field in the form as a criterie for a conditional field in the same form. Sample use case is that

  1. user selects a country from a select field which uses notes (countries) in a folder
  2. then I want select field listing all states from the selected country. The states are tags in the country note

any idea how to solve this? I tried to used dataviewjs to find the tags (that works in a note) but the problem is to get / use the value from the country field

many thanks in advance!!!