Skip to content

Input widgets

Input widgets are specialized controls which can be presented to the user at any time, as part of the conversation. They are presented as alternative keyboards, meaning that the normal input control is hidden and the input widget is shown instead.

To see all input widgets in action and try them out, visit the Web client demonstration bot.

An an example, when your conversation needs to get a user's location, it is nice to present a specialized location picker widget for sending the location, which includes a map and the user's current position:

In another dialog, you might require the user to make a multiple-choice selection using checkboxes. You could use the item picker widget for this case.

We also might want to present an entire form to the user at once. We can use the form input method for that, which looks like this:

Not all input widgets are supported on each platform that DialoX connects to. On platforms other than the web, the input widgets might not work. Refer to the channel-specific documentation to see which input widgets work on which channel.

Input widgets in Bubblescript

Input widgets are triggered by passing a special input method value to the expecting: clause of the ask statement:

  choices = input_method("item_picker",
    caption: "Please select",
    mode: "multiple",
    items: [
      [title: "Frontend developer", subtitle: "React, HTML, Javascript", value: "frontend"],
      [title: "Backend developer", subtitle: "Elixir, Erlang, bash…", value: "backend"],
      [title: "Marketing manager", subtitle: "Hubspot and Facebook marketing", value: "marketing"]
    ])
  ask "Which positions are you interesed in?", expecting: choices

The choices variable here is filled using the input_method function, which takes the input widget type as the first argument, and the configuration of the widget as the second argument.

When the user submits the input widget, the user's selection is stored in the answer.data variable.

Defining input widgets in data files

Instead of defining the widget in code like this, it is often easier to cleaner to create a YAML file and put the configuration in there:

  ask "Which positions are you interesed in?",
    expecting: input_method("item_picker", @item_picker)

Where the item_picker.yaml file contains:

caption: Please select
mode: multiple
items:
  - title: Frontend developer
    value: frontend
  - title: Backend developer
    value: backend
  - title: Marketing manager
    value: marketing

Input method reference

The function input_method(method, options) constructs a data structure which triggers the showing of an input widget. It validates the given options at runtime, to ensure that the widgets can be presented in a sensible manner.

  # construct the item picker input widget
  choices = input_method("item_picker", items: ["A", "B", "C"])
  # feed it to 'ask'
  ask "Pick one item:", expecting: choices

The result of the input is stored in the answer.data variable. If this variable is empty (nil), the user has cancelled the input widget (by clicking the cross icon).

The currently supported input methods are "item_picker", "location" and "form". The options to these are described below.

Common properties

All input widgets have some options shared between them:

  • required — Whether we require a value from the user or not. When the input is not required, a close button is shown in the top-right corner, allowing the user to cancel the interaction.
  • default_value — The preset value for the widget
  • height — A string, describing the desired height of the widget. Either compact, tall or full. Defaults to compact.
  • caption — An optional caption which is displayed as a title bar on top of the widget.
  • class — An optional CSS class which is set on the input widget. Can be used to tweak the styling for a particular widget.
  • button_label — The label of the submit button below the control

Item picker

The item_picker input method is a versatile widget which can be used in single and multiple selection mode.

Besides the common input widget options, it takes these extra options:

  • mode — either single or multiple; defaults to single.
  • confirm — In the case of single, this is a boolean value which can be set to true to show a confirmation button to confirm selection of the item. Otherwise, clicking the item immediately picks it.
  • items — The array of items that the user can choose from. The list can be either a list of plain strings, or it can be a list of maps with value, title elements (and optionally a subtitle).
  • last_item — How the last item in a multiple item picker behaves: either "default" or "exclusive". If last_item == "exclusive", it means that selecting the last item will unselect all other items, and selecting another item will unselect the last item.

Location selector

The location input method allows the user to pick a geographical location on the map.

Besides the common input widget options, it takes these extra options:

  • center — lat/lng coordinate that sets the initial position on the map
  • zoom — the initial zoom level, a number between 1 and 20. defaults to 12.

When triggered, the location selector asks permission to retrieve the user's location, and centers the map on that location. The center option is only used as fallback when the user has denied this permission.

Date picker

The date_picker input method is a widget which can be used to let the user pick a single date.

Besides the common input widget options, it takes these extra options:

  • confirm — A boolean value which can be set to true to show a confirmation button to confirm selection of the date. Otherwise, clicking the date immediately picks it.
  • constraints — An array of strings which specify the constraints of the date to be picked. At the moment, the following values are understood:

  • only_future - only enable dates after today

  • only_past - only enable dates before today
  • weekends - only enable saturdays and sundays
  • workdays - only enable monday through friday

These constraints can be combined. For instance, you can have the user select only workdays in the future by setting constraints to the array ["only_future", "workdays"].

