Follow up for #1667742: Add abstracted dialog to core (resolves accessibility bug) - to decide where we want to use modal dialogs in core.

Proposed resolution

Review places where modals are good UX and create task for each conversion. List the issues here:

Current issues

#1842036: [META] Convert all confirm forms already converted to new routing system to use modal dialog
#1857398: Move the request for current password on email/password change to a modal dialog.
#1855992: Use dialog api for formatter settings

Remaining tasks

Identify places where modals are good UX

User interface changes

Modals where there were none :)

API changes

None yet


User Advocate’s picture

I think it’s beneficial to consider the question of where to use modals by establishing a clear understanding of what they are to be used for and how they can be abstracted for general purpose usage while also able to target specific usage contexts. The following are some notes that aim to do that.

Purpose of a modal
The goal of a fully abstracted modal is to provide a means of allowing a user who is engage with a primary task objective to conduct a secondary task while keeping the primary ‘in the background’. The nature of those secondary tasks can vary significantly so the abstracted modal would ideally support such variance while keeping the function signature as concise as possible.

Types of modals
In general, a modal will ask the user to take some action and this may or may not involve inputting required information associated with the action. Here’s a list of example types:

  • Informational - Presents a timely message. No action required other than ‘OK’.
  • Decisions - Asks the user a question and expects an action in return. Actions are provided to the dialog and could be collections of choices such as [‘Yes’, ‘No’], [‘Save’, ‘Replace’, ‘Cancel’], [‘Red’, ‘Green’, ‘Blue’], etc. Each action consists of a label string and a url for the callback.
  • Complex - Contains forms provided by the calling context in addition to the collection of possible actions. The user provides more extensive input through the form. Examples are:
    • Login form
    • Add or edit a field for a content type, create or edit an image style, etc.
    • Multi-step wizards where no action is taken until all steps are passed
    • AJAX modals (e.g. file uploader with intelligence to recognize file formats and display appropriate fields)

The main advantage of an abstracted approach is that certain configuration parameters could be preset, based on the type of the modal. A ‘delete confirmation’ dialog could have a standard prompt to pose the ‘Are you sure…’ question along with a standard title and standard button strings. The actions of course would be case-specific. The prompt and title strings could contain placeholders for providing specifics such as the name or type of the object(s) being deleted. This provides both increased consistency for the user and greater efficiency for the developer who could call the function with minimal configuration.

All this suggests a two layered approach with a central modal dialog builder being accessed through a series of wrappers that are built for each type of modal. Based on the current implementation of the confirmation dialog, it looks like we have these parameters already in place:

  • $question – The Primary prompt
  • Actions – Provided as explicit parameters with labels and callback paths
  • $description – some optional extra help
  • $form – an optional array of input elements

In addition to this I would suggest a separate $title parameter for the dialog and to shift the $question (or $prompt) into the main area of the dialog so it can be clearly seen as a prompt. An optional $icon element would also be useful for providing visual cues that help the user recognize the meaning of the modal - in many applications we see these as exclamation marks, stop signs, etc.

One final note about getting to a higher level of abstraction, by packaging the actions into an array, the function signature can be fixed for all use cases while the range of actions can remain flexible.

I hope these suggestions are useful in the context of mapping out how and where we can get modals deployed. For anyone interested in the theory behind all this I’ve prepared this SBUI video that illustrates it from the UX design point of view.

tsvenson’s picture

Adding Drupal SBUI tag.

Edit: It was clearly added, but still didn't stick...

RobW’s picture

...allowing a user who is engage with a primary task objective to conduct a secondary task while keeping the primary ‘in the background’.

Another way of looking at modals that can help decide when to use them: modals are for when a task must be completed before the user is returned to the regular editing/interaction workflow.

For example, a WYSIWYG editor (WYSIHTML5 works this way) pops up an inline textbox to add a link instead of a modal, because adding or editing a link doesn't affect or invalidate the rest of the page, or even the rest of the editable text area. This allows users to continue interacting with their edit page (e.g., referencing or copying text that occurs in other areas of the page for the link text or href).

tkoleary’s picture

I was thinking the same thing. Both are valid. It can be "must be" or "can be" operations.

The "can be" ones usually have the use case "While I am using UI "foo" I want to quickly make a minor change in UI "bar" that effects what I am doing in UI "foo"

Current D7 examples include:

• I am editing an article node and I want to change some aspect of the configuration of my text editor (add a filter, change wysiwyg options, add buttons, add an allowed tag etc.) without leaving the node edit form.

• I am in blocks UI and I want to configure a block without a new page load. (how many times have you lost all your table drag changes in blocks by configuring a block mid-stream?)

• Edit menus, add link. Exact same issue as blocks.

• Field UI. Add new field —> manage display. Now occurs in two separate tabs but could be made into a multi-step modal.

Overall I think this functionality can be a HUGE improvement to usabilty in D8. Thanks Michael for laying it out so clearly.

Bojhan’s picture

