Skip to content

Commit 4e99c18

Browse files
committed
Forms 1.0.16: NoteChooser enhancements, SearchableChooser optimization, and dynamic receivingTemplateTitle support
- Added NoteChooser output format options: * Multi-select: Added 'title' and 'filename' formats (in addition to existing URL formats) * Single-select: Added singleSelectOutputFormat option (title vs filename, defaults to title) - Added NoteChooser filtering options: * startFolder: Filter notes to specific folder and subfolders * includeRegex: Optional regex pattern to include notes (case-insensitive) * excludeRegex: Optional regex pattern to exclude notes (case-insensitive) - Fixed dialogElementRenderer to respect singleSelectOutputFormat (was always using filename) - Added SearchableChooser shortDescription optimization: automatically shortens to final folder when row is narrow - Reverted compact label width to 10rem (kept input width at 360px) - Added support for receivingTemplateTitle as form field key for dynamic template selection - Updated FieldEditor with UI for all new NoteChooser options - Added comprehensive test examples in FormFieldRenderTest - Updated README with documentation for dynamic template selection - Updated CHANGELOG and plugin.json to version 1.0.16
1 parent 4b1f48c commit 4e99c18

8 files changed

Lines changed: 319 additions & 17 deletions

File tree

‎dwertheimer.Forms/CHANGELOG.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@
44

55
See Plugin [README](https://github.com/NotePlan/plugins/blob/main/dwertheimer.Forms/README.md) for details on available commands and use case.
66

7+
## [1.0.16] 2026-01-19 @dwertheimer
8+
9+
### Added
10+
- **NoteChooser Output Formats**: Added new output format options for note chooser fields:
11+
- **Multi-select mode**: Added `'title'` and `'filename'` output formats (in addition to existing `'wikilink'`, `'pretty-link'`, `'raw-url'`). These return plain note titles or filenames without any formatting.
12+
- **Single-select mode**: Added `singleSelectOutputFormat` option to choose between outputting the note title (default) or filename when a single note is selected.
13+
- **NoteChooser Filtering Options**: Added advanced filtering capabilities to note chooser fields:
14+
- **Start Folder**: Filter notes to only show those in a specific folder and its subfolders (e.g., `'@Templates'`).
15+
- **Include Regex**: Optional regex pattern to include only notes whose title or filename matches (case-insensitive).
16+
- **Exclude Regex**: Optional regex pattern to exclude notes whose title or filename matches (case-insensitive).
17+
- **SearchableChooser ShortDescription Optimization**: Added automatic shortening of short descriptions to just the final folder name when the option row is too narrow, ensuring the label text takes precedence and remains fully visible.
18+
19+
### Changed
20+
- **FormView CSS**: Reverted compact label width to 10rem (from 20rem) while keeping input width at 360px (2x the original 180px). This provides better balance between label and input field sizing.
21+
722
## [1.0.15] 2026-01-18 @dwertheimer
823

924
### Fixed

‎dwertheimer.Forms/README.md‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,37 @@ Use form fields like: <%- fieldName %>
346346

347347
All form field `key` values become variables in your template.
348348

349+
**Dynamic Template Selection:**
350+
351+
You can allow users to choose which processing template to use by adding a `note-chooser` field with the key `receivingTemplateTitle` to your form. This enables dynamic template selection at form submission time.
352+
353+
**How it works:**
354+
- Add a `note-chooser` field to your form
355+
- Set the field's `key` to exactly `receivingTemplateTitle`
356+
- When the form is submitted, the selected note's title will be used as the processing template
357+
- If no template is selected in the form field, the system falls back to the `receivingTemplateTitle` set in the form's frontmatter (if present)
358+
359+
**Example form field definition:**
360+
```json
361+
{
362+
"type": "note-chooser",
363+
"key": "receivingTemplateTitle",
364+
"label": "Choose Processing Template",
365+
"includePersonalNotes": true,
366+
"includeTemplatesAndForms": true,
367+
"startFolder": "@Templates",
368+
"includeRegex": "^Template",
369+
"description": "Select which template should process this form submission"
370+
}
371+
```
372+
373+
**Use cases:**
374+
- Allow users to choose between different processing templates (e.g., "Meeting Template" vs "Project Template")
375+
- Create a single form that can route to different processing templates based on user selection
376+
- Enable dynamic workflow routing based on form data
377+
378+
**Note:** The form must have `processingMethod: "form-processor"` set in its frontmatter. The `receivingTemplateTitle` field value takes precedence over the frontmatter value when a template is selected in the form.
379+
349380
**Date Formatting Example:**
350381

351382
```ejs
@@ -401,9 +432,11 @@ Don't use these as field keys (the plugin uses them internally):
401432
- `__isJSON__`, `submit`, `location`, `writeUnderHeading`
402433
- `openNoteTitle`, `writeNoteTitle`, `getNoteTitled`
403434
- `replaceNoteContents`, `createMissingHeading`
404-
- `receivingTemplateTitle`, `windowTitle`, `formTitle`
435+
- `windowTitle`, `formTitle`
405436
- `width`, `height`, `hideDependentItems`, `allowEmptySubmit`, `title`
406437

438+
**Exception:** `receivingTemplateTitle` can be used as a field key if you want to allow users to dynamically select the processing template. See "Dynamic Template Selection" in the Custom Processing Templates section above.
439+
407440
---
408441

409442
## Complete Field Reference (Advanced)

‎dwertheimer.Forms/plugin.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"noteplan.minAppVersion": "3.4.0",
55
"plugin.id": "dwertheimer.Forms",
66
"plugin.name": "📝 Template Forms",
7-
"plugin.version": "1.0.14",
7+
"plugin.version": "1.0.16",
88
"plugin.releaseStatus": "beta",
9-
"plugin.lastUpdateInfo": "Changed default window width from 25% to 50% for new forms, and doubled default compact field sizes (labels: 20rem, inputs: 360px)",
9+
"plugin.lastUpdateInfo": "Added NoteChooser output format options (title/filename for multi-select and single-select), advanced filtering (startFolder, includeRegex, excludeRegex), and SearchableChooser shortDescription optimization. Reverted compact label width to 10rem while keeping input width at 360px.",
1010
"plugin.description": "Dynamic Forms for NotePlan using Templating -- fill out a multi-field form and have the data sent to a template for processing",
1111
"plugin.author": "dwertheimer",
1212
"plugin.requiredFiles": ["react.c.FormView.bundle.dev.js", "react.c.FormBuilderView.bundle.dev.js", "react.c.FormBrowserView.bundle.dev.js"],

‎dwertheimer.Forms/src/FormFieldRenderTest.js‎

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,117 @@ export async function testFormFieldRender(): Promise<void> {
723723
showValue: true,
724724
description: 'Multi-select note chooser in compact display mode',
725725
},
726+
{
727+
type: 'note-chooser',
728+
label: 'Note Chooser (Multi-Select, Plain Title, Space)',
729+
key: 'testNoteMultiSelectTitle',
730+
allowMultiSelect: true,
731+
noteOutputFormat: 'title',
732+
noteSeparator: 'space',
733+
includePersonalNotes: true,
734+
includeCalendarNotes: false,
735+
includeRelativeNotes: false,
736+
includeTeamspaceNotes: true,
737+
showValue: true,
738+
description: 'Multi-select note chooser with plain title format (just the note title) separated by spaces',
739+
},
740+
{
741+
type: 'note-chooser',
742+
label: 'Note Chooser (Multi-Select, Filename, Comma)',
743+
key: 'testNoteMultiSelectFilename',
744+
allowMultiSelect: true,
745+
noteOutputFormat: 'filename',
746+
noteSeparator: 'comma',
747+
includePersonalNotes: true,
748+
includeCalendarNotes: false,
749+
includeRelativeNotes: false,
750+
includeTeamspaceNotes: true,
751+
showValue: true,
752+
description: 'Multi-select note chooser with filename format (full path/filename.md) separated by commas',
753+
},
754+
{
755+
type: 'heading',
756+
label: 'Note Chooser: Single Select Output Format',
757+
underline: true,
758+
},
759+
{
760+
type: 'note-chooser',
761+
label: 'Note Chooser (Output: Title)',
762+
key: 'testNoteSingleSelectTitle',
763+
singleSelectOutputFormat: 'title',
764+
includePersonalNotes: true,
765+
includeCalendarNotes: false,
766+
includeRelativeNotes: false,
767+
includeTeamspaceNotes: true,
768+
showValue: true,
769+
description: 'Single-select note chooser that outputs the note title (default behavior)',
770+
},
771+
{
772+
type: 'note-chooser',
773+
label: 'Note Chooser (Output: Filename)',
774+
key: 'testNoteSingleSelectFilename',
775+
singleSelectOutputFormat: 'filename',
776+
includePersonalNotes: true,
777+
includeCalendarNotes: false,
778+
includeRelativeNotes: false,
779+
includeTeamspaceNotes: true,
780+
showValue: true,
781+
description: 'Single-select note chooser that outputs the full filename path instead of title',
782+
},
783+
{
784+
type: 'heading',
785+
label: 'Note Chooser: Filtering Options',
786+
underline: true,
787+
},
788+
{
789+
type: 'note-chooser',
790+
label: 'Note Chooser (Start Folder: @Templates)',
791+
key: 'testNoteStartFolder',
792+
startFolder: '@Templates',
793+
includePersonalNotes: true,
794+
includeCalendarNotes: false,
795+
includeRelativeNotes: false,
796+
includeTeamspaceNotes: true,
797+
showValue: true,
798+
description: 'Note chooser filtered to only show notes in @Templates folder and its subfolders',
799+
},
800+
{
801+
type: 'note-chooser',
802+
label: 'Note Chooser (Include Regex: ^Project)',
803+
key: 'testNoteIncludeRegex',
804+
includeRegex: '^Project',
805+
includePersonalNotes: true,
806+
includeCalendarNotes: false,
807+
includeRelativeNotes: false,
808+
includeTeamspaceNotes: true,
809+
showValue: true,
810+
description: 'Note chooser that only includes notes whose title or filename starts with "Project" (case-insensitive regex)',
811+
},
812+
{
813+
type: 'note-chooser',
814+
label: 'Note Chooser (Exclude Regex: Archive|Draft)',
815+
key: 'testNoteExcludeRegex',
816+
excludeRegex: 'Archive|Draft',
817+
includePersonalNotes: true,
818+
includeCalendarNotes: false,
819+
includeRelativeNotes: false,
820+
includeTeamspaceNotes: true,
821+
showValue: true,
822+
description: 'Note chooser that excludes notes whose title or filename contains "Archive" or "Draft" (case-insensitive regex)',
823+
},
824+
{
825+
type: 'note-chooser',
826+
label: 'Note Chooser (Start Folder + Include Regex)',
827+
key: 'testNoteStartFolderIncludeRegex',
828+
startFolder: '@Templates',
829+
includeRegex: 'Form',
830+
includePersonalNotes: true,
831+
includeCalendarNotes: false,
832+
includeRelativeNotes: false,
833+
includeTeamspaceNotes: true,
834+
showValue: true,
835+
description: 'Note chooser filtered to @Templates folder AND only includes notes containing "Form" in title or filename',
836+
},
726837
{
727838
type: 'heading-chooser',
728839
label: 'Heading Chooser (Static)',

‎dwertheimer.Forms/src/components/FieldEditor.jsx‎

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,9 +948,11 @@ export function FieldEditor({ field, allFields, onSave, onCancel, requestFromPlu
948948
<option value="wikilink">Wikilink: [[Note Title]]</option>
949949
<option value="pretty-link">Pretty Link: [Note Title](noteplan://...)</option>
950950
<option value="raw-url">Raw URL: noteplan://x-callback-url/openNote?noteTitle=...</option>
951+
<option value="title">Plain Title: Note Title</option>
952+
<option value="filename">Filename: path/to/note.md</option>
951953
</select>
952954
<div className="field-editor-help">
953-
Choose how to format the selected notes in the output. Wikilink format is compatible with NotePlan&apos;s native linking.
955+
Choose how to format the selected notes in the output. Wikilink format is compatible with NotePlan&apos;s native linking. &quot;Plain Title&quot; and &quot;Filename&quot; return just the title or filename without any formatting.
954956
</div>
955957
</div>
956958
<div className="field-editor-row">
@@ -971,6 +973,73 @@ export function FieldEditor({ field, allFields, onSave, onCancel, requestFromPlu
971973
</div>
972974
</>
973975
)}
976+
{!((editedField: any): { allowMultiSelect?: boolean }).allowMultiSelect && (
977+
<div className="field-editor-row">
978+
<label>Single Select Output Format:</label>
979+
<select
980+
value={((editedField: any): { singleSelectOutputFormat?: string }).singleSelectOutputFormat || 'title'}
981+
onChange={(e) => {
982+
const updated = { ...editedField }
983+
;(updated: any).singleSelectOutputFormat = e.target.value
984+
setEditedField(updated)
985+
}}
986+
>
987+
<option value="title">Title (default)</option>
988+
<option value="filename">Filename</option>
989+
</select>
990+
<div className="field-editor-help">
991+
Choose what to output when a single note is selected. &quot;Title&quot; returns the note title, &quot;Filename&quot; returns the full filename path.
992+
</div>
993+
</div>
994+
)}
995+
<div className="field-editor-row">
996+
<label>Start Folder (optional):</label>
997+
<input
998+
type="text"
999+
value={((editedField: any): { startFolder?: string }).startFolder || ''}
1000+
onChange={(e) => {
1001+
const updated = { ...editedField }
1002+
;(updated: any).startFolder = e.target.value || undefined
1003+
setEditedField(updated)
1004+
}}
1005+
placeholder="e.g., @Templates/Forms"
1006+
/>
1007+
<div className="field-editor-help">
1008+
Filter notes to only show those in this folder and its subfolders. Leave empty to show all notes. Example: &quot;@Templates/Forms&quot;
1009+
</div>
1010+
</div>
1011+
<div className="field-editor-row">
1012+
<label>Include Regex (optional):</label>
1013+
<input
1014+
type="text"
1015+
value={((editedField: any): { includeRegex?: string }).includeRegex || ''}
1016+
onChange={(e) => {
1017+
const updated = { ...editedField }
1018+
;(updated: any).includeRegex = e.target.value || undefined
1019+
setEditedField(updated)
1020+
}}
1021+
placeholder="e.g., ^Project"
1022+
/>
1023+
<div className="field-editor-help">
1024+
Optional regex pattern to include only notes whose title or filename matches. Case-insensitive. Leave empty to include all notes. Example: &quot;^Project&quot; to include only notes starting with &quot;Project&quot;
1025+
</div>
1026+
</div>
1027+
<div className="field-editor-row">
1028+
<label>Exclude Regex (optional):</label>
1029+
<input
1030+
type="text"
1031+
value={((editedField: any): { excludeRegex?: string }).excludeRegex || ''}
1032+
onChange={(e) => {
1033+
const updated = { ...editedField }
1034+
;(updated: any).excludeRegex = e.target.value || undefined
1035+
setEditedField(updated)
1036+
}}
1037+
placeholder="e.g., Archive|Draft"
1038+
/>
1039+
<div className="field-editor-help">
1040+
Optional regex pattern to exclude notes whose title or filename matches. Case-insensitive. Leave empty to exclude nothing. Example: &quot;Archive|Draft&quot; to exclude notes containing &quot;Archive&quot; or &quot;Draft&quot;
1041+
</div>
1042+
</div>
9741043
</>
9751044
)}
9761045

‎helpers/react/DynamicDialog/DynamicDialog.jsx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,12 @@ export type TSettingItem = {
128128
showCalendarChooserIcon?: boolean, // for note-chooser, show a calendar button next to the chooser (default: true)
129129
onOpen?: () => void | Promise<void>, // for note-chooser and other choosers, callback when dropdown opens (for lazy loading)
130130
allowMultiSelect?: boolean, // for note-chooser, enable multi-select mode (default: false)
131-
noteOutputFormat?: 'raw-url' | 'wikilink' | 'pretty-link', // for note-chooser multi-select, output format (default: 'wikilink')
131+
noteOutputFormat?: 'raw-url' | 'wikilink' | 'pretty-link' | 'title' | 'filename', // for note-chooser multi-select, output format (default: 'wikilink')
132132
noteSeparator?: 'space' | 'comma' | 'newline', // for note-chooser multi-select, separator between notes (default: 'space')
133+
singleSelectOutputFormat?: 'title' | 'filename', // for note-chooser regular select mode, output format (default: 'title')
134+
startFolder?: ?string, // for note-chooser, start folder to filter notes (e.g., '@Templates/Forms')
135+
includeRegex?: ?string, // for note-chooser, regex pattern to include notes (applied to filename or title)
136+
excludeRegex?: ?string, // for note-chooser, regex pattern to exclude notes (applied to filename or title)
133137
// showValue option for SearchableChooser-based fields
134138
showValue?: boolean, // for folder-chooser, note-chooser, heading-chooser, dropdown-select-chooser: show the selected value below the input (default: false)
135139
// space-chooser options

0 commit comments

Comments
 (0)