1e41f4b71Sopenharmony_ci# AutoFillExtensionAbility
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThe [AutoFillExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md) is an [ExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-extensionAbility.md) component of the AUTO_FILL_PASSWORD or AUTO_FILL_SMART type that provides the auto-fill service.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciThe auto-fill service can be classified as follows:
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci- Auto-fill for accounts and passwords: Saved accounts and passwords are automatically populated, improving the efficiency of information input.
10e41f4b71Sopenharmony_ci- Scenario-specific auto-fill: Information such as the mobile number and address is automatically populated based on the usage scenario.
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci## Available APIs
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciThe table below describes the main APIs related to the auto-fill service. For details about other APIs, see [AutoFillRequest](../reference/apis-ability-kit/js-apis-inner-application-autoFillRequest-sys.md) and [AutoFillExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md).
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci| API                                                    | Description                                                        |
17e41f4b71Sopenharmony_ci| ------------------------------------------------------------ | ------------------------------------------------------------ |
18e41f4b71Sopenharmony_ci| onFillRequest(session: UIExtensionContentSession, request: FillRequest, callback: FillRequestCallback): void | Called when an auto-fill request is initiated or a password is generated.            |
19e41f4b71Sopenharmony_ci| onSaveRequest(session: UIExtensionContentSession, request: SaveRequest, callback: SaveRequestCallback): void | Called when an automatic or manual save request is initiated.                |
20e41f4b71Sopenharmony_ci| FillRequestCallback.onSuccess(response: FillResponse): void  | Implements the callback for an auto-fill request, which is used to automatically fill in or generate a password. The callback can be used to notify the client of the success of the request.|
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci## How to Develop
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ciIn this example, the party that provides the [AutoFillExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md) capability is called the provider, and the party that starts the AutoFillExtensionAbility is called the client.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci### Developing the AutoFillExtensionAbility Provider
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci#### Lifecycle
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ciThe [AutoFillExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md) provides the lifecycle callbacks [onCreate](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md#autofillextensionabilityoncreate), [onSessionDestroy](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md#autofillextensionabilityonsessiondestroy), [onForeground](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md#autofillextensionabilityonforeground), [onBackground](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md#autofillextensionabilityonbackground), and [onDestroy](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md#autofillextensionabilityondestroy). Override them as required.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci- **onCreate**: called to initialize the service logic when an AutoFillExtensionAbility is created.
33e41f4b71Sopenharmony_ci- **onSessionDestroy**: called when a **UIExtensionContentSession** instance is destroyed for the AutoFillExtensionAbility.
34e41f4b71Sopenharmony_ci- **onForeground**: called when the AutoFillExtensionAbility is switched from the background to the foreground.
35e41f4b71Sopenharmony_ci- **onBackground**: called when the AutoFillExtensionAbility is switched from the foreground to the background.
36e41f4b71Sopenharmony_ci- **onDestroy**: called to clear resources when the AutoFillExtensionAbility is destroyed.
37e41f4b71Sopenharmony_ci- **onSaveRequest**: called to trigger auto-save when form data exists and the page is to be switched.
38e41f4b71Sopenharmony_ci- **onFillRequest**: called to automatically fill in the account and password when a fill request is sent.
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci#### Implementing Auto-Fill for Accounts and Passwords
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ciBefore implementing auto-fill for accounts and passwords, manually create an AutoFillExtensionAbility in the DevEco Studio project.
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci1. Set the bundle name of the AutoFillExtensionAbility provider.
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci   In the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory, set **bundleName** to **com.ohos.passwordbox**. An example configuration is as follows:
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci   ```json
49e41f4b71Sopenharmony_ci   "app": {
50e41f4b71Sopenharmony_ci     "bundleName": "com.ohos.passwordbox",
51e41f4b71Sopenharmony_ci      // ...
52e41f4b71Sopenharmony_ci   }
53e41f4b71Sopenharmony_ci   ```
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci2. Configuration information about this ExtensionAbility.
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci   Configure an AutoFillExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) in the **entry/src/main/** directory. An example configuration is as follows:
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci   ```json
60e41f4b71Sopenharmony_ci   "extensionAbilities": [
61e41f4b71Sopenharmony_ci      {
62e41f4b71Sopenharmony_ci        "name": "AutoFillAbility",
63e41f4b71Sopenharmony_ci        "srcEntry": "./ets/autofillability/AutoFillAbility.ets",
64e41f4b71Sopenharmony_ci        // ...
65e41f4b71Sopenharmony_ci        "type": "autoFill/password"
66e41f4b71Sopenharmony_ci      }
67e41f4b71Sopenharmony_ci   ]
68e41f4b71Sopenharmony_ci   ```
69e41f4b71Sopenharmony_ci   
70e41f4b71Sopenharmony_ci3. Implement auto-fill and auto-save.
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci   1. Right-click the **ets** directory, and choose **New > Directory** to create a directory named **autofillability**.
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci   2. Right-click the **autofillability** directory, and choose **New > File** to create a file named **AutoFillAbility.ets**. An example code snippet is as follows:
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci      ```ts
77e41f4b71Sopenharmony_ci      import { hilog } from '@kit.PerformanceAnalysisKit';
78e41f4b71Sopenharmony_ci      import { AutoFillExtensionAbility, autoFillManager, UIExtensionContentSession } from '@kit.AbilityKit';
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci      class AutoFillAbility extends AutoFillExtensionAbility {
81e41f4b71Sopenharmony_ci        // ...
82e41f4b71Sopenharmony_ci        // The onFillRequest lifecycle callback is triggered when the auto-fill service initiates an auto-fill request.
83e41f4b71Sopenharmony_ci        onFillRequest(session: UIExtensionContentSession, request: autoFillManager.FillRequest, callback: autoFillManager.FillRequestCallback) {
84e41f4b71Sopenharmony_ci          hilog.info(0x0000, 'testTag', '%{public}s', 'autofill onFillRequest');
85e41f4b71Sopenharmony_ci          try {
86e41f4b71Sopenharmony_ci            // Save the page data and callback data carried in onFillRequest.
87e41f4b71Sopenharmony_ci            let obj: Record<string, UIExtensionContentSession | autoFillManager.FillRequestCallback | autoFillManager.ViewData> = {
88e41f4b71Sopenharmony_ci              'session': session,
89e41f4b71Sopenharmony_ci              'fillCallback': callback, // The auto-fill processing result is returned to the client through this callback.
90e41f4b71Sopenharmony_ci              'viewData': request.viewData, // Assemble the data to be populated to viewData and return the data to the client through the callback.
91e41f4b71Sopenharmony_ci            };
92e41f4b71Sopenharmony_ci            let storageFill: LocalStorage = new LocalStorage(obj);
93e41f4b71Sopenharmony_ci            // Load the auto-fill processing page.
94e41f4b71Sopenharmony_ci            session.loadContent('autofillpages/AutoFillPassWord', storageFill);
95e41f4b71Sopenharmony_ci          } catch (err) {
96e41f4b71Sopenharmony_ci            hilog.error(0x0000, 'testTag', '%{public}s', 'autofill failed to load content');
97e41f4b71Sopenharmony_ci          }
98e41f4b71Sopenharmony_ci        }
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci        // The onSaveRequest lifecycle callback is triggered when the auto-save service initiates an auto-save request.
101e41f4b71Sopenharmony_ci        onSaveRequest(session: UIExtensionContentSession, request: autoFillManager.SaveRequest, callback: autoFillManager.SaveRequestCallback): void {
102e41f4b71Sopenharmony_ci          hilog.info(0x0000, 'testTag', '%{public}s', 'autofill onSaveRequest');
103e41f4b71Sopenharmony_ci          try {
104e41f4b71Sopenharmony_ci            let obj: Record<string, UIExtensionContentSession | autoFillManager.SaveRequestCallback | autoFillManager.ViewData> = {
105e41f4b71Sopenharmony_ci              'session': session,
106e41f4b71Sopenharmony_ci              'saveCallback': callback, // The auto-save processing result is returned to the client through this callback.
107e41f4b71Sopenharmony_ci              'viewData': request.viewData, // Assemble the data to be populated to viewData and return the data to the client through the callback.
108e41f4b71Sopenharmony_ci            }
109e41f4b71Sopenharmony_ci            // Save the page data and callback data carried in onSaveRequest.
110e41f4b71Sopenharmony_ci            let storageSave: LocalStorage = new LocalStorage(obj);
111e41f4b71Sopenharmony_ci            // Load the auto-save processing page.
112e41f4b71Sopenharmony_ci            session.loadContent('autofillpages/SavePage', storageSave);
113e41f4b71Sopenharmony_ci          } catch (err) {
114e41f4b71Sopenharmony_ci            hilog.error(0x0000, 'testTag', '%{public}s', 'autofill failed');
115e41f4b71Sopenharmony_ci          }
116e41f4b71Sopenharmony_ci        }
117e41f4b71Sopenharmony_ci      }
118e41f4b71Sopenharmony_ci      ```
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ci4. Build the auto-fill processing page.
121e41f4b71Sopenharmony_ci
122e41f4b71Sopenharmony_ci   1. Right-click the **ets** directory, and choose **New > Directory** to create a directory named **autofillpages**.
123e41f4b71Sopenharmony_ci
124e41f4b71Sopenharmony_ci   2. Right-click the **autofillpages** directory, and choose **New > File** to create a file named **AutoFillPassWord.ets**.
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci   3. When users touch the account or password text box on the page, the auto-fill framework sends an auto-fill request to the auto-fill service to trigger the [onFillRequest](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md#autofillextensionabilityonfillrequest) lifecycle callback. In the **onFillRequest** lifecycle callback, display the page that shows the available accounts and passwords (implemented by **AutoFillPassWord.ets**).
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ci      ```ts
129e41f4b71Sopenharmony_ci      import { autoFillManager } from '@kit.AbilityKit';
130e41f4b71Sopenharmony_ci      
131e41f4b71Sopenharmony_ci      const storage = LocalStorage.getShared();
132e41f4b71Sopenharmony_ci      let fillCallback: autoFillManager.FillRequestCallback | undefined = storage.get<autoFillManager.FillRequestCallback>('fillCallback');
133e41f4b71Sopenharmony_ci      let viewData: autoFillManager.ViewData | undefined = storage.get<autoFillManager.ViewData>('viewData');
134e41f4b71Sopenharmony_ci      
135e41f4b71Sopenharmony_ci      // Assemble the data to be populated to viewData and use the onSuccess callback to return the data to the client for auto-fill.
136e41f4b71Sopenharmony_ci      function successFunc(data: autoFillManager.ViewData, target: string) {
137e41f4b71Sopenharmony_ci        console.info(`data.pageNodeInfos.length`, data.pageNodeInfos.length);
138e41f4b71Sopenharmony_ci        for (let i = 0; i < data.pageNodeInfos.length; i++) {
139e41f4b71Sopenharmony_ci          console.info(`data.pageNodeInfos[i].isFocus`, data.pageNodeInfos[i].isFocus);
140e41f4b71Sopenharmony_ci          if (data.pageNodeInfos[i].isFocus == true) {
141e41f4b71Sopenharmony_ci            data.pageNodeInfos[i].value = target;
142e41f4b71Sopenharmony_ci            break;
143e41f4b71Sopenharmony_ci          }
144e41f4b71Sopenharmony_ci        }
145e41f4b71Sopenharmony_ci        if (fillCallback) {
146e41f4b71Sopenharmony_ci          let response: autoFillManager.FillResponse = { viewData: data };
147e41f4b71Sopenharmony_ci          fillCallback.onSuccess(response);
148e41f4b71Sopenharmony_ci        }
149e41f4b71Sopenharmony_ci      }
150e41f4b71Sopenharmony_ci      
151e41f4b71Sopenharmony_ci      function failFunc() {
152e41f4b71Sopenharmony_ci        if (fillCallback) {
153e41f4b71Sopenharmony_ci          fillCallback.onFailure();
154e41f4b71Sopenharmony_ci        }
155e41f4b71Sopenharmony_ci      }
156e41f4b71Sopenharmony_ci      
157e41f4b71Sopenharmony_ci      function cancelFunc(fillContent?: string) {
158e41f4b71Sopenharmony_ci        if (fillCallback) {
159e41f4b71Sopenharmony_ci          try {
160e41f4b71Sopenharmony_ci            fillCallback.onCancel(fillContent);
161e41f4b71Sopenharmony_ci          } catch (error) {
162e41f4b71Sopenharmony_ci            console.error('fillContent undefined: ', JSON.stringify(error));
163e41f4b71Sopenharmony_ci          }
164e41f4b71Sopenharmony_ci        }
165e41f4b71Sopenharmony_ci      }
166e41f4b71Sopenharmony_ci      
167e41f4b71Sopenharmony_ci      @Entry
168e41f4b71Sopenharmony_ci      @Component
169e41f4b71Sopenharmony_ci      struct AutoFillControl {
170e41f4b71Sopenharmony_ci        build() {
171e41f4b71Sopenharmony_ci          Column() {
172e41f4b71Sopenharmony_ci            Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
173e41f4b71Sopenharmony_ci              Text('Select a saved account and password')
174e41f4b71Sopenharmony_ci                .fontWeight(500)
175e41f4b71Sopenharmony_ci                .fontFamily('HarmonyHeiTi-Medium')
176e41f4b71Sopenharmony_ci                .fontSize(20)
177e41f4b71Sopenharmony_ci                .fontColor('#000000')
178e41f4b71Sopenharmony_ci                .margin({ left: '4.4%' })
179e41f4b71Sopenharmony_ci            }.margin({ top: '8.8%', left: '4.9%' }).height('7.2%')
180e41f4b71Sopenharmony_ci      
181e41f4b71Sopenharmony_ci            Row() {
182e41f4b71Sopenharmony_ci              Column() {
183e41f4b71Sopenharmony_ci                List({ space: 10, initialIndex: 0 }) {
184e41f4b71Sopenharmony_ci                  ListItem() {
185e41f4b71Sopenharmony_ci                    Text('15501212262')
186e41f4b71Sopenharmony_ci                      .width('100%')
187e41f4b71Sopenharmony_ci                      .height(40)
188e41f4b71Sopenharmony_ci                      .fontSize(16)
189e41f4b71Sopenharmony_ci                      .textAlign(TextAlign.Center)
190e41f4b71Sopenharmony_ci                      .borderRadius(5)
191e41f4b71Sopenharmony_ci                  }
192e41f4b71Sopenharmony_ci                  .onClick(() => {
193e41f4b71Sopenharmony_ci                    if (viewData != undefined) {
194e41f4b71Sopenharmony_ci                      // Populate the selected account and password in the client.
195e41f4b71Sopenharmony_ci                      successFunc(viewData, '15501212262')
196e41f4b71Sopenharmony_ci                    }
197e41f4b71Sopenharmony_ci                  })
198e41f4b71Sopenharmony_ci                }
199e41f4b71Sopenharmony_ci                // ...
200e41f4b71Sopenharmony_ci                .listDirection(Axis.Vertical)
201e41f4b71Sopenharmony_ci                .scrollBar(BarState.Off)
202e41f4b71Sopenharmony_ci                .friction(0.6)
203e41f4b71Sopenharmony_ci                .divider({ strokeWidth: 1, color: '#fff5eeee', startMargin: 20, endMargin: 20 })
204e41f4b71Sopenharmony_ci                .edgeEffect(EdgeEffect.Spring)
205e41f4b71Sopenharmony_ci                .onScrollIndex((firstIndex: number, lastIndex: number, centerIndex: number) => {
206e41f4b71Sopenharmony_ci                  console.info('first' + firstIndex)
207e41f4b71Sopenharmony_ci                  console.info('last' + lastIndex)
208e41f4b71Sopenharmony_ci                  console.info('center' + centerIndex)
209e41f4b71Sopenharmony_ci                })
210e41f4b71Sopenharmony_ci                .onScroll((scrollOffset: number, scrollState: ScrollState) => {
211e41f4b71Sopenharmony_ci                  console.info(`onScroll scrollState = ScrollState` + scrollState + `scrollOffset = ` + scrollOffset)
212e41f4b71Sopenharmony_ci                })
213e41f4b71Sopenharmony_ci              }
214e41f4b71Sopenharmony_ci              .width('100%')
215e41f4b71Sopenharmony_ci              .shadow(ShadowStyle.OUTER_FLOATING_SM)
216e41f4b71Sopenharmony_ci              .margin({ top: 50 })
217e41f4b71Sopenharmony_ci            }
218e41f4b71Sopenharmony_ci      
219e41f4b71Sopenharmony_ci            Row() {
220e41f4b71Sopenharmony_ci              Button("Cancel")
221e41f4b71Sopenharmony_ci                .onClick(() => {
222e41f4b71Sopenharmony_ci                  // Call cancelFunc() to notify the client when auto-fill is canceled.
223e41f4b71Sopenharmony_ci                  cancelFunc();
224e41f4b71Sopenharmony_ci                })
225e41f4b71Sopenharmony_ci                .margin({ top: 30, bottom: 10, left: 10, right: 10 })
226e41f4b71Sopenharmony_ci      
227e41f4b71Sopenharmony_ci              Button("Failure")
228e41f4b71Sopenharmony_ci                .onClick(() => {
229e41f4b71Sopenharmony_ci                  // Call failFunc() to notify the client that auto-fill fails when the account and password are not obtained.
230e41f4b71Sopenharmony_ci                  failFunc();
231e41f4b71Sopenharmony_ci                })
232e41f4b71Sopenharmony_ci                .margin({ top: 30, bottom: 10, left: 10, right: 10 })
233e41f4b71Sopenharmony_ci            }
234e41f4b71Sopenharmony_ci            .backgroundColor('#f1f3f5').height('100%')
235e41f4b71Sopenharmony_ci          }
236e41f4b71Sopenharmony_ci        }
237e41f4b71Sopenharmony_ci      }
238e41f4b71Sopenharmony_ci      ```
239e41f4b71Sopenharmony_ci
240e41f4b71Sopenharmony_ci5. Build the auto-save processing page.
241e41f4b71Sopenharmony_ci
242e41f4b71Sopenharmony_ci   1. Right-click the **autofillpages** directory, and choose **New > File** to create a file named **SavePage.ets**.
243e41f4b71Sopenharmony_ci
244e41f4b71Sopenharmony_ci   2. When information exists in the **TextInput** component, trigger the [onSaveRequest](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md#autofillextensionabilityonsaverequest) lifecycle callback during page redirection (a user touches the login button). In the **onSaveRequest** callback, display the information save processing page (implemented by **SavePage.ets**).
245e41f4b71Sopenharmony_ci
246e41f4b71Sopenharmony_ci      ```ts
247e41f4b71Sopenharmony_ci      import { autoFillManager } from '@kit.AbilityKit';
248e41f4b71Sopenharmony_ci      import { hilog } from '@kit.PerformanceAnalysisKit';
249e41f4b71Sopenharmony_ci      
250e41f4b71Sopenharmony_ci      let storage=LocalStorage.getShared();
251e41f4b71Sopenharmony_ci      let saveRequestCallback = storage.get<autoFillManager.SaveRequestCallback>('saveCallback');
252e41f4b71Sopenharmony_ci      
253e41f4b71Sopenharmony_ci      function SuccessFunc(success : boolean) {
254e41f4b71Sopenharmony_ci        if (saveRequestCallback) {
255e41f4b71Sopenharmony_ci          if (success) {
256e41f4b71Sopenharmony_ci            saveRequestCallback.onSuccess();
257e41f4b71Sopenharmony_ci            return;
258e41f4b71Sopenharmony_ci          }
259e41f4b71Sopenharmony_ci          saveRequestCallback.onFailure();
260e41f4b71Sopenharmony_ci        }
261e41f4b71Sopenharmony_ci        hilog.error(0x0000, "testTag", "saveRequestCallback is nullptr!");
262e41f4b71Sopenharmony_ci      }
263e41f4b71Sopenharmony_ci      
264e41f4b71Sopenharmony_ci      @Entry
265e41f4b71Sopenharmony_ci      @Component
266e41f4b71Sopenharmony_ci      struct SavePage {
267e41f4b71Sopenharmony_ci        @State message: string = 'Save Account?'
268e41f4b71Sopenharmony_ci        build() {
269e41f4b71Sopenharmony_ci          Row() {
270e41f4b71Sopenharmony_ci            Column() {
271e41f4b71Sopenharmony_ci              Text(this.message)
272e41f4b71Sopenharmony_ci                .fontSize(35)
273e41f4b71Sopenharmony_ci                .fontWeight(FontWeight.Bold)
274e41f4b71Sopenharmony_ci              Row() {
275e41f4b71Sopenharmony_ci                // Call onSuccess() (upon the touch of the save button) to notify the client that the form data is saved successfully.
276e41f4b71Sopenharmony_ci                Button("save")
277e41f4b71Sopenharmony_ci                  .type(ButtonType.Capsule)
278e41f4b71Sopenharmony_ci                  .fontSize(20)
279e41f4b71Sopenharmony_ci                  .margin({ top: 30, right: 30 })
280e41f4b71Sopenharmony_ci                  .onClick(() => {
281e41f4b71Sopenharmony_ci                    SuccessFunc(true);
282e41f4b71Sopenharmony_ci                  })
283e41f4b71Sopenharmony_ci                // Call onFailure() (upon the touch of the back button) to notify the client that the user cancels saving the form data or saving the form data fails.
284e41f4b71Sopenharmony_ci                Button("back")
285e41f4b71Sopenharmony_ci                  .type(ButtonType.Capsule)
286e41f4b71Sopenharmony_ci                  .fontSize(20)
287e41f4b71Sopenharmony_ci                  .margin({ top: 30, left: 30 })
288e41f4b71Sopenharmony_ci                  .onClick(() => {
289e41f4b71Sopenharmony_ci                    SuccessFunc(false);
290e41f4b71Sopenharmony_ci                  })
291e41f4b71Sopenharmony_ci              }
292e41f4b71Sopenharmony_ci            }
293e41f4b71Sopenharmony_ci            .width('100%')
294e41f4b71Sopenharmony_ci          }
295e41f4b71Sopenharmony_ci          .height('100%')
296e41f4b71Sopenharmony_ci        }
297e41f4b71Sopenharmony_ci      }
298e41f4b71Sopenharmony_ci      ```
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ci#### Implementing Scenario-specific Auto-Fill
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ciFor details about the types of scenario-specific auto-fill, see [AutoFillType](../reference/apis-ability-kit/js-apis-inner-application-autoFillType-sys.md).
303e41f4b71Sopenharmony_ci
304e41f4b71Sopenharmony_ciBefore implementing scenario-specific auto-fill, you need to create a **SmartAutoFillExtensionAbility** object in the DevEco Studio project.
305e41f4b71Sopenharmony_ci
306e41f4b71Sopenharmony_ci1. Set the bundle name of the AutoFillExtensionAbility provider.
307e41f4b71Sopenharmony_ci
308e41f4b71Sopenharmony_ci   In the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory, set **bundleName** to **com.ohos.textautofill**. An example configuration is as follows:
309e41f4b71Sopenharmony_ci
310e41f4b71Sopenharmony_ci   ```json
311e41f4b71Sopenharmony_ci   "app": {
312e41f4b71Sopenharmony_ci     "bundleName": "com.ohos.textautofill",
313e41f4b71Sopenharmony_ci      // ...
314e41f4b71Sopenharmony_ci   }
315e41f4b71Sopenharmony_ci   ```
316e41f4b71Sopenharmony_ci
317e41f4b71Sopenharmony_ci2. Configuration information about this ExtensionAbility.
318e41f4b71Sopenharmony_ci
319e41f4b71Sopenharmony_ci   Configure an AutoFillExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) in the **entry/src/main/** directory. An example configuration is as follows:
320e41f4b71Sopenharmony_ci
321e41f4b71Sopenharmony_ci   ```json
322e41f4b71Sopenharmony_ci   "extensionAbilities": [
323e41f4b71Sopenharmony_ci      {
324e41f4b71Sopenharmony_ci         "name": "AutoFillAbility",
325e41f4b71Sopenharmony_ci         "srcEntry": "./ets/autofillability/AutoFillAbility.ets",
326e41f4b71Sopenharmony_ci         // ...
327e41f4b71Sopenharmony_ci         "type": "autoFill/smart"
328e41f4b71Sopenharmony_ci      }
329e41f4b71Sopenharmony_ci   ]
330e41f4b71Sopenharmony_ci   ```
331e41f4b71Sopenharmony_ci
332e41f4b71Sopenharmony_ci3. The implementation of the scenario-specific auto-fill service is basically the same as that of auto-fill for accounts and passwords. For details, see [Implementing Auto-Fill for Accounts and Passwords](#implementing-auto-fill-for-accounts-and-passwords).
333e41f4b71Sopenharmony_ci
334e41f4b71Sopenharmony_ci### Developing the AutoFillExtensionAbility Client
335e41f4b71Sopenharmony_ci
336e41f4b71Sopenharmony_ciYou can click the auto-fill component on the home page to start the [AutoFillExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-autoFillExtensionAbility-sys.md). For example, you can add the following component to the main page:
337e41f4b71Sopenharmony_ci
338e41f4b71Sopenharmony_ci#### Component That Supports Auto-Fill of Accounts and Passwords
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ci```ts
341e41f4b71Sopenharmony_ci@Entry
342e41f4b71Sopenharmony_ci@Component
343e41f4b71Sopenharmony_cistruct Index {
344e41f4b71Sopenharmony_ci  loginBtnColor: String = '#bfdbf9';
345e41f4b71Sopenharmony_ci
346e41f4b71Sopenharmony_ci  build() {
347e41f4b71Sopenharmony_ci    Column() {
348e41f4b71Sopenharmony_ci      Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
349e41f4b71Sopenharmony_ci        Text('Welcome!')
350e41f4b71Sopenharmony_ci          .fontSize(24)
351e41f4b71Sopenharmony_ci          .fontWeight(500)
352e41f4b71Sopenharmony_ci          .fontFamily('HarmonyHeiTi-Medium')
353e41f4b71Sopenharmony_ci          .fontColor('#182431')
354e41f4b71Sopenharmony_ci      }.margin({ top: '32.3%' }).width('35%').height('4.1%')
355e41f4b71Sopenharmony_ci
356e41f4b71Sopenharmony_ci      // Add a text box of the account type.
357e41f4b71Sopenharmony_ci      List() {
358e41f4b71Sopenharmony_ci        ListItemGroup({ style: ListItemGroupStyle.CARD }) {
359e41f4b71Sopenharmony_ci          ListItem({ style: ListItemStyle.CARD }) {
360e41f4b71Sopenharmony_ci            TextInput({placeholder: 'Enter an account.'})
361e41f4b71Sopenharmony_ci              .type(InputType.USER_NAME)
362e41f4b71Sopenharmony_ci              .fontFamily('HarmonyHeiTi')
363e41f4b71Sopenharmony_ci              .fontColor('#182431')
364e41f4b71Sopenharmony_ci              .fontWeight(400)
365e41f4b71Sopenharmony_ci              .fontSize(16)
366e41f4b71Sopenharmony_ci              .height('100%')
367e41f4b71Sopenharmony_ci              .id('userName')
368e41f4b71Sopenharmony_ci              .backgroundColor('#FFFFFF')
369e41f4b71Sopenharmony_ci              .onChange((value: string) => {
370e41f4b71Sopenharmony_ci                if (value) {
371e41f4b71Sopenharmony_ci                  this.loginBtnColor = '#007DFF';
372e41f4b71Sopenharmony_ci                } else {
373e41f4b71Sopenharmony_ci                  this.loginBtnColor = '#bfdbf9';
374e41f4b71Sopenharmony_ci                }
375e41f4b71Sopenharmony_ci              })
376e41f4b71Sopenharmony_ci              .enableAutoFill(true)
377e41f4b71Sopenharmony_ci          }.padding(0)
378e41f4b71Sopenharmony_ci
379e41f4b71Sopenharmony_ci          // Add a text box of the password type.
380e41f4b71Sopenharmony_ci          ListItem({ style: ListItemStyle.CARD }) {
381e41f4b71Sopenharmony_ci            TextInput({placeholder: 'Enter the password.'})
382e41f4b71Sopenharmony_ci              .type(InputType.Password)
383e41f4b71Sopenharmony_ci              .fontFamily('HarmonyHeiTi')
384e41f4b71Sopenharmony_ci              .fontColor('#182431')
385e41f4b71Sopenharmony_ci              .fontWeight(400)
386e41f4b71Sopenharmony_ci              .fontSize(16)
387e41f4b71Sopenharmony_ci              .height('100%')
388e41f4b71Sopenharmony_ci              .backgroundColor('#FFFFFF')
389e41f4b71Sopenharmony_ci              .id('passWord')
390e41f4b71Sopenharmony_ci              .onChange((value: string) => {
391e41f4b71Sopenharmony_ci                if (value) {
392e41f4b71Sopenharmony_ci                  this.loginBtnColor = '#007DFF';
393e41f4b71Sopenharmony_ci                } else {
394e41f4b71Sopenharmony_ci                  this.loginBtnColor = '#bfdbf9';
395e41f4b71Sopenharmony_ci                }
396e41f4b71Sopenharmony_ci              })
397e41f4b71Sopenharmony_ci              .enableAutoFill(true)
398e41f4b71Sopenharmony_ci          }.padding(0)
399e41f4b71Sopenharmony_ci        }
400e41f4b71Sopenharmony_ci        .backgroundColor('#FFFFFF')
401e41f4b71Sopenharmony_ci        .divider({ strokeWidth: 0.5, color: '#f1f3f5', startMargin: 15, endMargin: 15 })
402e41f4b71Sopenharmony_ci      }
403e41f4b71Sopenharmony_ci      .borderRadius(24)
404e41f4b71Sopenharmony_ci      .width('93.3%')
405e41f4b71Sopenharmony_ci      .height('16%')
406e41f4b71Sopenharmony_ci      .margin({ top: '8.6%' })
407e41f4b71Sopenharmony_ci    }
408e41f4b71Sopenharmony_ci  }
409e41f4b71Sopenharmony_ci}
410e41f4b71Sopenharmony_ci```
411e41f4b71Sopenharmony_ci
412e41f4b71Sopenharmony_ci#### Component That Supports Scenario-Specific Auto-Fill
413e41f4b71Sopenharmony_ci
414e41f4b71Sopenharmony_ci```ts
415e41f4b71Sopenharmony_ci@Entry
416e41f4b71Sopenharmony_ci@Component
417e41f4b71Sopenharmony_cistruct Index {
418e41f4b71Sopenharmony_ci  @State inputTxt: string = '';
419e41f4b71Sopenharmony_ci
420e41f4b71Sopenharmony_ci  build() {
421e41f4b71Sopenharmony_ci    Column() {
422e41f4b71Sopenharmony_ci      Column() {
423e41f4b71Sopenharmony_ci        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
424e41f4b71Sopenharmony_ci          Text ('Scenario-specific population')
425e41f4b71Sopenharmony_ci            .fontWeight(500)
426e41f4b71Sopenharmony_ci            .fontFamily('HarmonyHeiTi-Medium')
427e41f4b71Sopenharmony_ci          // ...
428e41f4b71Sopenharmony_ci        }
429e41f4b71Sopenharmony_ci        .margin({ top: '14.2%' }).height('7.2%')
430e41f4b71Sopenharmony_ci
431e41f4b71Sopenharmony_ci        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
432e41f4b71Sopenharmony_ci          Column() {
433e41f4b71Sopenharmony_ci            Row() {
434e41f4b71Sopenharmony_ci              Text('Set the type.')
435e41f4b71Sopenharmony_ci                .fontColor('#99000000')
436e41f4b71Sopenharmony_ci                .fontSize(14)
437e41f4b71Sopenharmony_ci                .fontWeight(400)
438e41f4b71Sopenharmony_ci                .textAlign(TextAlign.Start)
439e41f4b71Sopenharmony_ci                .width('91%')
440e41f4b71Sopenharmony_ci                .margin({ top: 5, left: -7.5 })
441e41f4b71Sopenharmony_ci            }
442e41f4b71Sopenharmony_ci
443e41f4b71Sopenharmony_ci            Row() {
444e41f4b71Sopenharmony_ci              TextInput({ placeholder: 'Input content', text: this.inputTxt })
445e41f4b71Sopenharmony_ci                .contentType(ContentType.FULL_PHONE_NUMBER) // Scenario-specific automatic population
446e41f4b71Sopenharmony_ci                .height('9.4%')
447e41f4b71Sopenharmony_ci                .width('91%')
448e41f4b71Sopenharmony_ci                .fontWeight(FontWeight.Bolder)
449e41f4b71Sopenharmony_ci                .placeholderColor('#99000000')
450e41f4b71Sopenharmony_ci                .backgroundColor('#ffffffff')
451e41f4b71Sopenharmony_ci                .id('password1')
452e41f4b71Sopenharmony_ci                .fontSize(16)
453e41f4b71Sopenharmony_ci                .fontWeight(400)
454e41f4b71Sopenharmony_ci                .borderStyle(BorderStyle.Solid)
455e41f4b71Sopenharmony_ci                .enableAutoFill(true)
456e41f4b71Sopenharmony_ci                .borderRadius(25)
457e41f4b71Sopenharmony_ci                .margin({ top: '8vp' })
458e41f4b71Sopenharmony_ci            }
459e41f4b71Sopenharmony_ci          }.margin({ top: '7.1%' })
460e41f4b71Sopenharmony_ci        }
461e41f4b71Sopenharmony_ci
462e41f4b71Sopenharmony_ci
463e41f4b71Sopenharmony_ci        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
464e41f4b71Sopenharmony_ci          Column() {
465e41f4b71Sopenharmony_ci            Row() {
466e41f4b71Sopenharmony_ci              Text('Set the type to name')
467e41f4b71Sopenharmony_ci                .fontColor('#99000000')
468e41f4b71Sopenharmony_ci                .fontSize(14)
469e41f4b71Sopenharmony_ci                .fontWeight(400)
470e41f4b71Sopenharmony_ci                .textAlign(TextAlign.Start)
471e41f4b71Sopenharmony_ci                .width('91%')
472e41f4b71Sopenharmony_ci                .margin({ top: 5, left: -7.5 })
473e41f4b71Sopenharmony_ci            }
474e41f4b71Sopenharmony_ci
475e41f4b71Sopenharmony_ci            Row() {
476e41f4b71Sopenharmony_ci              TextInput({ placeholder: 'Name', text: this.inputTxt })
477e41f4b71Sopenharmony_ci                .contentType(ContentType.PERSON_FULL_NAME) // Scenario-specific automatic population
478e41f4b71Sopenharmony_ci                .height('9.4%')
479e41f4b71Sopenharmony_ci                .width('91%')
480e41f4b71Sopenharmony_ci                .fontWeight(FontWeight.Bold)
481e41f4b71Sopenharmony_ci                .placeholderColor('#99000000')
482e41f4b71Sopenharmony_ci                .backgroundColor('#ffffffff')
483e41f4b71Sopenharmony_ci                .fontSize(16)
484e41f4b71Sopenharmony_ci                .fontWeight(400)
485e41f4b71Sopenharmony_ci                .id('password3')
486e41f4b71Sopenharmony_ci                .borderStyle(BorderStyle.Solid)
487e41f4b71Sopenharmony_ci                .enableAutoFill(true)
488e41f4b71Sopenharmony_ci                .borderRadius(25)
489e41f4b71Sopenharmony_ci                .onChange(() => {
490e41f4b71Sopenharmony_ci                })
491e41f4b71Sopenharmony_ci                .margin({ top: '8vp' })
492e41f4b71Sopenharmony_ci            }
493e41f4b71Sopenharmony_ci          }
494e41f4b71Sopenharmony_ci        }
495e41f4b71Sopenharmony_ci        .margin({ top: '20vp' })
496e41f4b71Sopenharmony_ci      }.height('70%')
497e41f4b71Sopenharmony_ci    }
498e41f4b71Sopenharmony_ci    .backgroundColor('#ffffff').height('100%')
499e41f4b71Sopenharmony_ci  }
500e41f4b71Sopenharmony_ci}
501e41f4b71Sopenharmony_ci```
502