1# Global Custom Dialog Box Independent of UI Components (Recommended) 2 3 4Due to the restrictions of [CustomDialogController](../reference/apis-arkui/arkui-ts/ts-methods-custom-dialog-box.md#customdialogcontroller), which does not support dynamic creation or refresh, for more complex use cases, you are advised to use the [openCustomDialog](../reference/apis-arkui/js-apis-arkui-UIContext.md#opencustomdialog12) API provided by the **PromptAction** object obtained from **UIContext** to implement a custom dialog box. 5 6 7## Opening and Closing a Custom Dialog Box 8 91. Create a **ComponentContent** instance. 10 11 **ComponentContent** is used to define the content of the custom dialog box. **wrapBuilder(buildText)** encapsulates the custom component, and **new Params(this.message)** is the input parameter for the custom component, which can be omitted or passed in with basic data types. 12 13 ```ts 14 private contentNode: ComponentContent<Object> = new ComponentContent(this.ctx, wrapBuilder(buildText), new Params(this.message)); 15 ``` 16 172. Open the custom dialog box. 18 19 Call **openCustomDialog** to open the custom dialog box, whose **customStyle** is set to **true** by default, meaning that the dialog box is styled entirely based on the **contentNode** settings you provide. 20 21 ```ts 22 this.ctx.getPromptAction().openCustomDialog(this.contentNode, this.options) 23 .then(() => { 24 console.info('OpenCustomDialog complete.') 25 }) 26 .catch((error: BusinessError) => { 27 let message = (error as BusinessError).message; 28 let code = (error as BusinessError).code; 29 console.error(`OpenCustomDialog args error code is ${code}, message is ${message}`); 30 }) 31 ``` 32 333. Close the custom dialog box. 34 35 Call **closeCustomDialog**, which requires the ComponentContent corresponding to the dialog box to be closed. To set a close method within the dialog box, follow the complete sample to encapsulate this functionality into a static method. 36 37 To release the corresponding ComponentContent after the dialog box is closed, call the **dispose** API of the ComponentContent. 38 39 ```ts 40 this.ctx.getPromptAction().closeCustomDialog(this.contentNode) 41 .then(() => { 42 console.info('CloseCustomDialog complete.') 43 }) 44 .catch((error: BusinessError) => { 45 let message = (error as BusinessError).message; 46 let code = (error as BusinessError).code; 47 console.error(`CloseCustomDialog args error code is ${code}, message is ${message}`); 48 }) 49 ``` 50 51## Updating the Content of a Custom Dialog Box 52 53ComponentContent has the same usage constraints as [BuilderNode](../reference/apis-arkui/js-apis-arkui-builderNode.md) and does not support custom components using decorators such as [@Reusable](../quick-start/arkts-create-custom-components.md#basic-structure-of-a-custom-component), [@Link](../quick-start/arkts-link.md), [@Provide](../quick-start/arkts-provide-and-consume.md), and [@Consume](../quick-start/arkts-provide-and-consume.md) to synchronize the state between the page where the dialog box pops up and the custom component in ComponentContent. Therefore, if you need to update the content of the custom component in the dialog box, use the **update** API provided by ComponentContent. 54```ts 55this.contentNode.update(new Params('update')) 56``` 57 58## Updating the Attributes of a Custom Dialog Box 59 60You can dynamically update the attributes of the dialog box through **updateCustomDialog**. Currently, the following attributes are supported: **alignment**, **offset**, **autoCancel**, and **maskColor**. 61Note that when attributes are updated, those unset will be restored to their default values. For example, if you initially set **{ alignment: DialogAlignment.Top, offset: { dx: 0, dy: 50 } }** and then update it to **{ alignment: DialogAlignment.Bottom }**, the initially set **offset: { dx: 0, dy: 50 }** will not be retained; the offset will be restored to the default value. 62```ts 63this.ctx.getPromptAction().updateCustomDialog(this.contentNode, options) 64 .then(() => { 65 console.info('UpdateCustomDialog complete.') 66 }) 67 .catch((error: BusinessError) => { 68 let message = (error as BusinessError).message; 69 let code = (error as BusinessError).code; 70 console.error(`UpdateCustomDialog args error code is ${code}, message is ${message}`); 71 }) 72``` 73 74## Sample 75 76```ts 77// PromptActionClass.ts 78import { BusinessError } from '@kit.BasicServicesKit'; 79import { ComponentContent, window } from '@kit.ArkUI'; 80import { UIContext } from '@ohos.arkui.UIContext'; 81 82export class PromptActionClass { 83 static ctx: UIContext; 84 static contentNode: ComponentContent<Object>; 85 static options: Object; 86 87 static setContext(context: UIContext) { 88 this.ctx = context; 89 } 90 91 static setContentNode(node: ComponentContent<Object>) { 92 this.contentNode = node; 93 } 94 95 static setOptions(options: Object) { 96 this.options = options; 97 } 98 99 static openDialog() { 100 if (this.contentNode !== null) { 101 this.ctx.getPromptAction().openCustomDialog(this.contentNode, this.options) 102 .then(() => { 103 console.info('OpenCustomDialog complete.') 104 }) 105 .catch((error: BusinessError) => { 106 let message = (error as BusinessError).message; 107 let code = (error as BusinessError).code; 108 console.error(`OpenCustomDialog args error code is ${code}, message is ${message}`); 109 }) 110 } 111 } 112 113 static closeDialog() { 114 if (this.contentNode !== null) { 115 this.ctx.getPromptAction().closeCustomDialog(this.contentNode) 116 .then(() => { 117 console.info('CloseCustomDialog complete.') 118 }) 119 .catch((error: BusinessError) => { 120 let message = (error as BusinessError).message; 121 let code = (error as BusinessError).code; 122 console.error(`CloseCustomDialog args error code is ${code}, message is ${message}`); 123 }) 124 } 125 } 126 127 static updateDialog(options: Object) { 128 if (this.contentNode !== null) { 129 this.ctx.getPromptAction().updateCustomDialog(this.contentNode, options) 130 .then(() => { 131 console.info('UpdateCustomDialog complete.') 132 }) 133 .catch((error: BusinessError) => { 134 let message = (error as BusinessError).message; 135 let code = (error as BusinessError).code; 136 console.error(`UpdateCustomDialog args error code is ${code}, message is ${message}`); 137 }) 138 } 139 } 140} 141``` 142 143```ts 144// Index.ets 145import { ComponentContent } from '@kit.ArkUI'; 146import { PromptActionClass } from './PromptActionClass'; 147 148class Params { 149 text: string = "" 150 151 constructor(text: string) { 152 this.text = text; 153 } 154} 155 156@Builder 157function buildText(params: Params) { 158 Column() { 159 Text(params.text) 160 .fontSize(50) 161 .fontWeight(FontWeight.Bold) 162 .margin({ bottom: 36 }) 163 Button('Close') 164 .onClick(() => { 165 PromptActionClass.closeDialog() 166 }) 167 }.backgroundColor('#FFF0F0F0') 168} 169 170@Entry 171@Component 172struct Index { 173 @State message: string = "hello" 174 private ctx: UIContext = this.getUIContext(); 175 private contentNode: ComponentContent<Object> = 176 new ComponentContent(this.ctx, wrapBuilder(buildText), new Params(this.message)); 177 178 aboutToAppear(): void { 179 PromptActionClass.setContext(this.ctx); 180 PromptActionClass.setContentNode(this.contentNode); 181 PromptActionClass.setOptions({ alignment: DialogAlignment.Top, offset: { dx: 0, dy: 50 } }); 182 } 183 184 build() { 185 Row() { 186 Column() { 187 Button("open dialog and update options") 188 .margin({ top: 50 }) 189 .onClick(() => { 190 PromptActionClass.openDialog() 191 192 setTimeout(() => { 193 PromptActionClass.updateDialog({ 194 alignment: DialogAlignment.Bottom, 195 offset: { dx: 0, dy: -50 } 196 }) 197 }, 1500) 198 }) 199 Button("open dialog and update content") 200 .margin({ top: 50 }) 201 .onClick(() => { 202 PromptActionClass.openDialog() 203 204 setTimeout(() => { 205 this.contentNode.update(new Params('update')) 206 }, 1500) 207 }) 208 } 209 .width('100%') 210 .height('100%') 211 } 212 .height('100%') 213 } 214} 215``` 216