1# Docking to the Soft Keyboard
2
3By docking the **Web** component to the soft keyboard, you can manage the display and interaction of the soft keyboard in your application, and can also customize its features to suit your specific needs. The main scenarios are as follows:
4
5- Bringing up the system soft keyboard to enter text: When a user taps a text box on a web page, the default soft keyboard (input method) is displayed at the bottom of the screen. The user can enter text using the soft keyboard, and the entered content is displayed in the text box.
6- Customizing the **Enter** key type of the system soft keyboard: The application specifies the web page text box to pull up different types of **Enter** keys on the soft keyboard. For example, **Confirm**, **Next**, and **Submit**.
7- Specifying the soft keyboard avoidance mode: On a mobile device, the input method is usually fixed at the lower part of the screen. The application can set different soft keyboard avoidance modes for web pages. For example, relocating, resizing, or no avoidance.
8- Defining a custom soft keyboard: On a mobile device, applications can use a self-drawing soft keyboard to replace the system soft keyboard.
9
10
11
12## W3C Standard Attributes for the Interaction Between the Web Page Text Box and the Soft Keyboard
13
14To support the interaction between the web page and the system soft keyboard and custom soft keyboard, ArkWeb complies with and implements the following input component attributes in the W3C specifications:
15- **type**
16
17  The **type** attribute defines the type of the **input** element, which affects the input validation, display mode, and keyboard type. The common type values are as follows.
18
19  | Value   | Description        |
20  | -------- | ---------- |
21  | text     | Default value. Common text.|
22  | number   | Number.      |
23  | email    | Email address.  |
24  | password | Password.      |
25  | tel      | Telephone number.    |
26  | url      | URL.     |
27  | date     | Date picker.     |
28  | time     | Time picker.     |
29  | checkbox | Check box.       |
30  | radio    | Radio button.      |
31  | file     | File upload.      |
32  | submit   | Submit button.      |
33  | reset    | Reset button.      |
34  | button   | Common button.      |
35
36- **inputmode**
37
38  The **inputmode** attribute is used to configure the input method type. It accepts the values listed below.
39
40  | Value| Description                                      |
41  | --------- | ---------------------------------------- |
42  | decimal   | Numeric keyboard, usually with a comma key.                       |
43  | email     | Text keyboard with keys usually used for email addresses, such as **@**.                  |
44  | none      | No keyboard.                                  |
45  | numeric   | Numeric keypad.                                 |
46  | search    | Text keyboard. The **Enter** key is displayed as **Go**.                  |
47  | tel       | Numeric keyboard with **+**, *****, and **#** keys.               |
48  | text      | Default value. Text keyboard.                                 |
49  | url       | Text keyboard with keys used for websites such as the **.**, **/**, and **.com** keys, or other domain name terminators used locally.|
50
51- enterkeyhint
52
53  The **enterkeyhint** attribute specifies the display mode of the **Enter** key on the virtual keyboard of the mobile device. It accepts the values listed below.
54
55  | Value| Description       |
56  | ------------- | --------- |
57  | enter         | Displays the default **Enter** key. |
58  | done          | Indicates that the input is complete.   |
59  | go            | Indicates to jump or execute.  |
60  | next          | Goes to the next input field.|
61  | previous      | Goes to the previous input field.|
62  | search        | Searches for information.     |
63  | send          | Sends a message.     |
64
65>**NOTE**
66>
67>When a user taps a web page input box, the default soft keyboard (input method) is displayed at the bottom of the screen, and the user can enter text on the screen.
68>
69>The **type** attribute affects not only the keyboard display, but also the input validation and element appearance.
70>
71>The **inputmode** is mainly used to optimize the keyboard input experience on mobile devices and does not change the basic input behavior or verification.
72
73
74
75## Setting the Avoidance Mode for the Soft Keyboard
76
77On a mobile device, you can set the avoidance mode for the soft keyboard on the web page.
78
791. Call [setKeyboardAvoidMode()](../reference/apis-arkui/arkui-ts/ts-universal-attributes-expand-safe-area.md#setkeyboardavoidmode11) of UIContext in your application code to set the avoidance mode, which can be **Resize** or **Offset** for the **Web** component.
80
81- In the **Resize** mode, the height of the application window can be reduced to avoid the soft keyboard, and the **Web** component is re-arranged with ArkUI.
82- In the **Offset** mode (the default mode), the height of the application window remains unchanged, and the **Web** component performs avoidance based on its own avoidance mode.
83
84(1) Set the soft keyboard avoidance mode of **UIContext** in the application code.
85
86```ts
87// EntryAbility.ets
88import { KeyboardAvoidMode } from '@kit.ArkUI';
89import { hilog } from '@kit.PerformanceAnalysisKit';
90
91onWindowStageCreate(windowStage: window.WindowStage) {
92  hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
93
94  windowStage.loadContent('pages/Index', (err, data) => {
95    let keyboardAvoidMode = windowStage.getMainWindowSync().getUIContext().getKeyboardAvoidMode();
96    // When the soft keyboard is displayed, the application window is resized to its original height minus the keyboard height.
97  windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE);
98    if (err.code) {
99      hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
100      return;
101    }
102    hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
103  });
104}
105```
106(2) Enable the soft keyboard in the **Web** component.
107
108```html
109<!DOCTYPE html>
110<html>
111  <head>
112    <title>Test Web Page</title>
113  </head>
114  <body>
115    <h1>DEMO</h1>
116    <input type="text" id="input_a">
117  </body>
118</html>
119```
120
121```ts
122//Index.ets
123@Entry
124@Component
125struct KeyboardAvoidExample {
126  controller: web_webview.WebviewController = new web_webview.WebviewController();
127  build() {
128    Column() {
129      Row().height("50%").width("100%").backgroundColor(Color.Gray)
130      Web({ src: $rawfile("index.html"),controller: this.controller})
131      Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor(Color.Pink).layoutWeight(1)
132    }.width('100%').height("100%")
133  }
134}
135```
136In this case, the **Web** component is re-arranged with ArkUI, as shown in Figure 1 and Figure 2.
137
138**Figure 1** Soft keyboard in the default avoidance mode
139
140![default-keyboardavoid](figures/default-keyboardavoid.png)
141
142**Figure 2** Soft keyboard following the avoidance mode of the ArkUI soft keyboard
143
144![arkui-keyboardavoid](figures/arkui-keyboardavoid.png)
145
1462. When the keyboard avoidance mode of **UIContext** is **Offset**, the application can set the keyboard avoidance mode of the **Web** component through the [WebKeyboardAvoidMode()](../reference/apis-arkweb/ts-basic-components-web.md#webkeyboardavoidmode12) API of the **Web** component. This API is at a higher priority than **virtualKeyboard.overlayContens** on the W3C side and accepts the following values:
147
148- **RESIZE_VISUAL**: Only the size of the visual viewport is adjusted, and the size of the layout viewport is not adjusted.
149- **RESIZE_CONTENT**: The size of both the visual viewport and the layout viewport is adjusted.
150- **OVERLAYS_CONTENT**: No viewport size is adjusted, and the soft keyboard overlays the content of the web page.
151
152>**NOTE**
153>
154>The visual viewport refers to the area of the web page that the user is viewing, and the width of this area is equal to the width of the browser window of the mobile device.
155>
156>The layout viewport refers to the width of the web page itself.
157
158(1) Set the soft keyboard avoidance mode of the **Web** component in the application code.
159
160```ts
161// Index.ets
162@Entry
163@Component
164struct KeyboardAvoidExample {
165  controller: web_webview.WebviewController = new web_webview.WebviewController();
166  build() {
167    Column() {
168      Row().height("50%").width("100%").backgroundColor(Color.Gray)
169      Web({ src: $rawfile("index.html"),controller: this.controller})
170        .keyboardAvoidMode (WebKeyboardAvoidMode.OVERLAYS_CONTENT) // The Web component does not adjust the size of any viewport.
171      Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor(Color.Pink).layoutWeight(1)
172    }.width('100%').height("100%")
173  }
174}
175```
176In this case, the **Web** component performs avoidance based on its own avoidance mode settings, as shown in Figure 3.
177
178**Figure 3** Soft keyboard avoidance mode of the **Web** component page
179
180![web-keyboardavoid](figures/web-keyboardavoid.png)
181
182The following are overlapping scenarios with other **Web** component behaviors.
183
184| Overlapping Scenario        | Specifications                                      |
185| ------------ | ---------------------------------------- |
186| Same-layer rendering component        | The soft keyboard avoidance behavior of the same-layer **Web** component is the same as that in common scenarios. The soft keyboard avoidance behavior of the same-layer native component is implemented by ArkUI.|
187| Offscreen component creation      | By default, the soft keyboard avoidance mode used in non-offscreen creation is used. You can set other avoidance modes before attaching the component to the tree.  |
188| customDialog | The **customDialog** component avoids the keyboard by itself.                       |
189| Foldable device         | The soft keyboard avoidance behavior is the same as that in common scenarios. The soft keyboard is opened and closed based on the screen status.   |
190| Soft keyboard docking       | The soft keyboard avoidance behavior is the same as that in common scenarios.                       |
191| Web nested scrolling     | In the nested scrolling scenario, the soft keyboard avoidance mode of the **Web** component is not recommended, including **RESIZE_VISUAL** and **RESIZE_CONTENT**.|
192
193
194
195## Blocking System Soft Keyboard and Custom Soft Keyboard
196
197The application can invoke [onInterceptKeyboardAttach](../reference/apis-arkweb/ts-basic-components-web.md#oninterceptkeyboardattach12) to block the system soft keyboard. On a web page, when an editable element such as the **input** tag is about to trigger the display of the soft keyboard, [onInterceptKeyboardAttach](../reference/apis-arkweb/ts-basic-components-web.md#oninterceptkeyboardattach12) is called. This allows you to manage the soft keyboard and use any of the following options:
198
199- The system soft keyboard with default settings
200- The system soft keyboard with a custom **Enter** key
201- The custom soft keyboard of the application
202
203```ts
204 // xxx.ets
205  import { webview } from '@kit.ArkWeb';
206  import { inputMethodEngine } from '@kit.IMEKit';
207
208  @Entry
209  @Component
210  struct WebComponent {
211    controller: webview.WebviewController = new webview.WebviewController();
212    webKeyboardController: WebKeyboardController = new WebKeyboardController()
213    inputAttributeMap: Map<string, number> = new Map([
214        ['UNSPECIFIED', inputMethodEngine.ENTER_KEY_TYPE_UNSPECIFIED],
215        ['GO', inputMethodEngine.ENTER_KEY_TYPE_GO],
216        ['SEARCH', inputMethodEngine.ENTER_KEY_TYPE_SEARCH],
217        ['SEND', inputMethodEngine.ENTER_KEY_TYPE_SEND],
218        ['NEXT', inputMethodEngine.ENTER_KEY_TYPE_NEXT],
219        ['DONE', inputMethodEngine.ENTER_KEY_TYPE_DONE],
220        ['PREVIOUS', inputMethodEngine.ENTER_KEY_TYPE_PREVIOUS]
221      ])
222
223      /**
224       * Builder for a custom keyboard component
225       */
226      @Builder
227      customKeyboardBuilder() {
228		  // Implement a custom keyboard component and connect it to WebKeyboardController to implement operations such as input, deletion, and close.
229        Row() {
230          Text("Finish")
231            .fontSize(20)
232            .fontColor(Color.Blue)
233            .onClick(() => {
234              this.webKeyboardController.close();
235            })
236          // Insert characters.
237          Button("insertText").onClick(() => {
238            this.webKeyboardController.insertText('insert ');
239          }).margin({
240            bottom: 200,
241          })
242          // Delete characters from the end to the beginning for the length specified by the length parameter.
243          Button("deleteForward").onClick(() => {
244            this.webKeyboardController.deleteForward(1);
245          }).margin({
246            bottom: 200,
247          })
248          // Delete characters from the beginning to the end for the length specified by the length parameter.
249          Button("deleteBackward").onClick(() => {
250            this.webKeyboardController.deleteBackward(1);
251          }).margin({
252            left: -220,
253          })
254          // Insert a function key.
255          Button("sendFunctionKey").onClick(() => {
256            this.webKeyboardController.sendFunctionKey(6);
257          })
258        }
259      }
260
261    build() {
262      Column() {
263        Web({ src: $rawfile('index.html'), controller: this.controller })
264        .onInterceptKeyboardAttach((KeyboardCallbackInfo) => {
265          // Initialize option. By default, the default keyboard is used.
266          let option: WebKeyboardOptions = {
267            useSystemKeyboard: true,
268          };
269          if (!KeyboardCallbackInfo) {
270            return option;
271          }
272
273          // Save the WebKeyboardController. When a custom keyboard is used, this handler is required to control behaviors such as input, deletion, and closing of the keyboard.
274          this.webKeyboardController = KeyboardCallbackInfo.controller
275          let attributes: Record<string, string> = KeyboardCallbackInfo.attributes
276          // Traverse attributes.
277          let attributeKeys = Object.keys(attributes)
278          for (let i = 0; i < attributeKeys.length; i++) {
279            console.log('WebCustomKeyboard key = ' + attributeKeys[i] + ', value = ' + attributes[attributeKeys[i]])
280          }
281
282          if (attributes) {
283            if (attributes['data-keyboard'] == 'customKeyboard') {
284              // Determine the soft keyboard to use based on the attributes of editable HTML elements. For example, if the attribute includes data-keyboard and its value is customKeyboard, use a custom keyboard.
285              console.log('WebCustomKeyboard use custom keyboard')
286              option.useSystemKeyboard = false;
287              // Set the custom keyboard builder.
288              option.customKeyboard = () => {
289                this.customKeyboardBuilder()
290              }
291              return option;
292            }
293
294            if (attributes['keyboard-return'] != undefined) {
295              // Determine the soft keyboard to use based on the attributes of editable HTML elements. For example, if the attribute includes keyboard-return, use the system keyboard and specify the type of the system soft keyboard's Enter key.
296              option.useSystemKeyboard = true;
297              let enterKeyType: number | undefined = this.inputAttributeMap.get(attributes['keyboard-return'])
298              if (enterKeyType != undefined) {
299                option.enterKeyType = enterKeyType
300              }
301              return option;
302            }
303          }
304
305          return option;
306        })
307      }
308    }
309  }
310```
311
312```html
313<!-- index.html -->
314    <!DOCTYPE html>
315    <html>
316
317    <head>
318        <meta charset="utf-8">
319        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
320    </head>
321
322    <body>
323
324    <p style="font-size:12px">input tag. Original default behavior: </p>
325    <input type="text" style="width: 300px; height: 20px"><br>
326    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
327
328    <p style="font-size:12px">input tag. System keyboard with enterKeyType as UNSPECIFIED: </p>
329    <input type="text" keyboard-return="UNSPECIFIED" style="width: 300px; height: 20px"><br>
330    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
331
332    <p style="font-size:12px">input tag. System keyboard with enterKeyType as GO: </p>
333    <input type="text" keyboard-return="GO" style="width: 300px; height: 20px"><br>
334    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
335
336    <p style="font-size:12px">input tag. System keyboard with enterKeyType as SEARCH: </p>
337    <input type="text" keyboard-return="SEARCH" style="width: 300px; height: 20px"><br>
338    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
339
340    <p style="font-size:12px">input tag. System keyboard with enterKeyType as SEND: </p>
341    <input type="text" keyboard-return="SEND" style="width: 300px; height: 20px"><br>
342    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
343
344    <p style="font-size:12px">input tag. System keyboard with enterKeyType as NEXT: </p>
345    <input type="text" keyboard-return="NEXT" style="width: 300px; height: 20px"><br>
346    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
347
348    <p style="font-size:12px">input tag. System keyboard with enterKeyType as DONE: </p>
349    <input type="text" keyboard-return="DONE" style="width: 300px; height: 20px"><br>
350    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
351
352    <p style="font-size:12px">input tag. System keyboard with enterKeyType as PREVIOUS: </p>
353    <input type="text" keyboard-return="PREVIOUS" style="width: 300px; height: 20px"><br>
354    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
355
356    <p style="font-size:12px">input tag. Custom keyboard: </p>
357    <input type="text" data-keyboard="customKeyboard" style="width: 300px; height: 20px"><br>
358
359    </body>
360
361    </html>
362```
363
364Figure 4, Figure 5, and Figure 6 show the ArkWeb custom keyboard examples.
365
366**Figure 4** Custom numeric keyboard
367
368![web-customkeyboardnumber](figures/web-customkeyboardnumber.png)
369
370**Figure 5** Custom alphabetic keyboard
371
372![web-customkeyboardletter](figures/web-customkeyboardletter.png)
373
374**Figure 6** Custom symbol keyboard
375
376![web-customkeyboardsymbol](figures/web-customkeyboardsymbol.png)
377