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 184 185**Figure 2** Soft keyboard following the avoidance mode of the ArkUI soft keyboard 186 187 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 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 436 437**Figure 5** Custom alphabetic keyboard 438 439 440 441**Figure 6** Custom symbol keyboard 442 443 444