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>
Beispiele
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:
{ "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> ...
Redirecting after a submission
You can redirect users to a new page after a successful form submission by setting the AMP-Redirect-To response header and specifying a redirect URL. The redirect URL must be a HTTPS URL, otherwise AMP will throw an error and redirection won't occur. HTTP response headers are configured via your server.
Make sure to update your Access-Control-Expose-Headers response header to include AMP-Redirect-To to the list of allowed headers. Learn more about these headers in CORS Security in AMP.
Example response headers:
AMP-Redirect-To: https://example.com/forms/thank-you Access-Control-Expose-Headers: AMP-Redirect-To
Custom validations
The amp-form extension allows you to build your own custom validation UI by using the custom-validation-reporting attribute along with one the following reporting strategies: show-first-on-submit, show-all-on-submit or as-you-go.
To specify custom validation on your form:
- Set the
custom-validation-reportingattribute on yourformto one of the validation reporting strategies. - Provide your own validation UI marked up with special attributes. AMP will discover the special attributes and report them at the right time depending on the reporting strategy you specified.
Here's an example:
<form method="post" action-xhr="https://example.com/subscribe" custom-validation-reporting="show-all-on-submit" target="_blank"> <fieldset> <label> <span>Name:</span> <input type="text" name="name" id="name5" required pattern="\w+\s\w+"> <span visible-when-invalid="valueMissing" validation-for="name5"></span> <span visible-when-invalid="patternMismatch" validation-for="name5"> Please enter your first and last name separated by a space (e.g. Jane Miller) </span> </label> <br> <label> <span>Email:</span> <input type="email" name="email" id="email5" required> <span visible-when-invalid="valueMissing" validation-for="email5"></span> <span visible-when-invalid="typeMismatch" validation-for="email5"></span> </label> <br> <input type="submit" value="Subscribe"> </fieldset> </form>
For validation messages, if your element contains no text content inside, AMP will fill it out with the browser's default validation message. In the example above, when the name5 input is empty and validation is kicked off (i.e., user tried to submit the form) AMP will fill <span visible-when-invalid="valueMissing" validation-for="name5"></span> with the browser's validation message and show that span to the user.
custom-validation-reporting for the missing error state. The validity states can be found in the official W3C HTML validation reporting documentation. Reporting strategies
Specify one of the following reporting options for the custom-validation-reporting attribute:
Show First on Submit
The show-first-on-submit reporting option mimics the browser's default behavior when default validation kicks in. It shows the first validation error it finds and stops there.
Show All on Submit
The show-all-on-submit reporting option shows all validation errors on all invalid inputs when the form is submitted. This is useful if you'd like to show a summary of validations.
As You Go
The as-you-go reporting option allows your user to see validation messages as they're interacting with the input. For example, if the user types an invalid email address, the user will see the error right away. Once they correct the value, the error goes away.
Interact and Submit
The interact-and-submit reporting option combines the behavior of show-all-on-submit and as-you-go. Individual fields will show any errors immediately after interactions, and on submit the form will show errors on all invalid fields.
Verification
HTML5 validation gives feedback based only on information available on the page, such as if a value matches a certain pattern. With amp-form verification you can give the user feedback that HTML5 validation alone cannot. For example, a form can use verification to check if an email address has already been registered. Another use-case is verifying that a city field and a zip code field match each other.
Here's an example:
<h4>Verification example</h4> <form method="post" action-xhr="/form/verify-json/post" verify-xhr="/form/verify-json/post" target="_blank"> <fieldset> <label> <span>Email</span> <input type="text" name="email" required> </label> <label> <span>Zip Code</span> <input type="tel" name="zip" required pattern="[0-9]{5}(-[0-9]{4})?"> </label> <label> <span>City</span> <input type="text" name="city" required> </label> <label> <span>Document</span> <input type="file" name="document" no-verify> </label> <div class="spinner"></div> <input type="submit" value="Submit"> </fieldset> <div submit-success> <template type="amp-mustache"> <p>Congratulations! You are registered with {{email}}</p> </template> </div> <div submit-error> <template type="amp-mustache"> {{#verifyErrors}} <p>{{message}}</p> {{/verifyErrors}}{{^verifyErrors}} <p>Something went wrong. Try again later?</p> {{/verifyErrors}} </template> </div> </form>
The form sends a __amp_form_verify field as part of the form data as a hint to
the server that the request is a verify request and not a formal submit.
This is helpful so the server knows not to store the verify request if the same
endpoint is used for verification and for submit.
Here is how an error response should look for verification:
{ "verifyErrors": [ {"name": "email", "message": "That email is already taken."}, {"name": "zip", "message": "The city and zip do not match."} ] }
To remove a field from the verify-xhr request, add the no-verify attribute
to the input element.
For more examples, see examples/forms.amp.html.
Variable substitutions
The amp-form extension allows platform variable substitutions for inputs that are hidden and that have the data-amp-replace attribute. On each form submission, amp-form finds all input[type=hidden][data-amp-replace] inside the form and applies variable substitutions to its value attribute and replaces it with the result of the substitution.
You must provide the variables you are using for each substitution on each input by specifying a space-separated string of the variables used in data-amp-replace (see example below). AMP will not replace variables that are not explicitly specified.
Here's an example of how inputs are before and after substitutions (note that you need to use platform syntax of variable substitutions and not analytics ones):
<!-- Initial Load --> <form ...> <input name="canonicalUrl" type="hidden" value="The canonical URL is: CANONICAL_URL - RANDOM - CANONICAL_HOSTNAME" data-amp-replace="CANONICAL_URL RANDOM" />