Skip to content

One-page Inputs

Normally QuickAdd asks for inputs one prompt at a time. Turn on one-page inputs and it gathers everything a choice needs into a single form you fill once, then runs. This is nicer when a choice asks for several things at once - a title, a date, and a status, say - and you would rather see them all together than click through them one by one.

For a task-oriented overview of prompts in general, see Controlling Prompts.

Go to Settings → QuickAdd and toggle One-page input for choices.

It works with Template, Capture, and Macro choices.

For a Macro, this-level NestedChoice and Choice members that resolve to Template or Capture appear on the macro’s form. A nested Macro is a separate page. Conditional branches are not collected up front. A UserScript or AI command defers later Template and Capture members on this page (script-declared quickadd.inputs still hoist; see User scripts). Set a member’s One-page input override to Never to keep it off this page.

Template and Capture choice builders have a One-page input override dropdown that overrides the global setting for that one choice:

  • Follow global setting - use whatever the global toggle is set to (default).
  • Always - force the one-page form for this choice even when it is off globally.
  • Never - use step-by-step prompts for this choice even when it is on globally.

QuickAdd scans the choice for placeholders and turns each one into a field:

  • Placeholders in file names, templates, and capture content: {{VALUE}}, {{VALUE:name}}, {{VDATE:name, YYYY-MM-DD}}, {{FIELD:name|...}}, and {{FILE:folder|...}}.
  • Nested {{TEMPLATE:path}} includes are scanned recursively, so their prompts show up too.
  • {{VALUE|type:multiline}} and {{VALUE:name|type:multiline}} become textareas.
  • {{VALUE:name|type:number|min:1|max:10}} becomes a bounded numeric input, and {{VALUE:name|type:slider|min:0|max:100|step:5}} becomes a slider plus numeric input.
  • The capture target file, when you are capturing to a folder or a tag.
  • Inputs declared by a user script inside a macro, if the script provides them.
  • Date fields accept natural language, like today or next friday.
  • Short aliases work and are configurable in settings: t (today), tm (tomorrow), yd (yesterday).
  • The field shows a formatted preview and stores a normalized @date:ISO value internally.
  • {{FIELD:...}} inputs suggest values from your vault (using Dataview when it is available, with a manual fallback otherwise).
  • {{FIELD:...|multi}} is not shown inline in the form, because vault field values can contain commas. QuickAdd collects the rest of the form first, then opens the regular multi-select for that field.
  • {{FILE:folder}} appears as a searchable picker in the form. Search matches the friendly note title, file name, and full vault path.
  • The selected file is shown above the search field and can be removed or replaced. Single-select fields keep the same first-file default as the previous dropdown.
  • {{FILE:folder|multi}} stays in the same form. Pick several files without opening a second modal, and remove the last pick by pressing Backspace in an empty search field.
  • Multi-select results keep the folder’s file order. File names and friendly labels containing commas are handled as complete values.

Inline FILE pickers introduced in QuickAdd 2.21.0.

A field marked with the |optional flag shows an (optional) badge and may be left blank. Leaving it blank stores an intentional empty value, so the step-by-step prompt will not ask for it again later.

Good to know:

  • A field counts as optional only when every occurrence of that variable across the scanned formats is flagged.
  • Optional dropdowns get a Skip (leave empty) entry; the first real option stays preselected.
  • An optional date field left blank resolves to empty. If what you typed cannot be read as a date, the field is handed to the regular step-by-step date prompt after you submit, instead of silently becoming empty.

The form only opens when it has something to ask:

  • If every required input already has a value (for example, prefilled by an earlier macro step), the form does not open.
  • An empty string counts as an intentional value and will not prompt again. This applies to {{VDATE}} too: a script-set "" renders empty instead of re-prompting.
  • For Capture choices, a non-empty editor selection prefills {{VALUE}} during preflight when selection-as-value is enabled.
  • Cancelling the form (Cancel button or Esc) cancels the whole run. QuickAdd does not fall back to the step-by-step prompts.
  • If the form fails to open for some other reason (for example, a requirement could not be collected), QuickAdd logs a warning and runs the choice with the standard step-by-step prompts instead.

QuickAdd uses reserved variable ids prefixed with __qa. for internal wiring during preflight and runtime. Capture-target flags are scoped by choice id (__qa.captureTargetFilePath.<choiceId>) so two captures in one macro get two distinct fields. The unscoped value-__qa.captureTargetFilePath=… flag still satisfies a collection that has exactly one capture-target field (a lone Capture, or a macro with one folder/tag capture). It does not satisfy two capture-target fields at once.

These internal keys will not collide with your own variables. Avoid using the __qa. prefix in your scripts.


