AMP
  • websites

amp-autocomplete

Introduction

An autocomplete-enabled input field suggests completed results corresponding to the user input as they type into the input field.

This feature can help the user to carry out their task more quickly.

Data can either be fetched from a JSON endpoint or locally from amp-state.

Setup

Import the amp-autocomplete component.

<script async custom-element="amp-autocomplete" src="https://cdn.ampproject.org/v0/amp-autocomplete-0.1.js"></script>

Import the amp-form component.

<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>

Optional: amp-bind is needed for dynamically changing the data source of an amp-autocomplete.

<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>

Optional: amp-mustache is needed for rich-content templating and client-side rendering of form responses.

<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>

Basic usage

An amp-autocomplete must always be nested in a form and have an input field and a datasource.

When a user types into this input field, relevant suggestions will automatically appear below the input field.

A datasource must be a JSON object containing an array property items, and can be specified inline with a child script type="application/json" tag, or a server endpoint specified with a src attribute.

<form class="sample-form"
  method="post"
  action-xhr="https://amp.dev/documentation/examples/api/echo"
  target="_top">
  <amp-autocomplete filter="substring">
    <input>
    <script type="application/json">
      {
        "items": ["apple", "orange", "banana"]
      }
    </script>
  </amp-autocomplete>
</form>

Alternatively, a datasource can also be provided as remote data through the src attribute.

<form class="sample-form"
  method="post"
  action-xhr="https://amp.dev/documentation/examples/api/echo"
  target="_top">
  <amp-autocomplete filter="substring"
    src="/static/samples/json/amp-autocomplete-cities.json">
    <input>
  </amp-autocomplete>
</form>

Dynamic src

The content of an amp-autocomplete can be changed dynamically by modifying its src value using amp-bind.


<div>
  <div class="suggest-data">
    <button on="tap:AMP.setState({ srcUrl: '/static/samples/json/amp-autocomplete-countries.json' })">Suggest countries</button>
    <button on="tap:AMP.setState({ srcUrl: '/static/samples/json/amp-autocomplete-cities.json' })">Suggest US cities</button>
  </div>
  <form class="sample-form"
    method="post"
    action-xhr="https://amp.dev/documentation/examples/api/echo"
    target="_top">
    <div class="input-field">
      <amp-autocomplete filter="substring"
        min-characters="0"
        src="/static/samples/json/amp-autocomplete-cities.json"
        [src]="srcUrl">
        <input name="name"
          required>
      </amp-autocomplete>
      <input name="submit-button"
        type="submit"
        value="Submit"><br>
    </div>
    <div submit-success>
      <template type="amp-mustache">
        Success! Mailing a postcard to {{name}}.
      </template>
    </div>
  </form>
</div>

Suggesting rich content

More complicated data can be passed into autocompleted with an array of JsonObjects in "items".

    { "items" : [
        {
            "city" : "Albany",
            "state" : "New York", 
            "areaCode" : 518,
            "population" : 98251
        }, {
            "city" : "Annapolis",
            "state" : "Maryland",
            "areaCode" : 410,
            "population" : 39321
        }, {
            "city" : "Trenton",
            "state" : "New Jersey",
            "areaCode" : 609,
            "population" : 84964
        }
    ] }

The corresponding display of these data in the amp-autocomplete can be specified through a template.

    <template type="amp-mustache" id="amp-template-custom">
      <div class="city-item" data-value="{{city}}, {{state}}">
          <div>{{city}}, {{state}}</div>
          <div class="custom-population">Population: {{population}}</div>        
      </div>
    </template>

By default, amp-autocomplete will suggest items by matching on the "value" property of each JsonObject, but for more specified data, an attribute filter-value can be provided to signify the appropriate property to search on.

In the above example, we will want to search on the property name, because that is what the user will most likely search for.

