Dialog Box / Question
Overview
An application’s primary activities take place in its main view. Occasionally the user needs to initiate a secondary activity at the same time as the primary activity, while maintaining the context of the first. Use the dialog box component to display a secondary activity in a window that floats above the primary activity taking place in the main view. The user’s attention is focused on the secondary activity, but they can still see the primary activity in the background.
A dialog box includes the following sections:
- A header at the top with a short title that explains what the dialog box is about
- One or more buttons right aligned at the bottom that close the dialog box and control the dialog’s action
- Optional content that displays between the dialog box header and the dialog box buttons
A dialog box is modal, which means that the user can see the primary activity in the background but cannot interact with it. Their focus is temporarily on the secondary activity.
Dialog boxes are reserved for simpler activities. Display more complex activities in the main view. In particular, dialog boxes cannot include a toolbar.
A dialog box must never launch another dialog box. Only one dialog box can be displayed at a time.
At mobile size, avoid using dialog boxes that are more complex than a simple question. There isn’t enough room to effectively display a secondary action without creating a confusing user experience, so keep this activity in the main view. If a view needs to be supported at mobile size, that often requires breaking larger tasks down into smaller pieces for the mobile experience.
The dialog box closes when the user presses any of the buttons at the bottom of the dialog or when the user presses the Escape key. You can include simple validations that disable a Save button until valid input is entered by the user, if appropriate. If the user closes the dialog box by pressing the Escape key, respond to that as if the user pressed the least destructive button option presented by the dialog. A dialog box should not close because the user clicks outside of it.
Dialog Box Buttons
A dialog box includes one button for each major action that the user can take with the dialog box. These buttons display in a section at the bottom-right of the dialog box. Each of these buttons closes the dialog box with a specific context.
The simplest dialog boxes only need to offer a single “Close” button, allowing the user to dismiss the dialog box. More complex dialog boxes ask the user to select between multiple actions, for example “Save” and “Cancel”. If the dialog box can add, modify, or delete anything, it must include a “Cancel” button to allow the user to back out of the dialog box without making any changes.
Dialog box button labels should be verbs that describe what will happen when the user presses the button. These labels should be both descriptive and succinct. Well labeled buttons should act like micro-help; not all users will read dialog box text completely, so button labels should be clear enough to accurately guide users through their tasks. Do not use generic button labels like “OK”; use descriptive button labels instead, such as “Close”, “Save”, and “Delete”. Always use the label “Cancel” for a button that allows the user to back out of the dialog box without making any changes.
Each dialog box button should use proper styling to communicate its impact:
- Use primary styling for the one dialog box button that performs the primary action for the dialog. Examples would include “Close” and “Save”. There should be no more than one primary button in the dialog box.
- Use destructive styling if pressing the dialog box button triggers a significant, destructive action like deletion. This button style should be used sparingly.
- Use secondary styling for all other dialog box buttons, including “Cancel” buttons. In some cases, all dialog box buttons have equal impact. Use secondary styling for all dialog buttons in this case.
Examples
Here are some common examples of dialog boxes.
A dialog box can be used to display a simple message that the user must acknowledge. In this case, display the message in the dialog box header and include a single Close button, which closes the dialog with no further action. (Most simple messages are displayed using notifications; a dialog box should only be used for this purpose if it’s important for the user to acknowledge the message.)
A dialog box can be used to ask a simple question. In this case, display the question in the dialog box header. Include buttons that answer the question but use descriptive labels (not just Yes/No). If the question requires more contextual information to help the user make the decision, display that info in the content area.
A dialog box can be used to prompt for user input then perform an action. In this case, display a title in the header, Save and Cancel buttons in the footer, and the appropriate input components in the content area.
A simple question displays as a slide-up at mobile size. (Don’t use complex dialog boxes at mobile size.)
A question that includes a destructive button.
Development
Web component development
Component reference
rui-question
Displays a simple question or message in a popup window at larger screen sizes and in a slide up at mobile size, with one or more buttons. No content displays other than the title and buttons.
Name | Type | Default | Description |
---|---|---|---|
titleText | string | '' | The short question or message displayed in the dialog box header |
showQuestion | boolean | false | This is a boolean trigger property. Bind this property to a backing boolean value in your controller, then set the backing value to true whenever you want to display the question. |
rui-question-show-question-change | event | Event fired when the showQuestion property value resets within the component. You must reset the backing boolean value in your controller to which the showQuestion property is bound when this event fires. | |
hideQuestion | boolean | false | The question is typically closed manually by the user, but you can also hide it programmatically. This is a boolean trigger property. Bind this property to a backing boolean value in your controller, then set the backing value to true whenever you want to programmatically hide the question. |
rui-question-hide-question-change | event | Event fired when the hideQuestion property value resets within the component. You must reset the backing boolean value in your controller to which the hideQuestion property is bound when this event fires. | |
rui-question-close | event | Event fired when the user clicks a dialog box button or presses the Escape key. In each of those cases the dialog box closes and the rui-question-close event fires. The event handler should accept a CustomEvent parameter; the detail of this event contains the text of the button pressed by the user, or the word “Escape” if the user pressed the Escape key, in which case you should respond to that as if the user pressed the least destructive button option presented by the dialog. |
rui-dialog-box
Displays information and/or inputs in a popup window, with one or more buttons
Name | Type | Default | Description |
---|---|---|---|
titleText | string | '' | The title displayed in the dialog box header |
dialogWidth | string | 'medium' | This determines the width of the dialog box. One of:
|
showDialog | boolean | false | This is a boolean trigger property. Bind this property to a backing boolean value in your controller, then set the backing value to true whenever you want to display the dialog box. |
rui-dialog-box-show-dialog-change | event | Event fired when the showDialog property value resets within the component. You must reset the backing boolean value in your controller to which the showDialog property is bound when this event fires. | |
hideDialog | boolean | false | The dialog box is typically closed manually by the user, but you can also hide it programmatically. This is a boolean trigger property. Bind this property to a backing boolean value in your controller, then set the backing value to true whenever you want to programmatically hide the dialog box. |
rui-dialog-box-hide-dialog-change | event | Event fired when the hideDialog property value resets within the component. You must reset the backing boolean value in your controller to which the hideDialog property is bound when this event fires. | |
rui-dialog-box-close | event | Event fired when the user clicks a dialog box button or presses the Escape key. In each of those cases the dialog box closes and the rui-dialog-box-close event fires. The event handler should accept a CustomEvent parameter; the detail of this event contains the text of the button pressed by the user, or the word “Escape” if the user pressed the Escape key, in which case you should respond to that as if the user pressed the least destructive button option presented by the dialog. | |
rui-dialog-box-before-show | event | Event fired right before the dialog box shows. | |
rui-dialog-box-after-show | event | Event fired right after the dialog box shows. | |
rui-dialog-box-before-close | string | '' | Event fired right before the dialog box closes. |
canClose | boolean | true | This is a boolean property telling the component whether or not the dialog can close when a dialog box button or the Escape key is pressed. Binding this property to false will fire the rui-dialog-box-before-close event, but not the rui-dialog-box-close event, and will keep the dialog from closing. |
canClosePollCount | number | 0 | If this property is set to a number greater than 0, the dialog box component will poll every 100 milliseconds to test if canClose is set to true. If your product has a long service call fired to validate form elements within the dialog asynchronously, you can set this to a high value to keep polling for an updated canClose value. |
rui-dialog-box-button
Adds a button to rui-dialog-box or rui-question. This button closes the dialog box with a specific context when pressed.
Name | Type | Default | Description |
---|---|---|---|
text | string | '' | The text displayed in the button. This is also the value returned in the rui-dialog-box’s rui-dialog-box-close event when the user presses this button. |
buttonStyle | string | 'secondary' | Specifies the styling displayed for the button: One of “primary”, “secondary”, or “destructive”
|
isDisabled | boolean | false | Specifies whether the button is disabled. |
Implementing a question
Use rui-question
to show a simple message or ask a simple question. The question includes a title (the message or question) and one or more dialog box buttons that close the question when pressed.
Begin by importing the rui-dialog-box
module into your application.
Let’s look at an example of an rui-question
used to prompt the user if they wish to log out.
First, let’s define a showLogOutQuestion
boolean property in the TypeScript, initializing that to a value of false. This property will control when the question displays.
Now let’s add the rui-question
element to the HTML:
- We set the
titleText
to an actual question: “Do you wish to log out?”. - We bind the
showQuestion
trigger property to theshowLogOutQuestion
boolean backing property in the TypeScript. - We reset the
showLogOutQuestion
property in therui-question-show-question-change
event handler. If we didn’t do this, the question would only ever display once. - We specify the
logOutQuestionClose()
method as the handler for therui-question-close
event that fires when the user answers the question.- The
detail
field in $event will include the name of the button that the user pressed (or “Escape” if the user pressed the Escape key).
- The
- The dialog box buttons provide all answers to the question: “Log Out” and “Cancel” in this case.
- We nest the dialog box buttons within a div that has the
question-buttons
CSS class applied. If you don’t nest the buttons like this, they won’t work as expected. - The “Log Out” button uses primary styling since this is the primary action for the dialog.
- The “Cancel” button uses secondary styling.
- We nest the dialog box buttons within a div that has the
In this example, we use a button in the view to trigger the display of the question. This button’s click event handler simply sets the showLogOutQuestion boolean property to a value of true when pressed, which in turn displays the question.
Here is the logOutQuestionClose()
method that we specified as the event handler for the question’s rui-question-close
event. The event parameter includes a detail
field that contains either “Log Out”, “Cancel”, or “Escape”, depending on whether the user pressed a question button or pressed the Escape key. In this example we call the logOut()
method if the user’s answer was “Log Out”. We do nothing if the user pressed the “Cancel” button or the Escape key.
Here’s an example of a question showing a destructive button. We set buttonStyle="destructive"
on the “Delete Record” button since pressing that button results in a significant, destructive action.
Implementing a dialog box
Begin by importing the rui-dialog-box module into your application.
Let’s look at an example of an rui-dialog-box
used to prompt for a user’s first and last name.
First, let’s define a showDialogBox
boolean property in the TypeScript, initializing that to a value of false. This property will control when the dialog box displays.
Now let’s add the rui-dialog-box
element to the HTML:
- We set the
titleText
to “User Information”. - We bind the
showDialog
trigger property to theshowDialogBox
boolean backing property in the TypeScript. - We reset the
showDialogBox
property in therui-dialog-box-show-dialog-change
event handler. If we didn’t do this, the dialog box would only ever display once. - We specify the
dialogBoxClose()
method as the handler for therui-dialog-box-close
event that fires when the user closes the dialog box.- The
detail
field in $event will include the name of the button that the user pressed (or “Escape” if the user pressed the Escape key).
- The
- We nest the dialog box content between the rui-dialog-box start and end tags. The content in this example is a form with 2 fields, along with their validation errors.
- The “Save” and “Cancel” dialog box buttons allow the user to specify how to process the input values.
- We nest the dialog box buttons within a div that has the
dialog-box-buttons
CSS class applied. If you don’t nest the buttons like this, they won’t work as expected. - The “Save” button uses primary styling since this is the primary action for the dialog.
- The “Cancel” button uses secondary styling.
- We nest the dialog box buttons within a div that has the
In this example, we use a button to trigger the display of the dialog box. This button’s click event handler simply sets the showDialog boolean property to a value of true when pressed, which in turn displays the dialog box.
Here is the dialogBoxClose()
method that we specified as the event handler for the dialog box’s rui-dialog-box-close event. The event parameter’s detail field contains a value of “Save”, “Cancel”, or “Escape”, depending on whether the user pressed a dialog box button or pressed the Escape key. In this example we call the updateSettings() method if the user’s pressed the “Save” button, and we log a console message if the user pressed the “Cancel” button or the Escape key.
Delaying the dialog box close
In some cases, you may need to perform some extra handling before the dialog closes. For example, if your application needs to complete server-side validation asynchronously, you must wait for that to complete before allowing the dialog box to close.
To do this, bind the dialog box’s canClose
property to a backing value in your controller that has a value of false. Define an event handler for the rui-dialog-box-before-close
event.
If the interim process is time consuming, use the canClosePollCount
property to set the number of times the component polls the canClose
value for true before quitting. The dialog box checks the canClose value every 100 milliseconds for the number of times specified in the canClosePollCount property, stopping once canClose is set to true.
In the dialogBeforeClose
event handler, execute any code needed to test if the dialog can close, updating the backing value appropriately.
Angular wrapper development
Wrapper reference
jha-question
Displays a simple question or message in a popup window at larger screen sizes and in a slide up at mobile size, with one or more buttons. No content displays other than the title and buttons.
Name | Type | Default | Description |
---|---|---|---|
jhaTitle | string | '' | The short question or message displayed in the dialog box header |
jhaShowQuestion | boolean | false | This is a boolean trigger property. Bind this property to a backing boolean value in your controller, then set the backing value to true whenever you want to display the question. |
jhaClose | event | Event fired when the user clicks a dialog box button or presses the Escape key. In each of those cases the dialog box closes and the jhaClose event fires. The event handler should accept a string parameter; this contains the text of the button pressed by the user, or the word “Escape” if the user pressed the Escape key, in which case you should respond to that as if the user pressed the least destructive button option presented by the dialog. |
jha-dialog-box
Displays information and/or inputs in a popup window, with one or more buttons
Name | Type | Default | Description |
---|---|---|---|
jhaTitle | string | '' | The title displayed in the dialog box header |
jhaDialogWidth | string | 'Medium' | This determines the width of the dialog box. One of:
|
jhaShowDialog | boolean | false | This is a boolean trigger property. Use two-way binding to bind this property to a boolean value in your TypeScript, then set the backing value to true whenever you want to display the dialog box. You must use two-way binding to set this value for it to work as expected. |
jhaHideDialog | boolean | false | This is a boolean trigger property. Use two-way binding to bind this property to a boolean value in your TypeScript, then set the backing value to true whenever you want to hide the dialog box. You must use two-way binding to set this value for it to work as expected. The dialog will close when the user presses one of the dialog box buttons. However, if you have a scenario where you need to programmatically close the dialog, set this property to true. |
jhaBeforeClose | event | Event fired when the user clicks a dialog box button or presses the Escape key. The event will fire regardless of whether the jhaCanClose property is set to true or false. You can use this event to do any final validation or cleanup before the jhaClose event is fired and the dialog is closed. | |
jhaClose | event | Event fired when the user clicks a dialog box button or presses the Escape key. In each of those cases the dialog box closes and the jhaClose event fires. The event handler should accept a string parameter; this contains the text of the button pressed by the user, or the word “Escape” if the user pressed the Escape key, in which case you should respond to that as if the user pressed the least destructive button option presented by the dialog. | |
jhaCanClose | boolean | true | This is a boolean property telling the component whether or not the dialog can close when a button or the Escape key is pressed. Binding this property to false will fire the jhaBeforeClose event, but not the jhaClose event, and will keep the dialog from closing. |
jhaCanClosePollCount | number | 0 | If this property is set to a number greater than 0, the dialog box component will poll every 100 milliseconds to test if jhaCanClose is set to true. If your product has a long service call fired to validate form elements within the dialog asynchronously, you can set this to a high value to keep polling for an updated jhaCanClose value. |
jhaOnShow | event | Fires right before the dialog box shows. | |
jhaOnShown | event | Fires right after the dialog box shows. | |
jhaOnHide | event | Fires right before the dialog box hides. | |
jhaOnHidden | event | Fires right after the dialog box hides. |
jha-dialog-box-button
Adds a button to jha-dialog-box or jha-question. This button closes the dialog box with a specific context when pressed.
Name | Type | Default | Description |
---|---|---|---|
jhaText | string | '' | The text displayed in the button. This is also the value returned in the jha-dialog-box’s jhaClose event when the user presses this button. |
jhaButtonStyle | string | 'Secondary' | Specifies the styling displayed for the button: One of “Primary”, “Secondary”, or “Destructive”
|
jhaTooltip | string | '' | Tooltip displayed when the mouse hovers over the button |
jhaIsDisabled | boolean | false | Specifies whether the button is disabled. |
Implementing a question
Use jha-question
to show a simple message or ask a simple question. The question includes a title (the message or question) and one or more dialog box buttons that close the question when pressed.
Begin by including noty in your package.json, where x.y.z is the currently supported version number for this framework specified here. Use npm install to install this framework.
Once the package has been installed, add it to your scripts bundle in the angular.json file.
Begin by importing the JhaDialogBoxModule
module into your application.
Let’s define a showLogOutQuestion
boolean property in the TypeScript, initializing that to a value of false. This property will control when the question displays.
Next add the jha-question element to the HTML, prompting the user if they wish to log out. The question includes a “Log Out” button that uses primary styling since this is the primary action for the dialog, and a “Cancel” button that uses secondary styling by default. Use two-way binding to bind the jhaShowQuestion property to the backing showLogOutQuestion boolean property in the TypeScript. (Without two-way binding, the popup would only display once.) We specify the logOutQuestionClose() event to be called when the user answers the question. Pass $event as the event handler parameter; this string value will reflect the name of the button that the user pressed (or “Escape” if the user pressed the Escape key). Add the dialog box buttons within the jha-question start and close tags.
In this example, we use a button in the view to trigger the display of the question. This button’s click event handler simply sets the showLogOutQuestion
boolean property to a value of true when pressed, which in turn displays the question.
Here is the logOutQuestionClose()
method that we specified as the event handler for the question’s jhaClose
event. The dialogResult
parameter reflects either “Log Out”, “Cancel”, or “Escape”, depending on whether the user pressed a button or pressed the Escape key. In this example we call the logOut()
method if the user’s answer was “Log Out”. We do nothing if the user pressed the “Cancel” button or the Escape key.
Here’s an example of a question showing a destructive button. We set jhaButtonStyle="destructive"
on the “Delete Record” button since pressing that button results in a significant, destructive action.
Implementing a dialog box
Begin by importing the JhaDialogBoxModule module into your application.
Let’s define a showDialogBox
boolean property in the TypeScript, initializing that to a value of false. This property will control when the dialog box displays.
Next add the jha-dialog-box element to the HTML. The dialog box includes a “Save” button that uses primary styling since this is the primary action for the dialog, and a “Cancel” button that uses secondary styling by default. Use two-way binding to bind the jhaShowDialog property to the backing showDialog boolean property in the TypeScript. (Without two-way binding, the popup would only display once.) Specify the dialogClosed() event to be called when the user closes the dialog. Pass $event as the event handler parameter; this string value will reflect the name of the button that the user pressed (or “Escape” if the user pressed the Escape key). Add the dialog box content and dialog box buttons within the jha-dialog-box start and close tags.
In this example, we use a button to trigger the display of the dialog box. This button’s click event handler simply sets the showDialog boolean property to a value of true when pressed, which in turn displays the dialog box.
Here is the dialogClosed()
method that we specified as the event handler for the dialog box’s jhaClose event. The dialogResult parameter reflects either “Save”, “Cancel”, or “Escape”, depending on whether the user pressed a button or pressed the Escape key. In this example we call the updateSettings() method if the user’s answer was “Save”, and we log a console message if the user pressed the “Cancel” button or the Escape key.
Delaying the dialog box close
In some cases, you may need to perform some extra handling before the dialog closes. For example, if your application needs to complete server-side validation asynchronously, you must wait for that to complete before allowing the dialog box to close.
To do this, bind the dialog box’s jhaCanClose
property to a backing value in your controller that has a value of false. Define an event handler for the jhaBeforeClose
event.
If the interim process is time consuming, use the jhaCanClosePollCount
property to set the number of times the component polls the jhaCanClose
value for true before quitting. The dialog box checks the jhaCanClose value every 100 milliseconds for the number of times specified in the jhaCanClosePollCount property, stopping once canClose is set to true.
In the dialogBeforeClose
event handler, execute any code needed to test if the dialog can close, updating the backing value appropriately.
Design
There are two flavors of dialog boxes:
- The Dialog Box component displays a header at the top with a title, a button bar at the bottom with at least one button, and content between the header and the button bar.
- The Question component is a simpler version of the dialog box component, with only the header and the button bar. The title in the header asks a question, and the buttons in the button bar answer the answer.
- At mobile size, the question displays as a slide-up.
All dialog boxes display a translucent modal backdrop behind them, which darkens the background. Add this component first. Resize it to cover the entire view. Lock the modal backdrop so you can drag other components on top of it.
Next, decide whether you’re displaying a dialog box or a question:
- If you’re displaying a dialog box:
- Drag a dialog box component onto the modal backdrop and resize it appropriately.
- Change the title in the header to an appropriate value.
- Drag text buttons onto the button bar and change their text appropriately. These buttons are right justified in the button bar and are separated by 7 pixels of horizontal space. Use primary, secondary, and destructive buttons appropriately. Vertically center these buttons.
- Add content to the center portion of the dialog box.
- If you’re displaying a question at tablet or desktop size:
- Drag a question component onto the modal backdrop and resize it appropriately.
- Change the title in the header to an appropriate value.
- Drag text buttons onto the button bar and change their text appropriately. These buttons are right justified in the button bar and are separated by 7 pixels of horizontal space. Use primary, secondary, and destructive buttons appropriately. Vertically center these buttons.
- If you’re displaying a question at mobile size:
- Drag a Slide Up component onto the bottom of the modal backdrop and resize it appropriately. The slide up always displays at the bottom of the screen.
- Change the title in the slide up component to an appropriate value.
- Drag slide up button components onto the slide up component and change their text appropriately. These buttons display below the slide up component’s title and are separated by 5 pixels of vertical space. Use primary, secondary, and destructive buttons appropriately.
Figma design
Dev Component | Design Component Name |
---|---|
Modal backdrop | RUI / Modal / Backdrop |
Dialog box | RUI / Modal / Dialog Box |
Question | RUI / Modal / Question |
Text button | RUI / Buttons / Button Available values for the Style property:
|
Slide up | RUI / Modal / Slide Up |
Slide up button | RUI / Modal / Slide Up Button Available values for the Style property:
|
Adobe XD design
- Sample App - Dialog Box
- Sample App - Question
- Sample app - Question - Mobile
- Sample app - Question - Mobile - Destructive
Dev Component | Design Component Name |
---|---|
Modal shield | JHA / Modal / Shield |
Dialog box | JHA / Modal / Dialog Box |
Question | JHA / Modal / Question |
Primary text button | JHA / Buttons / Button / Primary |
Secondary text button | JHA / Buttons / Button / Secondary |
Destructive text button | JHA / Buttons / Button / Destructive |
Slide up | JHA / Modal / Slide Up |
Slide up button - primary | JHA / Modal / Slide Up Button / Primary |
Slide up button - secondary | JHA / Modal / Slide Up Button / Secondary |
Slide up button - destructive | JHA / Modal / Slide Up Button / Destructive |