How do I add a type ahead field for a form

I am trying to create a type ahead feature for a form on my registration page to allow users to type in the name of the region or city without having to scroll down a huge list. Can you please provide details on how to do so?

In order to create a type ahead field that can dynamically insert values from a Data source we need to take a few steps. First we need to set up the data source with the data in it. In my case I have created a data source with a column called Country with a list of countries in it. i.e.

The following javaScript code is needed to be added to the screen JS.

Note: there are 2 things that need to be changed below. Where it says ‘name’ below it should match the name of the form field name and where it says column it should match the column in the data source. In this case it is also Country.

Fliplet.FormBuilder.get().then(function(form) {
  var typeAheadDataSourceId = 407776; // ID for the data source where the list of values comes from
  //Change the "name" to the name of the form field set in the form settings. 
  //Change Column below to the name of the Column in the Data source where you want to pull the data from
   var typeAheadFields = [
    {
      name: 'Country',
      column: 'Country'
    }
  ];

  return Fliplet.DataSources.connect(typeAheadDataSourceId, { offline: false })
    .then(function(source) {
      return source.find();
    })
    .then(function(rows) {
    
      return rows.map(function(row) {
        return row.data;
      });
    })
    .then(function(rows) {
      typeAheadFields.forEach(function(field, i) {
        var includedColumns = field.populate
          ? field.populate.map(function(toPopulate) {
              return toPopulate.column;
            })
          : [];
        var source = rows.map(function(entry) {
          // Map each data source entry to an object as source for for $.typeahead()
          return {
            name: entry[field.column],
            data: _.pick(entry, includedColumns)
          };
        });
        if (field.unique !== false) {
          // Only include unique options
          source = _.uniqBy(source, 'name');
        }

        if (field.validate !== false) {
          typeAheadFields[i].source = source;
        }

        $('[name="' + field.name + '"]').typeahead({
          source: source,
          fitToElement: true,
          sorter: function(items) {
            // Sort options alphabetically
            return _.orderBy(items, 'name');
          },
          updater: function(item) {
            form.field(field.name).val(item.name);
            if (field.populate) {
              field.populate.forEach(function(toPopulate) {
                form.field(toPopulate.name).val(item.data[toPopulate.column]);
              });
            }
          }
        });
      });
    })
});

One final step is to add this js library to the libraries section of the developer options.

https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js

The end result should look something like this:

Screen Recording 2021-08-12 at 11.41.28 am

This is really helpful! Just to be extra difficult… What is the best way to also make that field multi-select, like it is on the Typeahead screen template?

The reason why I’m not using the screen template is that the data I want to reference is in a different data source, so your method above worked better for that.

Thanks,
Nathan

Hi Nathan,

Have you tried using the Typeahead multi-select form field? It can be connected to a different data source than the form is connected to.

Thanks,
Deb

That’s exactly what I wanted, thank you! Is that a recent feature? The multi-select functionality is brilliant.