The Text Input widget lets your add-on read and react to text that users provide. You can configure these widgets to provide users automatic suggestions for input text.
The suggestions provided can come from a static list of strings you provide. Alternatively, you can build the suggestions from context, such as the text the user has already typed into the widget.
Configuring suggestions
Configuring suggestions for a text input only requires that you do the following:
- Create a list of suggestions by:
- Creating a static list, and/or
- Defining an action with a callback function that builds that list dynamically from context.
- Attach the suggestions list and/or action to the text input widget.
If you provide both a static list of suggestions and an action, the application UI uses the static list until the user starts entering characters, whereupon the callback function is used and the static list is ignored.
Static suggestions
To offer a static list of suggestions, you only need to do the following:
- Create a
Suggestions
object. - Add each static suggestion to it using
addSuggestion()
oraddSuggestions()
. - Attach the
Suggestions
object to the widget usingTextInput.setSuggestions()
.
The UI displays static suggestions in the order in which they were added. The UI also automatically performs case-insensitive prefix matching and filters the suggestion list as the user types characters into the widget.
Suggestion actions
If you aren't using a static suggestion list, you must define an action to build your suggestions dynamically. You can do this by following these steps:
- Create an
Action
object and associate it with an callback function you define. - Call the widget's
TextInput.setSuggestionsAction()
function, providing it theAction
object. - Implement the callback function to build the suggestion list and return
a built
SuggestionsResponse
object.
The UI calls the callback function whenever the user types a character into the text input, but only after the user has stopped typing for a moment. The callback function receives an event object containing information about the open card's widgets. See Action event objects for details.
The callback function must return a valid SuggestionsResponse
object containing the list of suggestions to display. The UI displays
suggestions in the order that they are added. Unlike static lists, the UI does
not conduct any automatic filtering of callback suggestions based on the user
input. If you want to have such filtering, you must read the text input value
from the event object and filter your suggestions as you construct the list.
Example
The following Google Workspace add-on code snippet shows how to configure suggestions on two different text input widgets, the first with a static list and the second using a callback function:
//
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!
}
Suggestions and OnChangeAction()
Text input widgets can have a setOnChangeAction()
handler function defined that executes whenever the widget loses focus.
If this handler and suggestions are both enabled for the same text input, the
following rules define the text input interaction behavior:
- The
setOnChangeAction()
handler executes after a suggestion is selected. - If the user presses Enter (or otherwise makes the text input lose focus)
without modifying the selected suggestion,
setOnChangeAction()
doesn't trigger again. -
setOnChangeAction()
does trigger again if the user, after selecting a suggestion, edits it so that it no longer matches any of the suggestions in the list. - If the user doesn't select a suggestion,
setOnChangeAction()
triggers when the text input loses focus.