Of course, some constraints do not make sense to combine (weekends + workdays for example.

Form

The form input method presents an entire form to the user inside the conversation. This can be used to let the user answer multiple questions at once, for instance, to ask somebody for his address details.

Under the hood, this uses the React JSON Schema Form library. So most options described there are functional and usable in this input widget. The Form customization section especially, goes into detail on the available customization options.

The form input method takes the following options:

  • schema — The JSON schema that the form adheres to.
  • ui_schema — Extra user interface options for the schema, see Form customization.

Form example

An example of a form input (as it is depicted in the image further up) is the following:

  ask "Please enter your address", expecting: input_method("form", @address)

Where address.yaml contains:

caption: Shipping address
height: tall
schema:
  type: object
  properties:
    street:
      type: string
      title: Street
    city:
      type: string
      title: City
    method:
      type: string
      title: "Shipping method"
      enum: ["Airplane", "Boat"]
    comments:
      type: string
      title: "Note"
  required: ["street", "city"]
ui_schema:
  ui:order:
    - street
    - city
    - "*"
  comments:
    ui:widget: textarea

Phone number widget

In the form, a special UI widget can be used to add a phone number input:

@form %{
  caption: "Get phone number",
  height: "compact",
  schema: %{
    properties: %{
      phone: %{
        type: "string",
        title: "Phone number",
        # OPTIONAL: only accept dutch numbers
        pattern: "^\\+31[\\d]{9}$"
      },
    }
  },
  ui_schema: %{
    phone: %{
      "ui:widget": "phone_number"
    },
  }
}

dialog main do
  say "Fill out this form"
  await input_method("form", @form)
  say answer.data.phone
end

IBAN number widget

In the form, a special UI widget can be used to add a iban number input:

@form %{
  caption: "Get IBAN number",
  schema: %{
    properties: %{
      iban: %{
        type: "string",
        title: "IBAN account number"
      },
    }
  },
  ui_schema: %{
    iban: %{
      "ui:widget": "iban_number"
    },
  }
}

dialog main do
  say "Fill out this form"
  await input_method("form", @form)
  say answer.data.iban
end

Date picker form widget

In the form, a special UI widget can be used to let the user select a date:

@form %{
  caption: "Get date",
  schema: %{
    properties: %{
      date: %{
        type: "string",
        title: "Start date"
      },
    }
  },
  ui_schema: %{
    date: %{
      "ui:widget": "date_picker",
      "ui:options": %{
        constraints: ["only_future"]
      }
    },
  }
}

dialog main do
  say "Fill out this form"
  await input_method("form", @form)
  say answer.data.date
end

The constraints key in the widget's ui:options is the same as in the date picker input method and allows you to place specific constraints on the date that is to be picked.

Wait control

The wait control is a blocking interface widget which blocks the user from proceeding further. It can show a large spinner, to indicate that somethings is busy in the background and the user needs to wait.

This control can be shown like this with the following code:

dialog please_wait do
  button = [
    title: "Button 1",
    type: "event",
    event: "button1"
  ]

  await input_method("wait",
    caption: "Please wait until an operator arrives",
    description: "Please be patient, this can take up to…",
    wait_time: 300,
    button: button
  )
end

This input method has the following options:

  • caption — the caption that is displayed on top of the input control.
  • description — a longer text that can be displayed below the spinner.
  • required — whether or not to display the "x" close button next to the header. Defaults to true.
  • wait_time - An optional number, the amount in seconds to wait. When given, it will display a countdown timer inside the spinner, like in the screenshow. If the countdown reaches zero, the dialog continues, with a timeout message being given as answer to the chat process. When given wait_time: 0, no countdown will be shown and the control will be shown indefinitely. When wait_time is omitted, no spinner is shown.
  • button — an optional button that can be given, to show a large button below the control. The button can fire an event or can open a link, like normal buttons do.

Conversation closed control

This input control is similar to the wait control, except that it cannot be cancelled by the user. It will not show a spinner, but a checkmark instead.

This control can be shown like this with the following code:

dialog closed do
  await input_method("closed",
    caption: "Conversation closed",
    description: "Thank you for your time! See you later."
  )
end

Its options are quite similar to the wait control:

  • caption — the caption that is displayed on top of the input control.
  • description — a longer text that can be displayed below the checkmark.
  • button — an optional button that can be given, to show a large button below the control. The button can fire an event or can open a link, like normal buttons do.
  • show_qr — when there's a button with type: "web_url", it will render this button as a QR code on desktop (and a regular button on mobile).

Numeric input

This input control shows an alternative keyboard with the numeric keypad.

This control can be shown with the following code:

dialog main do
  ask "Enter up to 4 numbers:", expecting: input_method("numeric", num_digits: 4)
end

It works similarly to a regular numeric input. On the phone channel, this method can be used to capture a longer (>2) sequence of DTMF characters.

This input method has the following options:

  • caption — the caption that is displayed on top of the input control.
  • required — whether or not to display the "x" close button next to the header. Defaults to true.
  • num_digits — controls the maximum number of digits that can be entered.
  • finish_on_key — pressing this key will send the earlier entered numbers. For use in IVR scenario's, "Enter the number and press #".