Error!
<form class="sample-form"
  method="post"
  action-xhr="https://amp.dev/documentation/examples/api/echo"
  target="_top">
  <label>
    <span>Search for</span>
    <amp-autocomplete filter="token-prefix"
      filter-value="city"
      min-characters="0">
      <input type="search"
        name="city">
      <script type="application/json">
        {
          "items": [{
            "city": "Albany",
            "state": "New York",
            "areaCode": 518,
            "population": 98251
          }, {
            "city": "Annapolis",
            "state": "Maryland",
            "areaCode": 410,
            "population": 39321
          }, {
            "city": "Trenton",
            "state": "New Jersey",
            "areaCode": 609,
            "population": 84964
          }]
        }
      </script>
      <template type="amp-mustache"
        id="amp-template-custom">
        <div class="city-item"
          data-value="{{city}}, {{state}}">
          <div>{{city}}, {{state}}</div>
          <div class="custom-population">Population: {{population}}</div>
        </div>
      </template>
    </amp-autocomplete>
  </label>
  <input type="submit"
    value="Search">
  <div submit-success>
    <template type="amp-mustache">
      Successfully submitted {{city}}!
    </template>
  </div>
  <div submit-error>
    Error!
  </div>
</form>

Displaying default items

Default suggestions for an amp-autocomplete can be displayed on user focus using rich content templating and the min-characters attribute on amp-autocomplete.

Additionally, because the data-disabled attribute on a template-rendered item allows it to be displayed but not searched against or selected, it can be useful for constructing a "header" within the results list that can serve to organize selectable items into categories. In the example below, "Popular groceries" acts as an example of the disabled item because it is not an item that you actually want to treat as a product.

Error!
<div>
  <amp-state id="generalInventory">
    <script type="application/json">
      {
        "items": [{
          "name": "apple",
          "emoji": "🍎",
          "price": "$1"
        }, {
          "name": "grapes",
          "emoji": "🍇",
          "price": "$2"
        }, {
          "name": "whole milk",
          "emoji": "🥛",
          "price": "$4"
        }, {
          "name": "banana",
          "emoji": "🍌",
          "price": "$0.50"
        }]
      }
    </script>
  </amp-state>
  <form class="sample-form"
    method="post"
    action-xhr="https://amp.dev/documentation/examples/api/echo"
    target="_top">
    <amp-autocomplete filter="substring"
      min-characters="0"
      filter-value="name"
      [src]="manualFilterData">
      <input type="search"
        name="product"
        on="input-debounced:AMP.setState({ manualFilterData: event.value.length == 0 ? 
          initialInventory : generalInventory })">
      <amp-state id="initialInventory">
        <script type="application/json">
          {
            "items": [{
              "isInitial": "true",
              "name": "apple"
            }, {
              "isInitial": "true",
              "name": "grapes"
            }, {
              "isInitial": "true",
              "name": "whole milk"
            }, {
              "isInitial": "true",
              "name": "banana"
            }]
          }
        </script>
      </amp-state>
      <template type="amp-mustache">
        {{#isInitial}}
          <div class="product"
            data-value="{{name}}">
            <amp-img class="trending"
              width="24"
              height="24"
              src="/static/samples/img/trending.png"></amp-img>
            <span class="name-and-description">{{name}}</span>
          </div>
        {{/isInitial}}
        {{^isInitial}}
          <div data-value="{{name}}"
            class="product">
            <div class="name-and-description">
              <div class="product-name">{{emoji}} <b>{{name}}</b> <i>{{price}}</i></div>
            </div>
          </div>
        {{/isInitial}}
      </template>
    </amp-autocomplete>
    <input type="submit"
      value="Search">
    <div submit-success>
      <template type="amp-mustache">
        Success! Added <strong>{{product}}</strong> to your cart.
      </template>
    </div>
    <div submit-error>
      Error!
    </div>
  </form>
</div>
Need further explanation?

If the explanations on this page don't cover all of your questions feel free to reach out to other AMP users to discuss your exact use case.

Go to Stack Overflow
An unexplained feature?

The AMP project strongly encourages your participation and contributions! We hope you'll become an ongoing participant in our open source community but we also welcome one-off contributions for the issues you're particularly passionate about.

Edit sample on GitHub