The jQuery UI dialog, like many jQuery UI plugins, is extremely easy to get started with but has a few areas that causes new users some trouble. One of the most commonly asked questions on the jquery-ui list is “Why does my dialog only open once?” In this article I’ll explain the problem these users are running into and how to get your dialogs to show each and every time.
Problem:
All jQuery UI plugins maintain state, such as the current option values, whether the plugin is enabled or disabled, which plugins have been initialized on the element, etc. This state persists from the time the plugin is instantiated on the element until it is destroyed, either explicitly by the user calling .pluginName('destroy')
or by removing the element (or one of its ancestors) via .remove()
. Because of this state management, you cannot instantiate the same plugin on an element multiple times, unless you destroy the plugin instance first.
The problem that users often encounter with dialogs is that they try to instantiate a new dialog every time the user performs some action (generally clicking a link or a button). This is an understandable mistake because at first glance it seems like calling .dialog()
on an element is what causes the dialog to open. In reality what is happening is that a new dialog instance is being created and then that instance is being opened immediately after instantiation. The reason that the dialog opens is because dialogs have an autoOpen
option, which defaults to true
. So when a user calls .dialog()
on an element twice, the second call is ignored because the dialog has already been instantiated on that element.
Solution:
The simple solution to this problem is to instantiate the dialog with autoOpen
set to false
and then call .dialog('open')
in the event handler.
$(document).ready(function() { var $dialog = $('') .html('This dialog will show every time!') .dialog({ autoOpen: false, title: 'Basic Dialog' }); $('#opener').click(function() { $dialog.dialog('open'); // prevent the default action, e.g., following a link return false; }); });