Early Adopter's guide to Umbraco v14 - Custom Modals
Tags: umbraco
Published: 2024-02-20 10:41:16

In our last post we looked at the verious ways you can open sidebars and modal dialogs in Umbraco v14, but we only looked at opening the dialogs that are already defined for us. 

Here we are going to look at creating our own custom dialogs. 

## Anatomy of a custom modal, 

A custom dialog consits of a number of things. 

- *Modal Data* this is the model for data passed to our modal.
- *Modal Value* this is the model for data being returned by our modal
- *A Modal element* this is the web component shown in the modal.
- *Modal Token* this is the token that makes our modal accessible in the back office (via the modal manager).

### Modal Data and values. 
The modalData model and modal value models define what is passed to and what is returned from our modal. 

For our example we are passing a headline and some content.

```ts
export interface TimeCustomModalData {
    headline: string;
    content: string;
}
```

And returning some content.

```ts
export interface TimeCustomModalValue {
    content: string 
}
```

### Modal Token
The modal token is the token name which will let other code call our modal. 

```ts
export const TIME_CUSTOM_MODAL =
  new UmbModalToken<TimeCustomModalData, TimeCustomModalValue>(
    "time.custom.modal",
    {
        modal: {
            type: 'sidebar',
            size: 'medium'
        }
    }
);
```

The token needs to understand what is passed to and returned from the modal, so thats why we define the data and value models first.

Also the token is where we set what type of box we want to open. 

- 'sidebar' opens at the side: 

![A Sidebar dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccvjpp881qre55m2lfiw.png)

- 'dialog' opens a dialog (overlay) box.

![A Dialog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edzv1k3y0y2cde0aum0z.png)

### Modal Element
The modal element is very similar to how we do other elements, except we extend `UmbModalBaseElement`

```ts
@customElement('time-custom-modal')
export class TimeCustomModalElement extends 
    UmbModalBaseElement<TimeCustomModalData, TimeCustomModalValue> 
```

within the element we can access the data that is passed to the modal via the data object.

#### Reading data passed to modal

so we can set our headline from the data passed:

```html
<umb-body-layout 
    .headline=${this.data?.headline ?? 'Custom dialog'}>
```

#### Returning data

Similary we can set the return value via the `updateValue` method which is part of the `UmbModalBaseElement` class.

So if we have a text area for content: 

```html
<uui-textarea
  label="content" 
  rows=10
  .value=${this.data?.content}
  @input=${this.#contentChange}></uui-textarea>
```

We can update the value when it changes: 

```ts
#contentChange(event: UUIInputEvent) {
  this.updateValue({content: event.target.value.toString()});
}
```

### Manifest
And finally only because its always required we must not forget to add a manfiest for the dialog. 

```ts
const modals: Array<ManifestModal> = [
    {
        type: 'modal',
        alias: 'time.custom.modal',
        name: 'Time custom modal',
        js: () => import('./custom-modal-element.js')
    }
];
```

---

> As with other posts the code is avalible in the demo repo : https://github.com/KevinJump/TimeDashboard/tree/master/TimeDashboard.Client/assets/src/dialogs