针对文本输入的自动补全建议

借助 Text Input 微件,您的插件可以读取用户提供的文本并做出响应。您可以配置这些 widget,以为用户提供输入文本的自动建议。

提供的建议可能来自您提供的字符串的静态列表。或者,您也可以从上下文(例如用户已在 widget 中输入的文本)构建建议。

配置建议

您只需执行以下操作即可配置文本输入的建议:

  • 通过以下方式创建建议列表:
    • 创建静态列表,和/或
    • 使用可根据上下文动态构建列表的回调函数定义操作
  • 将建议列表和/或操作附加到文本输入 widget。

如果您同时提供静态建议列表和一项操作,则应用界面会使用静态列表,直到用户开始输入字符,随后系统将使用回调函数并忽略静态列表。

静态建议

如需提供静态建议列表,您只需执行以下操作:

  1. 创建一个 Suggestions 对象。
  2. 使用 addSuggestion()addSuggestions() 将每条静态建议添加到其中。
  3. 使用 TextInput.setSuggestions()Suggestions 对象附加到 widget。

界面会按添加顺序显示静态建议。当用户在 widget 中输入字符时,界面还会自动执行不区分大小写的前缀匹配,并过滤建议列表。

建议操作

如果您未使用静态建议列表,则必须定义一项操作来动态构建建议。您可按以下步骤实现这一目的:

  1. 创建一个 Action 对象,并将其与您定义的回调函数相关联。
  2. 调用 widget 的 TextInput.setSuggestionsAction() 函数,并为其提供 Action 对象。
  3. 实现回调函数以构建建议列表并返回构建的 SuggestionsResponse 对象。

每当用户在文本输入中输入字符时,界面都会调用回调函数,但只能在用户停止输入一段时间后调用。回调函数会收到一个事件对象,其中包含有关已打开卡片的 widget 的信息。如需了解详情,请参阅操作事件对象

该回调函数必须返回一个有效的 SuggestionsResponse 对象,其中包含要显示的建议列表。界面会按照添加顺序显示建议。与静态列表不同,界面不会根据用户输入对回调建议执行任何自动过滤。如果您希望进行此类过滤,则必须从事件对象中读取文本输入值,并在构建列表时过滤建议。

示例

以下 Google Workspace 插件代码段展示了如何在两个不同的文本输入 widget(第一个使用静态列表,第二个使用回调函数)上配置建议:

// Create an input with a static suggestion list.
var textInput1 = CardService.newTextInput()
    .setFieldName('colorInput')
    .setTitle('Color choice')
    .setSuggestions(CardService.newSuggestions()
        .addSuggestion('Red')
        .addSuggestion('Yellow')
        .addSuggestions(['Blue', 'Black', 'Green']));

// Create an input with a dynamic suggestion list.
var action = CardService.newAction()
    .setFunctionName('refreshSuggestions');
var textInput2 = CardService.newTextInput()
    .setFieldName('emailInput')
    .setTitle('Email')
    .setSuggestionsAction(action);

// ...

/**
 *  Build and return a suggestion response. In this case, the suggestions
 *  are a list of emails taken from the To: and CC: lists of the open
 *  message in Gmail, filtered by the text that the user has already
 *  entered. This method assumes the Google Workspace
 *  add-on extends Gmail; the add-on only calls this method for cards
 *  displayed when the user has entered a message context.
 *
 *  @param {Object} e the event object containing data associated with
 *      this text input widget.
 *  @return {SuggestionsResponse}
 */
 function refreshSuggestions(e) {
   // Activate temporary Gmail scopes, in this case so that the
   // open message metadata can be read.
   var accessToken = e.gmail.accessToken;
   GmailApp.setCurrentMessageAccessToken(accessToken);

   var userInput = e && e.formInput['emailInput'].toLowerCase();
   var messageId = e.gmail.messageId;
   var message = GmailApp.getMessageById(messageId);

   // Combine the comma-separated returned by these methods.
   var addresses = message.getTo() + ',' + message.getCc();

   // Filter the address list to those containing the text the user
   // has already entered.
   var suggestionList = [];
   addresses.split(',').forEach(function(email) {
     if (email.toLowerCase().indexOf(userInput) !== -1) {
       suggestionList.push(email);
     }
   });
   suggestionList.sort();

   return CardService.newSuggestionsResponseBuilder()
       .setSuggestions(CardService.newSuggestions()
           .addSuggestions(suggestionList))
       .build();  // Don't forget to build the response!
 }

建议和OnChangeAction()

文本输入 widget 可以定义一个 setOnChangeAction() 处理程序函数,该函数会在 widget 失去焦点时执行。如果同时为同一文本输入启用了此处理程序和建议,则以下规则将定义文本输入互动行为:

  1. setOnChangeAction() 处理脚本会在用户选择建议后执行。
  2. 如果用户在未修改所选建议的情况下按了 Enter 键(或以其他方式使文本输入失去焦点),则 setOnChangeAction() 不会再次触发。
  3. 如果用户在选择建议后对其进行了修改,使其不再与列表中的任何建议匹配,则 setOnChangeAction() 会再次触发。
  4. 如果用户未选择建议,系统会在文本输入失去焦点时触发 setOnChangeAction()