Dialog Box Auto-Closing Upon Opening 2nd Time

I've been appending custom functionality to the simple worldbuilding system. At this time, I'm trying to loop over all actors and then use and their items to add things up and perform rolls. To add modifiers, I want to make a dialogue box pop up wherein I can type in additional modifiers/etc, such as +1att (give the attacker +1 advantage to their role under value) The first time, it works! It prints verbose. That is the "building block" string for me to build additional logic on top of. The 2nd time, the dialogue just instantly returns "" and then it doesn't print verbose.
if (messageText === "/combatcheck") {
// Prompt for additional input
// Define a function to display the dialog and return the input
async function getAdditionalInput() {
return new Promise((resolve) => {
// Unique identifier for the input
const uniqueId = `additional-input-${new Date().getTime()}`;

let dialog = new Dialog({
title: "Additional Input",
content: `<p>Enter additional flags/commands:</p><input type='text' id='${uniqueId}'/>`,
buttons: {
ok: {
icon: "<i class='fas fa-check'></i>",
label: "Submit",
callback: (html) => resolve(html.find(`#${uniqueId}`).val())
},
cancel: {
icon: "<i class='fas fa-times'></i>",
label: "Cancel",
callback: () => resolve(null)
}
},
default: "ok",
close: () => resolve(null)
});

// Render the dialog
dialog.render(true);
});
}
const additionalInput = await getAdditionalInput();
const verboseMode = additionalInput.includes("verbose");
if (verboseMode) {
console.log(`Verbose mode enabled!`);
}

// Keep doing stuff down here...
if (messageText === "/combatcheck") {
// Prompt for additional input
// Define a function to display the dialog and return the input
async function getAdditionalInput() {
return new Promise((resolve) => {
// Unique identifier for the input
const uniqueId = `additional-input-${new Date().getTime()}`;

let dialog = new Dialog({
title: "Additional Input",
content: `<p>Enter additional flags/commands:</p><input type='text' id='${uniqueId}'/>`,
buttons: {
ok: {
icon: "<i class='fas fa-check'></i>",
label: "Submit",
callback: (html) => resolve(html.find(`#${uniqueId}`).val())
},
cancel: {
icon: "<i class='fas fa-times'></i>",
label: "Cancel",
callback: () => resolve(null)
}
},
default: "ok",
close: () => resolve(null)
});

// Render the dialog
dialog.render(true);
});
}
const additionalInput = await getAdditionalInput();
const verboseMode = additionalInput.includes("verbose");
if (verboseMode) {
console.log(`Verbose mode enabled!`);
}

// Keep doing stuff down here...
Has anyone else had issues with Dialogues behaving so oddly? Why is my new Dailog instantly closing with no value?
3 Replies
Farling
Farling10mo ago
I may be wrong. but isn't the "dialog" variable going out of scope after render has been called - and thus the Dialog object is deleted at the end of the function?
mfi
mfi10mo ago
@Farling That's possible - I'm not familiar with how the internals work in terms of scoping. However, the FIRST render stays in-scope. Why would the second one suddenly not? Can anyone assist with this? We've been stuck for over a month which means we aren't gettign the value out of the product. Here's the code so that you can repeat the issue:
async function openTextareaDialog() {
return new Promise((resolve, reject) => {
// Create a unique ID for the textarea to avoid conflicts
const textAreaId = `input-text-${Date.now()}`;

const template = `
<form>
<div class="form-group">
<textarea id="${textAreaId}" name="input-text"></textarea>
</div>
</form>
`;

let d = new Dialog({
title: "Input Text",
content: template,
buttons: {
ok: {
icon: '<i class="fas fa-check"></i>',
label: "Submit",
callback: html => {
const text = html.find(`#${textAreaId}`).val();
resolve(text);
}
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: "Cancel",
callback: () => reject(new Error('Dialog cancelled'))
}
},
default: "ok",
close: () => {
// Reject the promise if the dialog is closed without submission
reject(new Error('Dialog closed'));
}
});

// Render the dialog
d.render(true);
});
}


/* Custom */
Hooks.on("chatMessage", async (chatLog, messageText, chatData) => {
if (messageText === "!showdialog") {
try {
// Open the dialog and wait for the user to submit
const enteredText = await openTextareaDialog();

// Output the entered text to the console
console.log('Entered dialog:', enteredText);
} catch (error) {
console.error('Dialog error:', error);
}
}
async function openTextareaDialog() {
return new Promise((resolve, reject) => {
// Create a unique ID for the textarea to avoid conflicts
const textAreaId = `input-text-${Date.now()}`;

const template = `
<form>
<div class="form-group">
<textarea id="${textAreaId}" name="input-text"></textarea>
</div>
</form>
`;

let d = new Dialog({
title: "Input Text",
content: template,
buttons: {
ok: {
icon: '<i class="fas fa-check"></i>',
label: "Submit",
callback: html => {
const text = html.find(`#${textAreaId}`).val();
resolve(text);
}
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: "Cancel",
callback: () => reject(new Error('Dialog cancelled'))
}
},
default: "ok",
close: () => {
// Reject the promise if the dialog is closed without submission
reject(new Error('Dialog closed'));
}
});

// Render the dialog
d.render(true);
});
}


/* Custom */
Hooks.on("chatMessage", async (chatLog, messageText, chatData) => {
if (messageText === "!showdialog") {
try {
// Open the dialog and wait for the user to submit
const enteredText = await openTextareaDialog();

// Output the entered text to the console
console.log('Entered dialog:', enteredText);
} catch (error) {
console.error('Dialog error:', error);
}
}
We decided to go forward using prompt() for the time being
Zhell
Zhell10mo ago
Use the name attribute instead of id. There is hardly ever any reason to use id attributes on forms. And if you want an asynchronous dialog, use Dialog.prompt or Dialog.wait. These are factory methods for this specific purpose.
const value = await Dialog.prompt({
content: `
<form>
<div class="form-group">
<label>Modifier</label>
<div class="form-fields">
<input type="text" name="mod" autofocus>
</div>
</div>
</form>`,
label: "OK",
title: "Get Modifier",
callback: ([html]) => new FormDataExtended(html.querySelector("FORM")).object.mod
});
const value = await Dialog.prompt({
content: `
<form>
<div class="form-group">
<label>Modifier</label>
<div class="form-fields">
<input type="text" name="mod" autofocus>
</div>
</div>
</form>`,
label: "OK",
title: "Get Modifier",
callback: ([html]) => new FormDataExtended(html.querySelector("FORM")).object.mod
});
Want results from more Discord servers?
Add your server