Do you build things with AMP? Fill out the AMP Developer Survey!
AMP
  • websites

Linked Dropdowns

Introduction

These linked dropdowns are implemented using AMP components. This pattern is useful when the values in the second dropdown depend on the value the user selects in the first dropdown. Here we select cities in a chosen country.

Setup

First we include amp-bind to track the page state and update the <amp-list> data source.

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

Next we include amp-list to request and display the dropdowns and their options.

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

Finally, we include amp-mustache to render the mustache templates inside the <amp-list>s.

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

For the last snippet, we show how to implement a linked list with amp-form using the get method

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

Implementation

We use two <amp-list> elements to render the options within each <select>. The first dropdown triggers a request, which is batched with the request triggered by the other <amp-list> and the <amp-state> element, so only one request is sent.

When the user selects a value in the first dropdown, amp-bind updates the cities state value. This updates second <amp-list>'s [src] binding, and it renders its template using the data in the cities array.

<div class="linked-dropdown">
  <amp-list layout="fixed-height"
    height="25"
    src="/static/samples/json/linked_dropdowns.json"
    binding="refresh"
    single-item
    items="."
    noloading>
    <template type="amp-mustache">
      <label for="country">Country:</label>
      <select id="country"
        on="change: AMP.setState({
                                          cities: dropdown.countries.filter(x => x.name == event.value)[0]
                                        })">
        <option value>Choose a country</option>
        {{#countries}}
          <option value="{{name}}">{{name}}</option>
        {{/countries}}
      </select>
    </template>
    <div placeholder
      role="listitem">
      <label for="country">Country:</label>
      <select disabled>
        <option value>Choose a country</option>
      </select>
    </div>
  </amp-list>
  <amp-list layout="fixed-height"
    height="25"
    [src]="cities || '/static/samples/json/linked_dropdowns.json'"
    src="/static/samples/json/linked_dropdowns.json"
    binding="refresh"
    single-item
    items="."
    noloading>
    <template type="amp-mustache">
      <label for="city">City:</label>
      <select [disabled]="!cities"
        disabled
        id="city">
        <option value>Choose a city</option>
        {{#cities}}
          <option value="{{.}}">{{.}}</option>
        {{/cities}}
      </select>
    </template>
    <div placeholder
      role="listitem">
      <label>City:</label>
      <select disabled>
        <option value>Choose a city</option>
      </select>
    </div>
  </amp-list>
  <amp-state id="dropdown"
    src="/static/samples/json/linked_dropdowns.json"></amp-state>
</div>

Implementation with amp-form using get method

Here we show the same example within the amp-form element.

We want to pass selected values into action url, as found in the action field in the amp-form component. In order to do this, we must include data-allow-initialization and name="query parameter" (in this case q for Google search) fields in each select statement. See amp-form for more details.

To redirect user after they've selected values, you must include a Submit button to close off the form. Once user selects the Submit button, they will be directed to the action url with attached queries.

<div class="linked-dropdown-form">
  <form data-initialize-from-url
    id="formResetSample"
    class="field"
    action="https://www.google.com"
    method="get"
    target="_top">
    <amp-list layout="fixed-height"
      height="25"
      src="/static/samples/json/linked_dropdowns.json"
      binding="refresh"
      single-item
      items="."
      noloading>
      <template type="amp-mustache">
        <label for="country">Country:</label>
        <select id="country"
          on="change: AMP.setState({
                                        citiesForm: dropdown.countries.filter(x => x.name == event.value)[0]
                                      })"
          name="q"
          data-allow-initialization>
          <option value>Choose a country</option>
          {{#countries}}
            <option value="{{name}}">{{name}}</option>
          {{/countries}}
        </select>
      </template>
      <div placeholder
        role="listitem">
        <label for="country">Country:</label>
        <select disabled>
          <option value>Choose a country</option>
        </select>
      </div>
    </amp-list>
    <amp-list layout="fixed-height"
      height="25"
      [src]="citiesForm || '/static/samples/json/linked_dropdowns.json'"
      src="/static/samples/json/linked_dropdowns.json"
      binding="refresh"
      single-item
      items="."
      noloading>
      <template type="amp-mustache">
        <label for="city">City:</label>
        <select [disabled]="!citiesForm"
          disabled
          id="city"
          on="change: AMP.setState({city: event.value})"
          name="q"
          data-allow-initialization>
          <option value>Choose a city</option>
          {{#citiesForm}}
            <option value="{{.}}">{{.}}</option>
          {{/citiesForm}}
        </select>
      </template>
    </amp-list>
    <amp-state id="dropdown"
      src="/static/samples/json/linked_dropdowns.json"></amp-state>
    <button on="select:formResetSample.submit">
      Submit
    </button>
  </form>
</div>
هل تحتاج إلى مزيد من التوضيح؟

إذا لم تكن الإيضاحات الموجودة في هذه الصفحة تُجيب على جميع أسئلتك، فلا تتردد في التواصل مع مستخدمي AMP الآخرين لمناقشة حالة الاستخدام المحددة لديك بالضبط.

الذهاب إلى Stack Overflow
هل هي ميزة غير موضحة؟

يشجع مشروع AMP مشاركتك ومساهمتك بشدة! ونأمل أن تكون مشاركًا دائمًا في مجتمعنا مفتوح المصدر، ولكننا نشجع أيضًا المساهمات التي تحدث لمرة واحدة في الأمور التي تتحمس لها.

تعديل العينة على GitHub