To have a user script’s inputs appear in the one-page form during preflight, export a static quickadd.inputs spec alongside your default export. This is optional and non-executing.

Example (function default export):

export default async function entry(params, settings) {
// ... your script ...
}
export const quickadd = {
inputs: [
{ id: "project", label: "Project", type: "text", defaultValue: "Inbox" },
{ id: "due", label: "Due date", type: "date", dateFormat: "YYYY-MM-DD" },
{ id: "confidence", label: "Confidence", type: "slider", defaultValue: "50", sliderConfig: { min: 0, max: 100, step: 5 } },
{ id: "status", label: "Status", type: "dropdown", options: ["Todo","Doing","Done"] }
]
};

Example (object default export):

export default {
async entry(params, settings) {
// ... your script ...
}
};
export const quickadd = {
inputs: [ { id: "topic", type: "text" } ]
};

Supported input fields:

  • id (string, required)
  • label (string)
  • type (“text” | “number” | “textarea” | “dropdown” | “date” | “field-suggest” | “suggester” | “slider”)
  • placeholder (string)
  • defaultValue (string)
  • options (string[] for dropdown and suggester)
  • numericConfig (object for number: { min?: number, max?: number, step?: number })
  • sliderConfig (object for slider: { min: number, max: number, step?: number }; min and max are required, step defaults to 1)
  • dateFormat (string for date)
  • description (string)
  • optional (boolean - field may be left empty; shows an “(optional)” badge)
  • suggesterConfig (object for suggester: { allowCustomInput?: boolean, caseSensitive?: boolean, multiSelect?: boolean })

Field type details:

  • text: single-line text input
  • number: numeric input, optionally bounded by numericConfig
  • textarea: multi-line text input
  • dropdown: fixed dropdown menu (no search, must select from list)
  • date: date input with natural language support
  • field-suggest: vault field suggestions (uses {{FIELD:...}} syntax)
  • slider: bounded numeric input with a slider and editable number field. Requires sliderConfig.min and sliderConfig.max; invalid configs fall back to number.
  • suggester: searchable autocomplete with custom options (allows typing custom values)
    • Supports multi-select mode via suggesterConfig.multiSelect: true
    • Multi-select: select multiple items, separated by commas. Suggestions stay open after each selection.

From within a script, you can open one form that collects several inputs at once using the QuickAdd API.

export default async function entry({ quickAddApi }) {
const values = await quickAddApi.requestInputs([
{ id: "project", label: "Project", type: "text", defaultValue: "Inbox" },
{ id: "due", label: "Due", type: "date", dateFormat: "YYYY-MM-DD" },
{ id: "confidence", label: "Confidence", type: "slider", defaultValue: "50", sliderConfig: { min: 0, max: 100, step: 5 } },
{ id: "status", label: "Status", type: "dropdown", options: ["Todo","Doing","Done"] },
{
id: "tags",
label: "Tags",
type: "suggester",
options: ["work", "personal", "urgent"],
placeholder: "Type to search tags..."
},
]);
// Access collected values
const { project, due, status, tags } = values;
}

Example with dynamic options (from Dataview):

export default async function entry({ quickAddApi, app }) {
// Get dynamic options from Dataview
const dv = app.plugins.plugins.dataview?.api;
const projectNames = dv?.pages()
.where(p => p.type === "project")
.map(p => p.file.name)
.array() ?? ["Inbox"];
const values = await quickAddApi.requestInputs([
{
id: "project",
label: "Select Project",
type: "suggester",
options: projectNames,
placeholder: "Start typing project name..."
},
]);
const { project } = values;
}

Example with multi-select:

export default async function entry({ quickAddApi }) {
const values = await quickAddApi.requestInputs([
{
id: "tags",
label: "Select Tags",
type: "suggester",
options: ["#work", "#personal", "#project", "#urgent", "#review"],
suggesterConfig: {
multiSelect: true,
caseSensitive: false
},
placeholder: "Type or select multiple tags..."
},
]);
// Result: values.tags = "#work, #project, #urgent"
const { tags } = values;
// Split into array if needed
const tagArray = tags.split(', ').filter(Boolean);
}

Behavior:

  • Values already present in variables are used and not re-asked.
  • Only missing inputs are prompted in the form.
  • Returned values are also stored into variables for later steps in the macro.

  • Macro support is best-effort: user scripts can declare inputs via quickadd.inputs.
  • Preflight may import user script modules to statically read quickadd.inputs. This can execute module top-level code.
  • Inline scripts aren’t scanned for input declarations yet.
  • You can still prompt ad-hoc (for example with inputPrompt or a suggester); those values are treated as prefilled and skip future one-page prompts.
  • Closing the requestInputs form without submitting rejects with MacroAbortError("Input cancelled by user"), which stops the macro unless you catch it.