1# Updating Widget Content Through the router or call Event 2 3 4On the widget page, the **postCardAction** API can be used to trigger a router or call event to start a UIAbility, which then updates the widget content. The following is an example of this widget update mode. 5 6> **NOTE** 7> 8> This topic describes development for dynamic widgets. For static widgets, see [FormLink](../reference/arkui-ts/ts-container-formlink.md). 9 10## Updating Widget Content Through the router Event 11 12- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the router event to start the UIAbility. 13 14 ```ts 15 let storage = new LocalStorage(); 16 @Entry(storage) 17 @Component 18 struct WidgetCard { 19 @LocalStorageProp('detail') detail: string = 'init'; 20 21 build() { 22 Column() { 23 Button ('Redirect') 24 .margin('20%') 25 .onClick(() => { 26 console.info('postCardAction to EntryAbility'); 27 postCardAction(this, { 28 'action': 'router', 29 'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed. 30 'params': { 31 'detail': 'RouterFromCard' 32 } 33 }); 34 }) 35 Text(`${this.detail}`).margin('20%') 36 } 37 .width('100%') 38 .height('100%') 39 } 40 } 41 ``` 42 43- In the **onCreate()** or **onNewWant()** lifecycle callback of the UIAbility, use the input parameter **want** to obtain the ID (**formID**) and other information of the widget, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API to update the widget. 44 45 ```ts 46 import UIAbility from '@ohos.app.ability.UIAbility'; 47 import formBindingData from '@ohos.app.form.formBindingData'; 48 import formProvider from '@ohos.app.form.formProvider'; 49 import formInfo from '@ohos.app.form.formInfo'; 50 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 51 import Want from '@ohos.app.ability.Want'; 52 import Base from '@ohos.base' 53 54 export default class EntryAbility extends UIAbility { 55 // If the UIAbility is started for the first time, onCreate is triggered after the router event is received. 56 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 57 this.handleFormRouterEvent(want); 58 } 59 60 handleFormRouterEvent(want: Want) { 61 console.info('Want:' + JSON.stringify(want)); 62 if (want.parameters && want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) { 63 let curFormId = JSON.stringify(want.parameters[formInfo.FormParam.IDENTITY_KEY]); 64 let message: string = JSON.parse(JSON.stringify(want.parameters.params)).detail; 65 console.info(`UpdateForm formId: ${curFormId}, message: ${message}`); 66 let formData: Record<string, string> = { 67 "detail": message + ': UIAbility.', // It matches the widget layout. 68 }; 69 let formMsg = formBindingData.createFormBindingData(formData) 70 formProvider.updateForm(curFormId, formMsg).then((data) => { 71 console.info('updateForm success.' + JSON.stringify(data)); 72 }).catch((error: Base.BusinessError) => { 73 console.error('updateForm failed:' + JSON.stringify(error)); 74 }) 75 } 76 } 77 // If the UIAbility is running in the background, onNewWant is triggered after the router event is received. 78 onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) { 79 console.info('onNewWant Want:' + JSON.stringify(want)); 80 if (want.parameters && want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) { 81 let curFormId = JSON.stringify(want.parameters[formInfo.FormParam.IDENTITY_KEY]); 82 let message: string = JSON.parse(JSON.stringify(want.parameters.params)).detail; 83 console.info(`UpdateForm formId: ${curFormId}, message: ${message}`); 84 let formData: Record<string, string> = { 85 "detail": message +': onNewWant UIAbility.', // Matches the widget layout. 86 }; 87 let formMsg = formBindingData.createFormBindingData(formData) 88 formProvider.updateForm(curFormId, formMsg).then((data) => { 89 console.info('updateForm success.' + JSON.stringify(data)); 90 }).catch((error: Base.BusinessError) => { 91 console.error('updateForm failed:' + JSON.stringify(error)); 92 }) 93 } 94 } 95 96 ... 97 } 98 ``` 99 100## Updating Widget Content Through the call Event 101 102- When using the call event of the **postCardAction** API, the value of **formId** must be updated in the **onAddForm** callback of the FormExtensionAbility. 103 104 ```ts 105 import formBindingData from '@ohos.app.form.formBindingData'; 106 import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; 107 import Want from '@ohos.app.ability.Want'; 108 109 export default class EntryFormAbility extends FormExtensionAbility { 110 onAddForm(want: Want) { 111 let dataObj1 = new Map<string, string>(); 112 if (want.parameters && want.parameters["ohos.extra.param.key.form_identity"] != undefined) { 113 let formId: string = JSON.parse(JSON.stringify(want.parameters["ohos.extra.param.key.form_identity"])); 114 dataObj1.set("formId", formId); 115 } 116 let obj1 = formBindingData.createFormBindingData(dataObj1); 117 return obj1; 118 } 119 ... 120 }; 121 ``` 122 123- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the call event to start the UIAbility. 124 125 ```ts 126 let storage = new LocalStorage(); 127 @Entry(storage) 128 @Component 129 struct WidgetCard { 130 @LocalStorageProp('detail') detail: string = 'init'; 131 @LocalStorageProp('formId') formId: string = '0'; 132 133 build() { 134 Column() { 135 Button ('Start in Background') 136 .margin('20%') 137 .onClick(() => { 138 console.info('postCardAction to EntryAbility'); 139 postCardAction(this, { 140 'action': 'call', 141 'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed. 142 'params': { 143 'method': 'funA', 144 'formId': this.formId, 145 'detail': 'CallFromCard' 146 } 147 }); 148 }) 149 Text(`${this.detail}`).margin('20%') 150 } 151 .width('100%') 152 .height('100%') 153 } 154 } 155 ``` 156 157- Listen for the method required by the call event in the **onCreate** callback of the UIAbility, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API in the corresponding method to update the widget. 158 159 ```ts 160 import UIAbility from '@ohos.app.ability.UIAbility'; 161 import formBindingData from '@ohos.app.form.formBindingData'; 162 import formProvider from '@ohos.app.form.formProvider'; 163 import Want from '@ohos.app.ability.Want'; 164 import Base from '@ohos.base' 165 import rpc from '@ohos.rpc'; 166 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 167 168 const MSG_SEND_METHOD: string = 'funA'; 169 170 class MyParcelable implements rpc.Parcelable { 171 num: number; 172 str: string; 173 constructor(num: number, str: string) { 174 this.num = num; 175 this.str = str; 176 } 177 marshalling(messageSequence: rpc.MessageSequence): boolean { 178 messageSequence.writeInt(this.num); 179 messageSequence.writeString(this.str); 180 return true; 181 } 182 unmarshalling(messageSequence: rpc.MessageSequence): boolean { 183 this.num = messageSequence.readInt(); 184 this.str = messageSequence.readString(); 185 return true; 186 } 187 } 188 189 // After the call event is received, the method listened for by the callee is triggered. 190 let FunACall = (data: rpc.MessageSequence) => { 191 // Obtain all parameters transferred in the call event. 192 let params: Record<string, string> = JSON.parse(data.readString()) 193 if (params.formId !== undefined) { 194 let curFormId: string = params.formId; 195 let message: string = params.detail; 196 console.info(`UpdateForm formId: ${curFormId}, message: ${message}`); 197 let formData: Record<string, string> = { 198 "detail": message 199 }; 200 let formMsg: formBindingData.FormBindingData = formBindingData.createFormBindingData(formData); 201 formProvider.updateForm(curFormId, formMsg).then((data) => { 202 console.info('updateForm success.' + JSON.stringify(data)); 203 }).catch((error: Base.BusinessError) => { 204 console.error('updateForm failed:' + JSON.stringify(error)); 205 }) 206 } 207 return new MyParcelable(1, 'aaa'); 208 } 209 210 export default class EntryAbility extends UIAbility { 211 // If the UIAbility is started for the first time, onCreate is triggered after the call event is received. 212 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 213 console.info('Want:' + JSON.stringify(want)); 214 try { 215 // Listen for the method required by the call event. 216 this.callee.on(MSG_SEND_METHOD, FunACall); 217 } catch (error) { 218 console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error as Base.BusinessError)}`) 219 } 220 } 221 } 222 ``` 223