# Custom Dialog Box
A custom dialog box is a dialog box you customize by using APIs of the **CustomDialogController** class. You can set the style and content to your preference for a custom dialog box.
> **NOTE**
>
> The APIs of this module are supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.
## APIs
CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, autoCancel?: boolean, alignment?: DialogAlignment, offset?: Offset, customStyle?: boolean, gridCount?: number, maskColor?: ResourceColor, openAnimation?: AnimateParam, closeAniamtion?: AnimateParam, showInSubWindow?: boolean})
**Parameters**
| Name | Type | Mandatory | Description |
| ---------------------- | ---------------------------------------- | ------------------------- | ---------------------- |
| builder | [CustomDialog](../../quick-start/arkts-dynamic-ui-elememt-building.md#customdialog) | Yes | Constructor of the custom dialog box content. |
| cancel | () => void | No | Callback invoked when the dialog box is closed after the overlay exits. |
| autoCancel | boolean | No | Whether to allow users to click the overlay to exit.
Default value: **true** |
| alignment | [DialogAlignment](ts-methods-alert-dialog-box.md#dialogalignment) | No | Alignment mode of the dialog box in the vertical direction.
Default value: **DialogAlignment.Default** |
| offset | [Offset](ts-types.md#offset) | No | Offset of the dialog box relative to the alignment position.|
| customStyle | boolean | No | Whether to use a custom style for the dialog box.
Default value: **false**, which means that the dialog box automatically adapts its width to the grid system and its height to the child components; the maximum height is 90% of the container height; the rounded corner is 24 vp. |
| gridCount8+ | number | No | Number of [grid columns](../../ui/ui-ts-layout-grid-container-new.md) occupied by the dialog box.
The default value is 4, and the maximum value is the maximum number of columns supported by the system. If this parameter is set to an invalid value, the default value is used.|
| maskColor10+ | [ResourceColor](ts-types.md#resourcecolor) | No | Custom mask color.
Default value: **0x33000000** |
| openAnimation10+ | [AnimateParam](ts-explicit-animation.md#animateparam) | No | Parameters for defining the open animation of the dialog box.
**NOTE**
If **iterations** is set to an odd number and **playMode** is set to **Reverse**, the dialog box will not be displayed when the animation ends. |
| closeAniamtion10+| [AnimateParam](ts-explicit-animation.md#animateparam) | No | Parameters for defining the close animation of the dialog box. |
| showInSubWindow10+| boolean | No | Whether to display a dialog box in a subwindow.
Default value: **false**, indicating that the dialog box is not displayed in the subwindow
**NOTE**
A dialog box whose **showInSubWindow** attribute is **true** cannot trigger the display of another dialog box whose **showInSubWindow** attribute is also **true**. |
## CustomDialogController
### Objects to Import
```ts
dialogController : CustomDialogController = new CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, autoCancel?: boolean})
```
> **NOTE**
>
> **CustomDialogController** is valid only when it is a member variable of the **@CustomDialog** and **@Component** decorated struct and is defined in the **@Component** decorated struct. For details, see the following example.
### open()
open(): void
Opens the content of the custom dialog box. If the content has been displayed, this API does not take effect.
### close
close(): void
Closes the custom dialog box. If the dialog box is closed, this API does not take effect.
## Example
```ts
// xxx.ets
@CustomDialog
struct CustomDialogExample {
@Link textValue: string
@Link inputValue: string
controller: CustomDialogController
cancel: () => void
confirm: () => void
build() {
Column() {
Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })
TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
.onChange((value: string) => {
this.textValue = value
})
Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button('cancel')
.onClick(() => {
this.controller.close()
this.cancel()
}).backgroundColor(0xffffff).fontColor(Color.Black)
Button('confirm')
.onClick(() => {
this.inputValue = this.textValue
this.controller.close()
this.confirm()
}).backgroundColor(0xffffff).fontColor(Color.Red)
}.margin({ bottom: 10 })
}
}
}
@Entry
@Component
struct CustomDialogUser {
@State textValue: string = ''
@State inputValue: string = 'click me'
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({
cancel: this.onCancel,
confirm: this.onAccept,
textValue: $textValue,
inputValue: $inputValue
}),
cancel: this.existApp,
autoCancel: true,
alignment: DialogAlignment.Default,
offset: { dx: 0, dy: -20 },
gridCount: 4,
customStyle: false
})
aboutToDisappear() {
delete this.dialogController,
this.dialogController = undefined
}
onCancel() {
console.info('Callback when the first button is clicked')
}
onAccept() {
console.info('Callback when the second button is clicked')
}
existApp() {
console.info('Click the callback in the blank area')
}
build() {
Column() {
Button(this.inputValue)
.onClick(() => {
if (this.dialogController != undefined) {
this.dialogController.open()
}
}).backgroundColor(0x317aff)
}.width('100%').margin({ top: 5 })
}
}
```
![en-us_image_0000001212058470](figures/en-us_image_0000001212058470.gif)