Modal Dialog Component
Dialogs opened from code through the modal service. They are kept on a stack, the call returns a promise, and a dialog can hold a @dynamicforms/vue-forms form.
Basic Usage
A message dialog, a yes/no confirmation, a form dialog with validation and sized dialogs, opened through the modal service. A <modal-view /> must be mounted once, in the app root - see Installation.
Modal Dialog Examples
The modal system provides several types of dialogs that can be triggered programmatically:
Message Dialog
Simple dialog with information message and a close button.
Confirmation Dialog
Dialog with Yes/No options for confirmation.
Form Dialog
Dialog with a form including validation.
Dialog Sizes
Dialogs with different sizes (small, medium, large, x-large); the inputs in the dialog change its title, icon, title color and size.
Features
- One dialog at a time - a
modal.*call made while a dialog is open hides that dialog without closing it and shows the new one. The hidden dialog is shown again when the new one closes. - Message dialogs -
modal.message('Title', 'Text')shows a dialog with a singlecloseaction. The demo's message is Markdown (MdString) with a CSS class added throughRenderableValue. - Confirmations -
modal.yesNo('Title', 'Text')showsyes/noactions and resolves to whichever was clicked. - Form dialogs - a
@dynamicforms/vue-formsGrouppassed asoptions.formis the dialog body. ItsActionmembers (e.g.submit,cancel) are the dialog's buttons, and the promise resolves with the name of the one that was clicked; the dialog adds its owncloseonly where none of them is drawn. A vue-formsActionand the@dynamicforms/vuetify-inputsActionare both drawn; the latter adds the responsive render options. EachFieldis drawn as the component infield.extra.component, or as a<df-input>where it names none, with the field's label. A nestedGrouporListmember is not drawn - see<modal-view>. - Error messages - the form dialog's email field has a pattern validator with the code
invalid_email. The documentation app installs vuetify-inputs with anerrorTextthat renders that code from a markdown message - see Translating errors. - Custom components -
modal.custom('Title', component, componentProps)renders a component, or a component named inoptions.componentsor registered globally, as the dialog body. - Sizing -
options.sizeis'small','medium','large'or'x-large'; each is fullscreen below its own breakpoint.'default'sizes the dialog to its content. - Changing an open dialog - the sized dialogs' body holds an input for the title and selects for the icon, the title color and the size. The demo writes their values to the dialog's
props.title,props.icon,props.colorandprops.size- see Changing an open dialog.
Changing an open dialog
The sized dialogs write the values of their inputs to the dialog's props, the DialogProps of the promise modal.message() returns:
ts
// Dialog sizes: the inputs in the dialog body write the title, the icon, the title color and the size to the open
// dialog's props
async function showSizedDialog(size: DialogSize) {
const titleField = new Field({ value: 'Dialog Size Example', label: 'Dialog title' });
const iconField = new Field({ value: 'mdi-resize', label: 'Icon' });
const colorField = new Field({ value: 'none', label: 'Title color' });
const sizeField = new Field({ value: size, label: 'Dialog size' });
const icons = ['mdi-resize', 'mdi-star', 'mdi-heart', 'mdi-rocket', 'mdi-palette'];
// 'none' sets no color: the title bar keeps its default
const colors = ['none', 'primary', 'secondary', 'success', 'info', 'warning', 'error'];
const colorOf = (name: string) => (name === 'none' ? undefined : name);
const column = (cols: Record<string, number>, input: SimpleComponentDef): SimpleComponentDef => ({
componentName: 'v-col',
componentProps: cols,
children: [input],
});
const dialog = modal.message(
titleField.value,
{
componentName: 'v-row',
children: [
column({ cols: 12, sm: 8 }, { componentName: 'df-input', componentProps: { control: titleField } }),
column(
{ cols: 12, sm: 4 },
{
componentName: 'df-select',
componentProps: {
control: iconField,
choices: icons.map((icon) => ({ id: icon, text: icon.slice(4), icon })),
allowNull: false,
},
},
),
column(
{ cols: 12, sm: 6 },
{
componentName: 'df-select',
componentProps: {
control: colorField,
choices: colors.map((color) => ({ id: color, text: color })),
allowNull: false,
},
},
),
column(
{ cols: 12, sm: 6 },
{
componentName: 'df-select',
componentProps: {
control: sizeField,
choices: dialogSizes.map((name) => ({ id: name, text: name })),
allowNull: false,
},
},
),
],
},
{ icon: iconField.value, color: colorOf(colorField.value), size },
);
const stop = watch(
() => [titleField.value, iconField.value, colorField.value, sizeField.value] as const,
([title, icon, color, dialogSize]) => {
dialog.props.title = title;
dialog.props.icon = icon;
dialog.props.color = colorOf(color);
dialog.props.size = dialogSize;
},
);
dialogResult.value = await dialog;
stop();
}Full method signatures, CloseablePromise, ModalOptions, and DialogSize are documented in the modal service API reference.
See also
- Template Dialog - a dialog declared in a template with
<df-modal>. - API Reference - the props, methods and options of the
modalservice,<df-modal>,<modal-view>andDialogSize.
