#BlackLivesMatter
Do you build things with AMP? Fill out the new AMP Developer Survey!
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 specified with an input or textarea tag 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 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>

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!

Inline autocomplete

<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>

<h2>Inline autocomplete</h2>

Displaying suggestions inline

Suggestions can be triggered on a specified character token in an amp-autocomplete for multiple autosuggestions in a single input by using the inline attribute. The token for triggering the autosuggestion must be the provided value for the inline attribute. For example, if inline="+", then when the + token is entered by the user, any relevant suggestions will be displayed. Otherwise, the field will behave the same as an unenhanced input field. The inline attribute does not support the empty string, or "" as a legitimate token value on amp-autocomplete.

Error!
<form class="sample-form"
  method="post"
  action-xhr="https://amp.dev/documentation/examples/api/echo"
  target="_top">
  <amp-autocomplete filter="prefix"
    inline="+"
    min-characters="0"
    filter-value="name">
    <textarea autoexpand
      rows="2"
      placeholder="Type your message here"
      name="message"></textarea>
    <template type="amp-mustache">
      <div class="close-friends"
        data-value="{{ email }}">
        <amp-img class="profile-pic"
          height="20"
          width="20"
          layout="responsive"
          alt="Profile picture of AMP logo"
          src="/static/samples/img/favicon.png"></amp-img>
        <div class="info">
          <div>{{ name }}</div>
          <div class="custom">{{ email }}</div>
        </div>
      </div>
    </template>
    <script type="application/json">
      {
        "items": [{
            "email": "harrypotter@hogwarts.edu",
            "name": "Harry Potter"
          },
          {
            "email": "albusdumbledore@hogwarts.edu",
            "name": "Albus Dumbledore"
          },
          {
            "email": "voldemort@deatheater.org",
            "name": "Tom Marvolo Riddle"
          },
          {
            "email": "severussnape@hogwarts.edu",
            "name": "Severus Snape"
          },
          {
            "email": "siriusblack@hogwarts.edu",
            "name": "Sirius Black"
          },
          {
            "email": "hermionegranger@hogwarts.edu",
            "name": "Hermione Granger"
          },
          {
            "email": "ronweasley@hogwarts.edu",
            "name": "Ron Weasley"
          },
          {
            "email": "dracomalfoy@hogwarts.edu",
            "name": "Draco Malfoy"
          },
          {
            "email": "nevillelongbottom@hogwarts.edu",
            "name": "Neville Longbottom"
          },
          {
            "email": "rubeushagrid@hogwarts.edu",
            "name": "Rubeus Hagrid"
          },
          {
            "email": "dobby@hogwarts.edu",
            "name": "Dobby"
          },
          {
            "email": "bellatrixlestrange@deatheater.org",
            "name": "Bellatrix Lestrange"
          },
          {
            "email": "minervamcgonagall@hogwarts.edu",
            "name": "Minerva McGonagall"
          }
        ]
      }
    </script>
  </amp-autocomplete>
  <input type="submit"
    value="Search">
  <div submit-success>
    <template type="amp-mustache">
      Success! <strong>{{message}}</strong>
    </template>
  </div>
  <div submit-error>
    Error!
  </div>
</form>

Specifying query parameters

User inputs can be passed to a statically generated endpoint when the query attribute is paired with the src attribute.

For example if a src="https://example.com and query="q", then a user who types in abc will get the fetch JSON result from https://example.com?q=abc.

<form class="sample-form"
  method="post"
  action-xhr="https://amp.dev/documentation/examples/api/echo"
  target="_top">
  <amp-autocomplete filter="none"
    min-characters="1"
    src="https://amp.dev/samples_templates/products_autosuggest"
    query="q">
    <input type="search"
      name="queryInput">
  </amp-autocomplete>
  <input type="submit"
    value="Search">
  <div submit-success>
    <template type="amp-mustache">
      Success! Received <strong>{{queryInput}}</strong>.
    </template>
  </div>
</form>
Besoin de plus amples explications ?

Si les explications de cette page ne répondent pas à vos questions, n'hésitez pas à contacter d'autres utilisateurs d'AMP pour discuter de votre cas d'utilisation spécifique.

Se rendre sur Stack Overflow
Une fonctionnalité n'a pas encore été expliquée ?

Le projet AMP encourage fortement votre participation et vos contributions ! Nous espérons que vous deviendrez un membre régulier de notre communauté open source, mais nous serons également ravis de recevoir des contributions ponctuelles concernant les questions qui vous intéressent particulièrement.

Modifier l'exemple sur GitHub