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. amp-selector
Not Allowed
<input type=button>
,<input type=image>
<input type=password>
and<input type=file>
- Most of the form-related attributes on inputs including:
form
,formaction
,formtarget
,formmethod
and 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. 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-success
andsubmit-error
. Both success and error responses should have aContent-Type: application/json
header.
<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> Form submitting... Thank you for waiting. </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
event
property 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:
{ "name": "Jane Miller", "email": "email@example.com" }
Then amp-bind
updates the <p>
element's text to match the subscibe
state:
... <p [text]="'Thanks, ' + subscribe +'! You have successfully subscribed.'"> Thanks Jane Miller! You have successfully subscribed. </p> ...
Autoexpand
AMP Form provides an autoexpand
attribute to <textarea>
elements. This allows the textarea
to expand and shrink to accomodate the user's rows of input, up to the field's maximum size. If the user manually resizes the field, the autoexpand behavior will be removed.
<textarea autoexpand></textarea>
Polyfills
The amp-form
extension provide polyfills for behaviors and functionality missing from some browsers or being implemented in the next version of CSS.
Invalid submit blocking and validation message bubble
Browsers that use webkit-based engines currently (as of August 2016) do not support invalid form submissions. These include Safari on all platforms, and all iOS browsers. The amp-form
extension polyfills this behavior to block any invalid submissions and shows validation message bubbles on invalid inputs.
User-interaction pseudo-classes
The :user-invalid
and :user-valid
pseudo classes are part of the future CSS Selectors 4 spec and are introduced to allow better hooks for styling invalid/valid fields based on a few criteria.
One of the main differences between :invalid
and :user-invalid
is when are they applied to the element. The :user-invalid
class is applied after a significant interaction from the user with the field (e.g., the user types in a field, or blurs from the field).
The amp-form
extension provides classes to polyfill these pseudo-classes. The amp-form
extension also propagates these to the ancestor form
. However, fieldset
elements are only ever set to have class 'user-valid' to be consistent with browser behaviour.
<textarea>
validation
Regular expression matching is a common validation feature supported natively on most input elements, except for <textarea>
. We polyfill this functionality and support the pattern
attribute on <textarea>
elements.
Security considerations
Protecting against XSRF
In addition to following the details in the AMP CORS spec, please pay extra attention to the section on "Processing state changing requests" to protect against XSRF attacks where an attacker can execute unauthorized commands using the current user session without the user knowledge.
In general, keep in mind the following points when accepting input from the user:
- Only use POST for state changing requests.
- Use non-XHR GET for navigational purposes only (e.g. search).
- Non-XHR GET requests are will not receive accurate origin/headers and backends won't be able to protect against XSRF with the above mechanism.
- In general, use XHR/non-XHR GET requests for navigational or information retrieval only.
- Non-XHR POST requests are not allowed in AMP documents. This is due to inconsistencies of setting
Origin
header on these requests across browsers, and the complications supporting it would introduce in protecting against XSRF. This might be reconsidered and introduced later — please file an issue if you think this is needed.
Attributes
action-xhr
Specifies a server endpoint to handle the form input and submit the form via XMLHttpRequest (XHR). An XHR request (sometimes called an AJAX request) is where the browser would make the request without a full load of the page or opening a new page. Browsers will send the request in the background using the Fetch API when available and fall back to XMLHttpRequest API for older browsers.
This attribute is required for method=POST
, and is optional for method=GET
.
The value for action-xhr
can be the same or a different endpoint than action
and has the same action
requirements above.
Other form attributes
All other form attributes are optional.
Invalid AMP email attributes
The AMP for Email spec disallows the use of the following attributes on the AMP email format.
action
name
target
verify-xhr
Actions
The amp-form
element exposes the following actions.
submit
Allows you to trigger the form submission on a specific action, for example, tapping a link, or submitting a form on input change.
clear
Empties the values from each input in the form. This can allow users to quickly fill out forms a second time.
Events
Use amp-form
events with the on
attribute
The following example listens to both the submit-success
and submit-error
events and shows different lightboxes depending on the event:
<form ... on="submit-success:success-lightbox;submit-error:error-lightbox" ... ></form>
submit
The form is submitted and before the submission is complete.
submit-success
The form submission is done and the response is a success.
submit-error
The form submission is done and the response is an error.
Input events
AMP exposes change
and input-debounced
events on child <input>
elements. This allows you to use the on
attribute to execute an action on any element when an input value changes.
For example, a common use case is to submit a form on input change (selecting a radio button to answer a poll, choosing a language from a select
input to translate a page, etc.).
<form id="myform" method="post" action-xhr="https://example.com/myform" target="_blank"> <fieldset> <label> <input name="answer1" value="Value 1" type="radio" on="change:myform.submit">Value 1 </label> <label> <input name="answer1" value="Value 2" type="radio" on="change:myform.submit">Value 2 </label> </fieldset> </form>
See the full example here.
Styling
Classes and CSS hooks
The amp-form
extension provides classes and CSS hooks for publishers to style their forms and inputs.
The following classes can be used to indicate the state of the form submission:
.amp-form-initial
.amp-form-verify
.amp-form-verify-error
.amp-form-submitting
.amp-form-submit-success
.amp-form-submit-error
The following classes are a polyfill for the user interaction pseudo classes:
.user-valid
.user-invalid
Publishers can use these classes to style their inputs and fieldsets to be responsive to user actions (e.g., highlighting an invalid input with a red border after user blurs from it).
See the full example here on using these.
Validation
See amp-form rules in the AMP validator specification.
Вы читали этот документ десятки раз, но так и не нашли ответов на все свои вопросы? Возможно, другие люди столкнулись с такой же проблемой — обратитесь к ним на Stack Overflow.
Перейти на Stack Overflow Нашли ошибку или недостающую функцию?Проект AMP активно поощряет ваше участие и сотрудничество! Мы надеемся, что вы станете постоянным участником нашего открытого сообщества, но разовые вклады в работу над задачами, которые вам особенно интересны, также приветствуются.
Перейти на GitHub