I want to provide a dialog with an input box and get the entered value back to the plugin.
How can I do this with the current joplin.views.dialogs API?
My example command looks like this:
await joplin.commands.register({
name: 'editURL',
label: 'Set URL',
iconName: 'fas fa-edit',
enabledCondition: "oneNoteSelected && !inConflictFolder",
execute: async () => {
// get the selected note and exit if none is currently selected
const selectedNote = await joplin.workspace.selectedNote();
if (!selectedNote) return;
// create new dialog
// API: dialog box has fixed width which cannot be overwritten by plugin itself - so input is cutted
const dialogs = joplin.views.dialogs;
const urlDialog = await dialogs.create();
await dialogs.setHtml(urlDialog, `
<div class="joplin-note-ext-dialog" style="display:inline-flex; min-width:300px;">
<label style="min-width:fit-content; margin:auto; padding-right:5px;">Set URL:</label>
<input type="text" style="width:100%;" value="${selectedNote.source_url}">
</div>
`);
const result = await dialogs.open(urlDialog);
// get return and new URL value
if (result == 'ok') {
// API: How to get feedback from a dialog? PostMessage?
alert('This button was clicked: ' + result);
}
},
});
Would it be possible to allow PostMessages like in joplin.views.panels API?
Or is there any other way to get this information from the dialog?
Addition: I think I found a small issue in the dialogs...
The opened dialog has a fixed width which cannot be overwritten by plugin content.
In the example command above, I want to have a min-width of 300px for the dialog. Just to a have a bigger input field.
But the dialog will not extend to the desired width. The input is just cutted at the end.
After adding width: fit-content; to the parent container div#joplin-plugin-content the dialog box extends to the desired width.
Hmm, yes good question, it seems I've overlooked that. How about making dialogs.open return the value of all form elements?
Other solutions indeed would involve postMessage, but that seems unnecessary as what you'd want from a dialog usually is the values of whatever fields are in it.
I think this way would cover any possible use case, since you can do relatively advanced dialog behaviour by modifying with JavaScript the input values. You can also use hidden inputs and have custom JS components modify its value.
With this I am able to retrieve the value from the input box with const newUrl = result.formData.urlForm.url as string;.
But there are still two problems I observed.
I have to specify the form tag - the global value with '_' (as specified above) seems not to be created.
When I hit Enter while the cursor is in the input box - the plugin HTML code is removed from the DOM completely. So only an empty div#joplin-plugin-content tag remains. The screenshot shows the dialog and the DOM after Enter was pressed:
Yes in the end I've decided not to implement this because it's not really standard. In HML, inputs should be within form elements, so this is required by the plugin API too.