DEV Community

HarmonyOS
HarmonyOS

Posted on

Active invocation of the soft keyboard and soft keyboard avoidance in web scenarios

Read the original article:Active invocation of the soft keyboard and soft keyboard avoidance in web scenarios

Requirement Description

In the development process of HarmonyOS Web, it is inevitable to handle the issues of soft keyboard invocation and avoidance. In the Web domain, there are two relatively unique scenarios regarding the soft keyboard — proactively invoking the keyboard upon entering a page and keyboard avoidance for H5 pages. This article mainly provides reference implementations and solutions for these two specific cases.

Background Knowledge

The Web component can be used to register application-side code into the frontend page. After registration, the frontend can invoke application-side functions using the registered object name, enabling frontend-to-application communication.

By setting the safe area type to SafeAreaType.KEYBOARD, components can extend their safe area accordingly. Note that this property will not take effect if the parent container is a scrollable container.

This allows implementation of custom soft keyboard avoidance modes. However, note that this interface is ineffective when the UIContext’s keyboard avoidance mode is set to KeyboardAvoidMode.RESIZE.

This module mainly serves foreground applications (such as Notes, Messages, Settings, and third-party apps) to control and manage input methods, including showing/hiding the keyboard, switching input methods, retrieving the list of available input methods, and more.

Implementation Steps

This article analyzes two frequently encountered scenarios — proactive soft keyboard invocation on H5 pages and keyboard avoidance in H5 interfaces — and provides corresponding reference implementations.

  • Proactive keyboard invocation when an input field exists on an H5 page:

You can use the Web component’s onPageEnd() callback in conjunction with the @ohos.inputMethod framework’s showTextInput() method to automatically focus the input box and invoke the keyboard once the page loads. The inputMethod.TextConfig can configure keyboard input field styles, and the attach() method binds the custom-drawn control to the input method.

  • Keyboard avoidance for H5 pages:

There are four main approaches, each with different effects:

Method 1: Set the Web component’s property layoutWeight(1). This defines how much space the component occupies in the parent container’s main axis direction, adapting to fill remaining space dynamically.

  Web({
        src: $rawfile('index.html'),
        controller: this.controller,
      })
        .domStorageAccess(true)
        .height('100%')
        .backgroundColor(Color.Yellow)
        .layoutWeight(1)
    }
Enter fullscreen mode Exit fullscreen mode

Method 2: Set the safe area type. You can achieve keyboard avoidance by configuring the Web component with expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]).

  Web({
        src: $rawfile('index.html'),
        controller: this.controller,
      })
        .domStorageAccess(true)
        .height('100%')
        .backgroundColor(Color.Yellow)
        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])
  }
Enter fullscreen mode Exit fullscreen mode

Method 3: In EntryAbility.ets, use setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE) in onWindowStageCreate to compress the page size by the keyboard’s height when the keyboard is raised.

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err) => {
      windowStage.getMainWindowSync().getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE)
    });
  }
Enter fullscreen mode Exit fullscreen mode

Method 4: Modify the keyboard avoidance mode by setting the Web component’s property keyboardAvoidMode(WebKeyboardAvoidMode.RESIZE_VISUAL) to adjust the visible area dynamically when the keyboard appears.

  Web({
        src: $rawfile('index.html'),
        controller: this.controller,
      })
        .domStorageAccess(true)
        .height('100%')
        .backgroundColor(Color.Yellow)
        .keyboardAvoidMode(WebKeyboardAvoidMode.RESIZE_VISUAL)
Enter fullscreen mode Exit fullscreen mode

Code Snippet

  • App-side code:
  import { webview } from '@kit.ArkWeb';
  import { inputMethod } from '@kit.IMEKit';
  import { BusinessError } from '@kit.BasicServicesKit';

  let inputMethodController = inputMethod.getController();
  @Entry
  @Component
  struct WebComponent {
    controller: webview.WebviewController = new webview.WebviewController();
    aboutToAppear(): void {
      webview.WebviewController.setWebDebuggingAccess(true)
      try {
        let textConfig: inputMethod.TextConfig = {
          inputAttribute: {
            textInputType: 0,
            enterKeyType: 1
          }
        };
        inputMethodController.attach(true, textConfig, (err: BusinessError) => {
          if (err) {
            console.error(`Failed to attach: ${err.code} ${err.message}`);
            return;
          }
          console.info('Succeeded in attaching the inputMethod.');
        });
      } catch(err) {
        console.error(`Failed to attach: ${err.code} ${err.message}`);
      }
    }
    build() {
      Scroll() {
        Column() {
          Web({
            src: $rawfile('demo.html'),
            controller: this.controller,
          })
            .onPageEnd(() => {
              inputMethodController.showTextInput().then(() => {
                console.info('Succeeded in showing text input.');
              }).catch((err: BusinessError) => {
                console.error(`Failed to showTextInput: ${err.code} ${err.message}}`);
              });
            })
            .domStorageAccess(true)
            .height('100%')
        }
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

HTML code:

  <!doctype html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport"
            content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
  </head>
  <body>
  <h1>H5 Side</h1>
  <div>
      <input id="myInput" type="text" value="" style="margin:10px 0" onload/><br/>
  </div>
  </body>
  <script>
      function test(){
            document.getElementById("myInput").focus();
         }
      // Execute immediately when the document is loaded
      document.addEventListener('DOMContentLoaded', test);
  </script>
  </html>
  <style>
      body{
          width:100%;
          height:auto;
          margin:50px auto;
          text-align:center;
      }
  </style>
Enter fullscreen mode Exit fullscreen mode

Limitations or Considerations

This sample supports API Version 19 Release and above.

This sample supports HarmonyOS 5.1.1 Release SDK and above.

Compilation and execution require DevEco Studio 5.1.1 Release or later.

Written by Bunyamin Akcay

Top comments (0)