amp-form

Edit on Github
Open in Playground View Demo

Introduction

The amp-form extension allows the usage of forms and input fields in an AMP document. amp-form allows HTTP and XHR (XMLHttpRequest) form submissions. An HTTP form submission loads a new page, while an XHR form submission doesn't require a page reload.

Setup

Import the library.

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

Customize success or error messages by using amp-form-submit-success and amp-form-submit-error classes.

<style amp-custom>
form.amp-form-submit-success [submit-success],
form.amp-form-submit-error [submit-error]{
  margin-top: 16px;
}
form.amp-form-submit-success [submit-success] {
  color: green;
}
form.amp-form-submit-error [submit-error] {
  color: red;
}
form.amp-form-submit-success.hide-inputs > input {
  display: none;
}
</style>

Form Submission with Page Reload

Use the action attribute to specify a server-endpoint which should handle the form input. This works only for GET requests. The URL must be HTTPS. The following sample uses type="search" to emulate a search. The search button will trigger a page reload.

Please find security considerations to check best practices when choosing GET or POST methods.

You can find the code for the server endpoint used in this demo at /backend/amp-form.go.

Example

<form method="GET"
  class="p2"
  action="/components/amp-form/submit-form"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="search"
      placeholder="Search..."
      name="googlesearch">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
</form>

Form Submission with Page Update

Use the action-xhr attribute to submit the form via XMLHttpRequest (XHR). You can use amp-mustache templates to show custom success or error messages, using data sent by the server endpoint as JSON. For example, if the server sends {"foo": "bar"}, you can use use {{foo}} in the template to render bar.

The amp-form component displays submit-success or submit-error elements based on the response and renders the template data inside these two elements. The submit-success and submit-error elements must be direct children of form.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-input-text-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative m0 p0 mb3">
    <input type="text"
      class="block border-none p0 m0"
      name="name"
      placeholder="Name..."
      required>
    <input type="email"
      class="block border-none p0 m0"
      name="email"
      placeholder="Email..."
      required>
  </div>
  <input type="submit"
    value="Subscribe"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks {{name}} for trying the
      <code>amp-form</code> demo! Try to insert the word "error" as a name input in the form to see how
      <code>amp-form</code> handles errors.
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error! Thanks {{name}} for trying the
      <code>amp-form</code> demo with an error response.
    </template>
  </div>
</form>

Hiding input fields after success

Use the amp-form-submit-success class to hide input fields after a successful submission. The following CSS rule hides all form input fields after successful form submission:

form.amp-form-submit-success > input {
  display: none
}

Example

<form class="p3 hide-inputs"
  method="post"
  action-xhr="/components/amp-form/submit-form-input-text-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="text"
      name="name"
      placeholder="Name..."
      required>
  </div>
  <input type="submit"
    value="Subscribe"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks {{name}} for trying the
      <code>amp-form</code> demo! Try to insert the word "error" as a name input in the form to see how
      <code>amp-form</code> handles errors.
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error! Thanks {{name}} for trying the
      <code>amp-form</code> demo with an error response.
    </template>
  </div>
</form>

Other form input samples

amp-form supports all HTML5 form types with the exception of file, password and image. Use type="date" for input fields that should contain a date.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input name="select-date"
      type="date"
      value="2020-12-30">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="month" for input fields that should contain a month.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input name="select-month"
      type="month"
      value="2020-12">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="week" for input fields that should contain a week.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="week"
      name="week_year">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="datetime-local" for input fields that should contain a date and time.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input name="select-datetime"
      type="datetime-local"
      value="2020-12-30T12:34:56">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="time" for input fields that should contain a time.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="time"
      name="time_now">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="checkbox" to let the user select ZERO or MORE options of a limited number of choices.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input ampstart-input-chk inline-block relative mb3 mr1">
    <input type="checkbox"
      id="animal1"
      name="animal1"
      class="relative"
      value="Cats">
    <label for="animal1">I like cats</label>
  </div>
  <div class="ampstart-input ampstart-input-chk inline-block relative mb3 mr1">
    <input type="checkbox"
      id="animal2"
      name="animal2"
      class="relative"
      value="Dogs">
    <label for="animal2"> I like dogs </label>
  </div>
  <button type="submit"
    value="OK"
    class="ampstart-btn caps">OK</button>
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="email" for input fields that should contain an e-mail address.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="email"
      name="email"
      placeholder="Email...">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="hidden" to define a field not visible to a user.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <input type="hidden"
    name="city"
    value="London">
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="number" for input fields that should contain a numeric value.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="number"
      name="quantity"
      min="1"
      max="5">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="radio" to let a user select ONLY ONE of a limited number of choices.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input ampstart-input-radio inline-block relative mb3">
    <input type="radio"
      id="cat"
      class="relative"
      name="favourite animal"
      value="cat"
      checked>
    <label for="cat">Cat</label>
  </div>
  <div class="ampstart-input ampstart-input-radio inline-block relative m0 p0 mb3 ">
    <input type="radio"
      id="dog"
      class="relative"
      name="favourite animal"
      value="dog">
    <label for="dog">Dog</label>
  </div>
  <div class="ampstart-input ampstart-input-radio inline-block relative m0 p0 mb3 ">
    <input type="radio"
      id="other"
      class="relative"
      name="favourite animal"
      value="other">
    <label for="other">Other</label>
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="range" for input fields that should contain a value within a range.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class=" ampstart-input inline-block relative mb3">
    <input type="range"
      name="points"
      min="0"
      max="10">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="tel" for input fields that should contain a telephone number.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="tel"
      name="my_tel"
      placeholder="Telephone...">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="url" for input fields that should contain a URL address.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="url"
      placeholder="URL..."
      name="website">
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use type="reset" to clear input fields.

Example

<form method="post"
  class="p2"
  action-xhr="/components/amp-form/submit-form-xhr"
  target="_top">
  <div class="ampstart-input inline-block relative mb3">
    <input type="text"
      placeholder="Some text...">
  </div>
  <div>
    <input type="submit"
      value="OK"
      class="ampstart-btn caps">
    <input type="reset"
      value="Reset"
      class="ampstart-btn caps">
  </div>
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>

Use select element for dropdowns.

Example

<form method="post"
  action-xhr="https://ampbyexample.com/components/amp-form/submit-form-xhr"
  target="_top"
  class="p2">
  <div class="ampstart-input inline-block relative mb3">
    <select name="cars"
      id="cars">
      <option value="volvo">Volvo</option>
      <option value="saab">Saab</option>
      <option value="fiat">Fiat</option>
      <option value="audi">Audi</option>
    </select>
    <label for="cars"
      class="absolute top-0 right-0 bottom-0 left-0">Select a car</label>
  </div>
  <input type="submit"
    value="OK"
    class="ampstart-btn caps">
  <div submit-success>
    <template type="amp-mustache">
      Success! Thanks for trying the
      <code>amp-form</code> demo!
    </template>
  </div>
  <div submit-error>
    <template type="amp-mustache">
      Error!
    </template>
  </div>
</form>