Thanks for opening this issue, looks like this received some great feedback already. The most important goal of this issue is to create a consistent pattern for using modals, it should be clear so contrib maintainers can follow suit. It looks like realistically it comes down to the following places:

  1. After pressing a button, e.g. confirmation dialog.
  2. After clicking an operation in a table
  3. In context of an operation, e.g. opening the "more information" link below node body's textarea in a modal

I feel both 1,3 are clear cut cases where we can apply modal dialogs and can expect contrib to follow suit seamlessly. However most of my concern is with 2, this because if we apply this sparingly the user will never know what happens when they click an operation.

For example, if as tkoleary suggested we apply it for:


That means, you now have one table that does offer a modal when you click "Configure" and other places in core where it doesn't offer that. Or do we want to also offer a modal for vocabulary/term configuration, image styles, shortcuts, views, entity translation etc. - essentially rendering all edit/configure links in tables as modals, with a few exceptions (e.g. views).

I am personally not a big fan of replacing table operations with modals, although there are plenty of places where its in the task flow (blocks ui, formatter settings in field UI) there are also plenty of places where its not (content listing, views listing, rules listing etc.). By handpicking places we feel its suitable, we are introducing significant inconsistency in the user experience and one that contrib will be unable to follow. I have usability tested many applications where it was done inconsistently, and it has a huge hit on perceived usability as people don't know what to expect.

I think formatter settings is the only place in core currently where we employ a visual signal for opening something in table. Perhaps we need a different visual affordance, however with the introduction of drop buttons that is near impossible or really ugly to do. And we need to decide what constitutes as a complex UI, where you are just editing values of an object (e.g. views). Anyways, just more food for thought

RobW’s picture

I think it's more valuable to list the type of actions taking place in a modal (e.g., form-wide confirmation dialog, multi-step operations within a single form item) as opposed to the type of link launching them (e.g., button, table link). I do totally agree that consistency is paramount for an understandable user experience, and a visual indicator that the action you're about to take will open a modal would be a big win.

It would be helpful to have a list of general actions and specific current instances modals are launched from, should be launched from, or could (fuzzy area) be launched from to review. For instance, I'm not sure that the "more information" link below a filtered text area should be opened in a modal -- a user should be able to reference allowed tags as they're writing, instead of having to stop writing, open a modal, remember tags, close and continue until they need to check again, then repeat -- but I'm sure some would disagree, and the issue probably needs a bit of discussion. Going through a list with pros and cons will help expose patterns we can apply impartially across core and make available to module developers.

klonos’s picture

Just in case nobody else has though of this before, one of the things that I'd like to see in a modal is the request for current password on password/email change (account edit page).

Here's an issue filed specifically for this request:

#1857398: Move the request for current password on email/password change to a modal dialog.

I'm adding it to the list of issues in the issue summary as well...

klonos’s picture

Issue summary:View changes

...adding #1857398

jibran’s picture

Issue summary:View changes

Updated issue summary.

Xano’s picture

Issue summary:View changes

#2253257: Use a modal for entity delete operation links we reached concensus that we'd like to convert all delete links to use modals, but we need to list these links first:

  • \Drupal\Core\Entity\EntityForm
  • \Drupal\forum\Form\ForumForm
  • Drupal\path\Form\EditForm, which also still uses a button and a form redirect to redirect from the edit form to the delete form.
  • Drupal\Core\Entity\EntityListBuilder, which is worked on in #2253257: Use a modal for entity delete operation links.
  • Drupal\aggregator\Controller\AggregatorController
  • Drupal\ban\Form\BanAdmin
  • theme_book_admin_table()
  • Drupal\comment\CommentViewBuilder
  • Drupal\comment\Plugin\views\field\LinkDelete
  • Drupal\config_translation\Controller\ConfigTranslationController
  • content_translation_overview()
  • Drupal\image\Form\ImageStyleEditForm
  • theme_language_negotiation_configure_browser_form_table()
  • Drupal\menu_ui\MenuForm
  • Drupal\node\Controller\NodeController
  • Drupal\node\Plugin\views\field\LinkDelete
  • Drupal\node\Plugin\views\field\RevisionLinkDelete
  • Drupal\path\Controller\PathController
  • Drupal\shortcut\Form\SetCustomize
  • Drupal\taxonomy\Form\OverviewTerms

All links/button point to a confirmation page we can show in the modal. I'd like to get some feedback on whether or not we want to convert all of them.

yoroy’s picture

Thanks for compiling that list. For consistency sake, there'd be no objection to convert them all. I can't tell, but do you think there are odd ones in this list?

Xano’s picture

Not as far as I can see, but I will do a manual check when making the actual conversion. Would you like the conversion to happen in a single patch, or separate ones? Converting one link to a dialog requires only the addition of a few lines of code that will be the same for any link.

// Edit: I can use #2253257: Use a modal for entity delete operation links to do all conversions instead of just the one.

yoroy’s picture

Maybe do a patch that does one first, hash things out as necessary, get that committed and then do another one that converts all the others?

LewisNyman’s picture