TJSDialog how to use buttons and callback or return value?
I'm planning to use TJSDialog to act as an intervening Application. So... player clicks a button that would normally generate a ChatMessage. However, a flag causes instead a dialog to appear with several options for the player. Once the decision is made between the options, that information needs to be used by the component that opened the dialog to allow the ChatMessage to be generated at that point.
Option 1
I can see that TJSDialog has a mechanism for something along these lines, but I haven't been able to figure out how to use it -
managedPromise
- seems to be a private property of TJSDialog without a setter.
Option 2
It seems that using the prompt
function is one way... but a simple binary choice won't be sufficient for my case. It will be more like a radio button with multiple options of which one must be selected.
Option 3
Another option would be the onClose
callback, provided that I could write a value to return from the dialog, which sounds plausible, except that I'm not sure how to provide buttons to the TJSDialog. It tells me that I can provide them as TJSDialogButtonData
types but I can't find that type definition in the runtime codebase.
Option 4
I suppose I could write the value to a svelte store, provide a custom button in the content, which writes to that store, then close the dialog when an option is clicked and trigger the onClose
callback from there.4 Replies
Have you used
TJSDialog.confirm()
? Here's an example:
https://github.com/fantasycalendar/FoundryVTT-ItemPiles/blob/master/src/API/trade-api.js#L70-L87
You could quite easily implement something similar with your own extension of the TJSDialog class, returning the result you want to have from your own overwritten method of prompt
or such"Option" 3 & 4 are no good. I don't have any visibility on what the content of your dialog is like, but it sounds like it has multiple options that may not be buttons. IE checkboxes or something else. You can set up a form and when the user clicks a submit button you can process the form and return the results through the "ManagedPromise" and then manually close the dialog. However, I want to try and provide the least difficult way for you to accomplish your goal.
Can you post a pict of the dialog content / component that you would like to display?
TJSDialog gives you significantly more flexibility to design advanced dialogs than the core Dialog implementation. "ManagedPromise" is something unique to TJSDialog. As the documentation states you get access to it in your content component through
const managedPromise = getContext('#managedPromise')
. This allows you to do any complicated async processing you want and return the results through the normal dialog flow. Re: TJSDialogButtonData
. That is a typedef
or description of the object data that you can pass for dialog buttons. It's defined at the bottom of TJSDialog
. You'll notice that you can set onPress
to a callback function or give it a string name of a function in the content component to invoke when the button is pressed. When you do this you also want to set autoClose
to false
. For form processing this is where you can invoke form.requestSubmit()
and then if the form validates the form has a processing function it invokes. That is where you can process the form and return any results through the ManagedPromise
.
I hazard to point you to an example of this as they are complex async oriented dialogs handling the standard CRUD document actions, but here is a section of a dialog to examine for more involved form processing:
https://github.com/typhonjs-fvtt-lib/svelte/blob/main/src/component/dialog/document/TJSDocumentCreate.svelte#L46-L75
Here is where the requestSubmit
function in the content component is hooked up to the button (note that autoClose
is also set to false
):
https://github.com/typhonjs-fvtt-lib/svelte/blob/main/src/application/dialog/document/TJSDocumentCreate.js#L57
Depending on how complex your dialog is you may want to extend TJSDialog, but it's possible to do all sorts of things in a data derived manner as well, but for code cleanliness sometimes it's easier to extend TJSDialog.
-------------------------
The above is for a full involved async form processing example. Don't just copy code. There may be a much easier solution, so please post a pict of the content of your dialog.It will be something like this. These are
li
elements in a ul
with click event listeners attached. Clicking one will select it and deselect the others. UI will highlight selection. Then there will be a Roll
button below to confirm. The row selected will have some data associated with it that the component that created the dialog will need to process.
You mentioned documentation... are you referring to comments within the code? Please could you point out where getContext('#managedPromise').
is documented? As I didn't see that.In this case there is no form per se as you'll be tracking whatever data the user manipulates in the content Svelte component. It probably should be an async dialog though.
// dialog content Svelte component
// Invoking the dialog via data.
You may also want to extend TJSDialog and include all of the above data in the constructor passing it on to TJSDialog.
Then you would do...
There are two versions of
wait
; an instance and the prior shown static version shown above.
And yes documentation in the source file itself.