I want to have a feature in the game that has pop ups appear for crucial/random events and for notifications. I can get the pop ups to appear fine using the inbuilt dialog system but I want the option to prevent people from just canceling out of the crucial ones and force them to make a choice from offered buttons.
I’ve already found some code made by someone else that prevents the user from just clicking off the pop up to cancel it (script below) but there’s still the X button in the corner.
Can I remove that somehow?
Here is the code to prevent clicking off the box (from violgamba over on the twine forums):
Macro.add("popLink", { tags : null, handler: function()
{
var a = $("<a/>");
a.html(this.args[0]);
a.data("title", this.args[1]);
a.data("content", this.payload[0].contents);
a.data("undismissable", this.args[2]);
Dialog.addClickHandler(a, null, onPopLinkClicked);
$(this.output).append(a);
}});
function onPopLinkClicked(evt)
{
var $target = $(evt.target);
Dialog.setup($target.data("title"));
Dialog.wiki($target.data("content"));
if ($target.data("undismissable"))
{
$("#ui-overlay").removeClass("ui-close");
$("#ui-dialog").addClass("closeBlocked");
}
else
{
$("#ui-overlay").addClass("ui-close");
$("#ui-dialog").removeClass("closeBlocked");
}
}```
I’m not at all experienced with Sugarcube macros or pop-ups so take this with a huge grain of salt, but this may not be possible? A few minutes of searching indicates preventing users from closing a pop-up is related to preventing users from closing a window in general, which gave me this StackOverflow answer (dom events - How to block users from closing a window in Javascript? - Stack Overflow), which says you’re not ‘meant’ to do it and you’d have to use workarounds. Not sure if those workarounds would actually do anything since I haven’t tested them. You could look up ‘stop users from closing window javascript’ if you want to see more possible answers.
You might be able to make it so that closing the window without selecting anything defaults to one of the possible choices - that’s the only idea that comes to mind for me…
There are two general categories of Dialog, Modal and Modeless, and you are describing the behaviour of a Modal Dialog.
And while I agree with the general advice that using a Modal Dialog in a web-browser based application is not a good idea, especially when that application may be accessed by people using Accessibility Tools, I will answer your question about how a such a dialog can be created using SugarCube.
If you review the source code of the engine function responsible for opening a dialog, you will see that an Event Handler is added to the page to listen for a click.dialog-close event, and it is that handler which is responsible for closing the dialog if either the X button or the background of the page is selected.
If you review the HTML section of SugarCube’s documentation you will learn the HTML element structure used to display all dialogs, and the identifiers assigned to those elements.
The following Modal dialog example demonstrates:
how to identify a Dialog from all others by passing a known CSS class to the Dialog.setup() function.
how to use a jQuery off() function to remove an existing Event Handler.
how to use a jQuery hide() function to hide the X button. warning: doing this affects all dialogs, not just your custom one.
how to use a jQuery show() function to reset the X button when the Model dialog is closed by listening for the :dialogclosing event, so the button will become visible in other dialogs.
<<link "Open Modal Dialog">>
<<script>>
/* identify this dialog using a known CSS class */
Dialog.setup("Modal Dialog", "modal");
/* Load the dialog's content from a 'child' Passage */
Dialog.wiki(Story.get("Dialog Content").processText());
Dialog.open();
/* Disable the X button and Background selecting behaviour */
$(document).off('click.dialog-close', '.ui-close');
/* Hide the X button */
$('#ui-dialog-close').hide();
/* Reset the X button when the dialog is closed */
$(document).one(':dialogclosing', function (ev) {
$('#ui-dialog-close').show();
});
<</script>>
<</link>>