AMP Form
Thursday 16 February 2017Once I had the authorization working and could display the comment form properly the next step was to get the form submitting properly. First of all, to use forms in AMP you need to include the following script:
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
AMP forms work mostly the same way as normal HTML5 forms, but there are a few differences. With AMP you have to either use GET forms or you can use POST forms but you need to use action-xhr instead of action. For POST forms you also need to include a target of either _blank or _top. Using action-xhr means that the page will basically post an AJAX request which expects a JSON response instead of reloading the whole page. If you want to reload the whole page you should use method="get".
The response from the request needs to include the same headers as the authorization request, which are detailed in this post. The response doesn't need to contain any specific data, you can put whatever you want in there. You can use the response data to update the page after a successful post, but I have not done that yet.
In this case, the controller function action for my new comment just adds the comment and then returns the id and body of the new comment in JSON along with the necessary headers. I would like to display the new comment on the page, but the syntax to display the JSON data is {{ var }} which is the same syntax blade uses. I know there is a workaround for this, but I haven't looked for it yet.
The two big issues I had with this form were how to update the page after a successful post. I wanted to do two things: hide the form to leave a comment and display a success message. There are AMP components to accomplish both of these tasks.
To hide the form after a successful post you can add the following CSS:
form.amp-form-submit-success > input {
display: none
}
And set the form's class to "hide-inputs." When the success message comes back the form's class is updated to included amp-form-submit-success which will cascade down to hide any child inputs. I had my inputs in a panel inside the form and the inputs were not hidden because the input was not a direct child of the form. This was fixed by rearranging the elements so that the form was inside the divs so that the inputs were children of the form. Before I arrived at this solution I first tried to hide the entire form, which worked great, but also hid the success message. Since my form field was a textarea I had to add another item to the CSS for textareas, otherwise identical to that above.
The next step was displaying a success message, which I did by following the instructions here. The block of sample code from this page is:
<form class="hide-inputs" method="post" action-xhr="https://ampbyexample.com/components/amp-form/submit-form-input-text-xhr" target="_top">
<input type="text" class="data-input" name="name" placeholder="Name..." required>
<input type="submit" value="Subscribe" class="button button-primary">
<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>
The div submit-success is hidden until the form submission comes back with a success message at which point it is display, and likewise with the submit-error block. To use the amp-mustache templates you need to include the following in a script tag:
script custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"
In the submit-success section the {{ name }} will substitute in the "name" element from the JSON data returned from the post. In my case I have left this out for now and just display a success message and hide the form.
To see this in action you can look at the AMP version of this blog here. When you submit a comment the form disappears and is replaced by a success message. Ideally the new comment would show up, but I'll get to that at some point in the future.
Update - the blade syntax to display the "{{ }}" for Javascript is "@{{ whatever }}". So I updated my code to actually display the comment after it is posted.
Labels:
coding,
laravel,
amp
25 comments