amp-form
Description
Allows you to create forms to submit input fields in an AMP document.
Required Scripts
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
Usage
The amp-form extension allows you to create forms (<form>) to submit input fields in an AMP document. The amp-form extension also provides polyfills for some missing behaviors in browsers.
If you're submitting data in your form, your server endpoint must implement the requirements for CORS security.
Before creating a <form>, you must include the required script for the <amp-form> extension, otherwise your document will be invalid. If you're using input tags for purposes other than submitting their values (e.g., inputs not inside a <form>), you do not need to load the amp-form extension.
<form method="post" action-xhr="https://example.com/subscribe" target="_top"> <fieldset> <label> <span>Name:</span> <input type="text" name="name" required> </label> <br> <label> <span>Email:</span> <input type="email" name="email" required> </label> <br> <input type="submit" value="Subscribe"> </fieldset> <div submit-success> <template type="amp-mustache"> Subscription successful! </template> </div> <div submit-error> <template type="amp-mustache"> Subscription failed! </template> </div> </form>
Inputs and fields
Allowed
- Other form-related elements, including:
<textarea>,<select>,<option>,<fieldset>,<label>,<input type=text>,<input type=submit>, and so on. <input type=password>and<input type=file>inside of<form method=POST action-xhr>.amp-selector
Not Allowed
<input type=button>,<input type=image>- Most of the form-related attributes on inputs including:
form,formaction,formtarget,formmethodand others.
(Relaxing some of these rules might be reconsidered in the future - please let us know if you require these and provide use cases).
For details on valid inputs and fields, see amp-form rules in the AMP validator specification.
Success and error response rendering
You can render success or error responses in your form by using amp-mustache, or success responses through data binding with amp-bind and the following response attributes:
| Response attribute | Description |
|---|---|
submit-success |
Can be used to display a success message if the response is successful (i.e., has a status of 2XX). |
submit-error |
Can be used to display a submission error if the response is unsuccessful (i.e., does not have a status of 2XX). |
submitting |
Can be used to display a message when the form is submitting. The template for this attribute has access to the form's input fields for any display purposes. Please see the full form example below for how to use the submitting attribute. |
To render responses with templating:
- Apply a response attribute to any descendant of the
<form>element. - Render the response in the child element by including a template via
<template></template>or<script type="text/plain"></script>tag inside it or by referencing a template with atemplate="id_of_other_template"attribute. - Provide a valid JSON object for responses to
submit-successandsubmit-error. Both success and error responses should have aContent-Type: application/jsonheader.
<amp-form> in tandem with another templating AMP component, such as <amp-list>, note that templates may not nest in valid AMP documents. In this case a valid workaround is to provide the template by id via the template attribute. Learn more about nested templates in <amp-mustache>. In the following example, the responses are rendered in an inline template inside the form.
<form ...> <fieldset> <input type="text" name="firstName" /> ... </fieldset> <div submitting> <template type="amp-mustache"> Form submitting... Thank you for waiting {{name}}. </template> </div> <div submit-success> <template type="amp-mustache"> Success! Thanks {{name}} for subscribing! Please make sure to check your email {{email}} to confirm! After that we'll start sending you weekly articles on {{#interests}}<b>{{name}}</b> {{/interests}}. </template> </div> <div submit-error> <template type="amp-mustache"> Oops! {{name}}, {{message}}. </template> </div> </form>
The publisher's action-xhr endpoint returns the following JSON responses:
On success:
{ "name": "Jane Miller", "interests": [ {"name": "Basketball"}, {"name": "Swimming"}, {"name": "Reading"} ], "email": "email@example.com" }
On error:
{ "name": "Jane Miller", "message": "The email (email@example.com) you used is already subscribed." }
You can render the responses in a referenced template defined earlier in the document by using the template's id as the value of the template attribute, set on the elements with the submit-success and submit-error attributes.
<template type="amp-mustache" id="submit_success_template"> Success! Thanks {{name}} for subscribing! Please make sure to check your email {{email}} to confirm! After that we'll start sending you weekly articles on {{#interests}}<b>{{name}}</b> {{/interests}}. </template> <template type="amp-mustache" id="submit_error_template"> Oops! {{name}}, {{message}}. </template> <form ...> <fieldset> ... </fieldset> <div submit-success template="submit_success_template"></div> <div submit-error template="submit_error_template"></div> </form>
See the full example here.
To render a successful response with data binding
- Use the on attribute to bind the form submit-success attribute to
AMP.setState(). - Use the
eventproperty to capture the response data. - Add the state attribute to the desired element to bind the form response.
The following example demonstrates a form submit-success response with amp-bind:
<p [text]="'Thanks, ' + subscribe +'! You have successfully subscribed.'"> Subscribe to our newsletter </p> <form method="post" action-xhr="/components/amp-form/submit-form-input-text-xhr" target="_top" on="submit-success: AMP.setState({'subscribe': event.response.name})" > <div> <input type="text" name="name" placeholder="Name..." required /> <input type="email" name="email" placeholder="Email..." required /> </div> <input type="submit" value="Subscribe" /> </form>
When the form is submitted successfully it will return a JSON response similar to the following: