• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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: You can set 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, you 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. The default value is **text**.
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 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 is displayed at the bottom of the screen, and the user can enter text on the screen.
68>
69>The **type** attribute affects the keyboard display, input validation, and element appearance.
70>
71>The **inputmode** is used to optimize the keyboard input experience on mobile devices and does not affect the basic input behavior or verification.
72
73
74## Automatically Displaying the Soft Keyboard
75To improve user experience, you can invoke the [showTextInput()](../reference/apis-ime-kit/js-apis-inputmethod.md#showtextinput10) API to automatically display the soft keyboard after the page is loaded.
76
77```html
78<!-- index.html -->
79<!DOCTYPE html>
80<html>
81  <head>
82    <title>Test Web Page</title>
83  </head>
84  <body>
85    <h1>DEMO</h1>
86    <input type="text" id="input_a">
87  </body>
88</html>
89```
90
91```ts
92//Index.ets
93import { webview } from '@kit.ArkWeb';
94import { inputMethod } from '@kit.IMEKit';
95
96@Entry
97@Component
98struct WebComponent {
99  controller: webview.WebviewController = new webview.WebviewController();
100  build() {
101    Column() {
102      Web({ src: $rawfile("index.html"), controller: this.controller})
103        .onPageEnd(() => {
104          this.controller.runJavaScript(`document.getElementById('input_a').focus()`).then(() => {
105            setTimeout(() => {
106              inputMethod.getController().showTextInput();
107            }, 10);
108          });
109        });
110    }
111  }
112}
113```
114
115## Setting the Avoidance Mode for the Soft Keyboard
116
117On a mobile device, you can set the avoidance mode for the soft keyboard on the web page.
118
1191. 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.
120
121- 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.
122- 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.
123
124(1) Set the soft keyboard avoidance mode of **UIContext**.
125
126```ts
127// EntryAbility.ets
128import { KeyboardAvoidMode } from '@kit.ArkUI';
129import { hilog } from '@kit.PerformanceAnalysisKit';
130
131onWindowStageCreate(windowStage: window.WindowStage) {
132  hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
133
134  windowStage.loadContent('pages/Index', (err, data) => {
135    let keyboardAvoidMode = windowStage.getMainWindowSync().getUIContext().getKeyboardAvoidMode();
136    // When the soft keyboard is displayed, the application window is resized to its original height minus the keyboard height.
137  windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE);
138    if (err.code) {
139      hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
140      return;
141    }
142    hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
143  });
144}
145```
146(2) Enable the soft keyboard in the **Web** component.
147
148```html
149<!-- index.html -->
150<!DOCTYPE html>
151<html>
152  <head>
153    <title>Test Web Page</title>
154  </head>
155  <body>
156    <h1>DEMO</h1>
157    <input type="text" id="input_a">
158  </body>
159</html>
160```
161
162```ts
163//Index.ets
164import { webview } from '@kit.ArkWeb';
165
166@Entry
167@Component
168struct KeyboardAvoidExample {
169  controller: webview.WebviewController = new webview.WebviewController();
170  build() {
171    Column() {
172      Row().height("50%").width("100%").backgroundColor(Color.Gray)
173      Web({ src: $rawfile("index.html"),controller: this.controller})
174      Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor(Color.Pink).layoutWeight(1)
175    }.width('100%').height("100%")
176  }
177}
178```
179The **Web** component is re-arranged with ArkUI, as shown in Figure 1 and Figure 2.
180
181**Figure 1** Soft keyboard in the default avoidance mode
182
183![default-keyboardavoid](figures/default-keyboardavoid.png)
184
185**Figure 2** Soft keyboard following the avoidance mode of the ArkUI soft keyboard
186
187![arkui-keyboardavoid](figures/arkui-keyboardavoid.png)
188
1892. 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/arkts-basic-components-web-e.md#webkeyboardavoidmode12) API of the **Web** component. This API is at a higher priority than **virtualKeyboard.overlayContens** on the W3C side.
190
191- **RESIZE_VISUAL**: Only the size of the visual viewport is adjusted, and the size of the layout viewport is not adjusted.
192- **RESIZE_CONTENT**: The size of both the visual viewport and the layout viewport is adjusted.
193- **OVERLAYS_CONTENT**: No viewport size is adjusted, and the soft keyboard overlays the content of the web page.
194
195>**NOTE**
196>
197>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.
198>
199>The layout viewport refers to the width of the web page itself.
200
201Set the soft keyboard avoidance mode of the **Web** component in the application code.
202
203```ts
204// Index.ets
205import { webview } from '@kit.ArkWeb';
206
207@Entry
208@Component
209struct KeyboardAvoidExample {
210  controller: webview.WebviewController = new webview.WebviewController();
211  build() {
212    Column() {
213      Row().height("50%").width("100%").backgroundColor(Color.Gray)
214      Web({ src: $rawfile("index.html"),controller: this.controller})
215        .keyboardAvoidMode (WebKeyboardAvoidMode.OVERLAYS_CONTENT) // The Web component does not adjust the size of any viewport.
216      Text("I can see the bottom of the page").width("100%").textAlign(TextAlign.Center).backgroundColor(Color.Pink).layoutWeight(1)
217    }.width('100%').height("100%")
218  }
219}
220```
221The **Web** component performs avoidance based on its avoidance mode, as shown in Figure 3.
222
223**Figure 3** Soft keyboard avoidance mode of the **Web** component page
224
225![web-keyboardavoid](figures/web-keyboardavoid.png)
226
2273. When the soft keyboard is displayed, you can call [expandSafeArea()](../reference/apis-arkui/arkui-ts/ts-universal-attributes-expand-safe-area.md#expandsafearea) to expand the safe area of the **Web** component to prevent the **Web** component from avoiding the soft keyboard. For more examples, see [Calculating and Adjusting Safe Area Insets](../web/web-safe-area-insets.md).
228
229  ```ts
230  // xxx.ets
231  import { webview } from '@kit.ArkWeb';
232
233  @Entry
234  @Component
235  struct WebComponent {
236    controller: webview.WebviewController = new webview.WebviewController();
237
238    build() {
239      Column() {
240        Web({ src: 'www.example.com', controller: this.controller })
241          .width('100%').height('100%')
242          .expandSafeArea([SafeAreaType.KEYBOARD, SafeAreaType.SYSTEM])
243      }
244    }
245  }
246  ```
247
248
249The following are interaction scenarios with other **Web** component behaviors.
250
251| Overlapping Scenario        | Specifications                                      |
252| ------------ | ---------------------------------------- |
253| Same-layer rendering component        | The soft keyboard avoidance mode of the same-layer **Web** component is the same as that in common scenarios.<br></div>The soft keyboard avoidance mode of the same-layer system component is implemented by ArkUI.|
254| 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.  |
255| customDialog | The **customDialog** component avoids the keyboard by itself.                       |
256| 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.   |
257| Soft keyboard docking       | The soft keyboard avoidance behavior is the same as that in common scenarios.                       |
258| 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**.|
259
260
261
262## Blocking System Soft Keyboard and Custom Soft Keyboard
263
264An application can invoke the [onInterceptKeyboardAttach](../reference/apis-arkweb/arkts-basic-components-web-events.md#oninterceptkeyboardattach12) API to control the display of the soft keyboard and use any of the following options:
265
266- The system soft keyboard with default settings
267- The system soft keyboard with a custom **Enter** key
268- The custom soft keyboard of the application
269
270```ts
271  // Index.ets
272  import { webview } from '@kit.ArkWeb';
273  import { inputMethodEngine } from '@kit.IMEKit';
274
275  @Entry
276  @Component
277  struct WebComponent {
278    controller: webview.WebviewController = new webview.WebviewController();
279    webKeyboardController: WebKeyboardController = new WebKeyboardController();
280    inputAttributeMap: Map<string, number> = new Map([
281        ['UNSPECIFIED', inputMethodEngine.ENTER_KEY_TYPE_UNSPECIFIED],
282        ['GO', inputMethodEngine.ENTER_KEY_TYPE_GO],
283        ['SEARCH', inputMethodEngine.ENTER_KEY_TYPE_SEARCH],
284        ['SEND', inputMethodEngine.ENTER_KEY_TYPE_SEND],
285        ['NEXT', inputMethodEngine.ENTER_KEY_TYPE_NEXT],
286        ['DONE', inputMethodEngine.ENTER_KEY_TYPE_DONE],
287        ['PREVIOUS', inputMethodEngine.ENTER_KEY_TYPE_PREVIOUS]
288      ])
289
290      /**
291       * Builder for a custom keyboard component
292       */
293      @Builder
294      customKeyboardBuilder() {
295		  // Implement a custom keyboard component and connect it to WebKeyboardController to implement operations such as input, deletion, and close.
296        Row() {
297          Text("Finish")
298            .fontSize(20)
299            .fontColor(Color.Blue)
300            .onClick(() => {
301              this.webKeyboardController.close();
302            })
303          // Insert characters.
304          Button("insertText").onClick(() => {
305            this.webKeyboardController.insertText('insert ');
306          }).margin({
307            bottom: 200,
308          })
309          // Delete characters from the end to the beginning for the length specified by the length parameter.
310          Button("deleteForward").onClick(() => {
311            this.webKeyboardController.deleteForward(1);
312          }).margin({
313            bottom: 200,
314          })
315          // Delete characters from the beginning to the end for the length specified by the length parameter.
316          Button("deleteBackward").onClick(() => {
317            this.webKeyboardController.deleteBackward(1);
318          }).margin({
319            left: -220,
320          })
321          // Insert a function key.
322          Button("sendFunctionKey").onClick(() => {
323            this.webKeyboardController.sendFunctionKey(6);
324          })
325        }
326      }
327
328    build() {
329      Column() {
330        Web({ src: $rawfile('index.html'), controller: this.controller })
331        .onInterceptKeyboardAttach((KeyboardCallbackInfo) => {
332          // Initialize option. By default, the default keyboard is used.
333          let option: WebKeyboardOptions = {
334            useSystemKeyboard: true,
335          };
336          if (!KeyboardCallbackInfo) {
337            return option;
338          }
339
340          // 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.
341          this.webKeyboardController = KeyboardCallbackInfo.controller;
342          let attributes: Record<string, string> = KeyboardCallbackInfo.attributes;
343          // Traverse attributes.
344          let attributeKeys = Object.keys(attributes);
345          for (let i = 0; i < attributeKeys.length; i++) {
346            console.log('WebCustomKeyboard key = ' + attributeKeys[i] + ', value = ' + attributes[attributeKeys[i]]);
347          }
348
349          if (attributes) {
350            if (attributes['data-keyboard'] == 'customKeyboard') {
351              // 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.
352              console.log('WebCustomKeyboard use custom keyboard');
353              option.useSystemKeyboard = false;
354              // Set the custom keyboard builder.
355              option.customKeyboard = () => {
356                this.customKeyboardBuilder()
357              }
358              return option;
359            }
360
361            if (attributes['keyboard-return'] != undefined) {
362              // 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.
363              option.useSystemKeyboard = true;
364              let enterKeyType: number | undefined = this.inputAttributeMap.get(attributes['keyboard-return']);
365              if (enterKeyType != undefined) {
366                option.enterKeyType = enterKeyType;
367              }
368              return option;
369            }
370          }
371
372          return option;
373        })
374      }
375    }
376  }
377```
378
379```html
380<!-- index.html -->
381    <!DOCTYPE html>
382    <html>
383
384    <head>
385        <meta charset="utf-8">
386        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
387    </head>
388
389    <body>
390
391    <p style="font-size:12px">input tag. Original default behavior: </p>
392    <input type="text" style="width: 300px; height: 20px"><br>
393    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
394
395    <p style="font-size:12px">input tag. System keyboard with enterKeyType as UNSPECIFIED: </p>
396    <input type="text" keyboard-return="UNSPECIFIED" style="width: 300px; height: 20px"><br>
397    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
398
399    <p style="font-size:12px">input tag. System keyboard with enterKeyType as GO: </p>
400    <input type="text" keyboard-return="GO" style="width: 300px; height: 20px"><br>
401    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
402
403    <p style="font-size:12px">input tag. System keyboard with enterKeyType as SEARCH: </p>
404    <input type="text" keyboard-return="SEARCH" style="width: 300px; height: 20px"><br>
405    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
406
407    <p style="font-size:12px">input tag. System keyboard with enterKeyType as SEND: </p>
408    <input type="text" keyboard-return="SEND" style="width: 300px; height: 20px"><br>
409    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
410
411    <p style="font-size:12px">input tag. System keyboard with enterKeyType as NEXT: </p>
412    <input type="text" keyboard-return="NEXT" style="width: 300px; height: 20px"><br>
413    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
414
415    <p style="font-size:12px">input tag. System keyboard with enterKeyType as DONE: </p>
416    <input type="text" keyboard-return="DONE" style="width: 300px; height: 20px"><br>
417    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
418
419    <p style="font-size:12px">input tag. System keyboard with enterKeyType as PREVIOUS: </p>
420    <input type="text" keyboard-return="PREVIOUS" style="width: 300px; height: 20px"><br>
421    <hr style="height:2px;border-width:0;color:gray;background-color:gray">
422
423    <p style="font-size:12px">input tag. Custom keyboard: </p>
424    <input type="text" data-keyboard="customKeyboard" style="width: 300px; height: 20px"><br>
425
426    </body>
427
428    </html>
429```
430
431Figure 4, Figure 5, and Figure 6 show the ArkWeb custom keyboard examples.
432
433**Figure 4** Custom numeric keyboard
434
435![web-customkeyboardnumber](figures/web-customkeyboardnumber.png)
436
437**Figure 5** Custom alphabetic keyboard
438
439![web-customkeyboardletter](figures/web-customkeyboardletter.png)
440
441**Figure 6** Custom symbol keyboard
442
443![web-customkeyboardsymbol](figures/web-customkeyboardsymbol.png)
444