Anubhaw swarup
Vymo Engineering
Published in
6 min readFeb 2, 2022

--

CHIPS - Auto-Suggestions for Inputs in your forms

“ZERO. That’s exactly how many users love using their keyboards to fill up a form on their mobile device.” How did we take the tedium out of the form filling exercise? In this blog post, I talk about how we rendered user delight to our users by providing suggestions right when they are filling the forms. We did this with Elasticsearch Kafka and ETL.

Context

Filling forms can get tedious. I’m sure you’ve groaned aloud when you had to enter almost the same values again and again on lengthy forms. Let me give just one example: Assume you have to upload the details of 100 people because you have to create their user accounts in your software. Assume that all these people work at the same organization (and, therefore, have the same work address). Now, imagine yourself entering almost the same details over and over again. Tedious, right? Or, take another example: think of a form that needs an email ID. We know emails mostly end with a domain name such as @gmail.com, @outlook.com, @live.com, or @vymo.com. But you might need to supply this information in more than one form. Over and over.

In short, filing forms can quickly become tiresome and, by that very reason, prone to errors.

So, how did we solve this problem? By using what we call Chips. You just tap a chip (from the 5 chips we show you), and it moves in to populate the input field.

Our approach

If you open our Vymo app, you’ll see that the last five options that you selected are shown as chips below the field, just as you are about to fill it again. You tap one of the suggestions, and the value moves in to populate that input field. Every time that you fill that form, the list of values for the last five options gets updated.

How do we decide which input fields should contain these chips? The computation is done at a level that makes sense for that input field. For example, if we’re entering the user details for a group of people who belong to one department AND one section of the department AND in one functional unit within that section, the input field in the User Create form can be department + subsection + function + field . The value for the following input fields types to be served as chips when the forms containing the same are being rendered.

When a form is rendered, some APIs are called and the response contains the chips for multiple input fields.

Design

Here’s how the process works:

  • The several threads that can lead to one input screen and form are maintained separately. For example, a form might be reachable through a creation workflow or an update workflow or a state change of an entity. This information is maintained separately and contributes to one level of logic when fetching chips.
  • Everytime a create, update, or state change happens on a form, an event is triggered with information on the values that were used earlier for the input fields and the state of the form.
  • An Elasticsearch index is maintained to persist the data in a manner which incorporates a list of all possible combinations of attributes that can affect the input field values. If you think back to the previous example, the persistence is done for the following values:
    - The department
    - The subsections of the department
    - The details of the user who is entering the values on the form
    - The form’s position in the entire flow
    - The event for the activity which is being done.
  • The last five entries for that field from the index are fetched, and the query is based on the level information already present in the index.

Flow

chips flow

Elasticsearch (index and query)

All details needed during the query of the fields are persisted in the Elasticsearch index. If you think back to the example I mentioned earlier, the details will be department — subsection — function — event — fieldCode — fieldValue — update date.

We did a bulk query by using the `http://localhost:9200/_msearch` API of Elasticsearch. This API lets us query multiple fields at once and, thereby, handles the network related delays also.

Each Elasticsearch document has a custom unique ID.. We use a custom hashing method to generate this ID and use it to upsert in cases where we get the same value for the same field again. If the same value is entered on the form, we do not create a new entry so that the index is not overloaded with redundant values. An upsert inline painless script with just an update to the last updated date works well in these cases.

inline script for es query

Functions and scoring in Elasticsearch query

While fetching the matching response for the field code and the user, we create a unique scoring mechanism. This mechanism lets us roll up fields that were not touched by the current user or for current function or current event, but still allows the suggestions to be fetched. We wrote functions within an ES query and provided weights to each of the functions. Based on the matches for a document, we calculate the score through the following method:
“score_mode”: “sum”,
“boost_mode”: “replace”

When we have these scores within the same query, we sort the query by these scores and by the updated date, so that we get the most recent amongst the qualifying values. We use “Function_score” in the query to get the result.

The roll up works in the following manner:

If a user has not created a record, the chips are based on the values entered by another user for the same function.

Basic Elasticsearch schema

A generic schema could look like this:

The following schema is specific to the Vymo use case but it can be extended to cover other use cases.

CONCLUSION

And, in this manner, we used Elasticsearch Kafka and ETL to render user delight. See the entire thing in action in the following images.

--

--