はじめに

純粋にAMP-HTMLでformを扱うのはどうすればいいのか気になったので調べてみた

準備するコンポーネント

参考にした記事

実装

【DEMO】

作ったフォームの流れ

アクション先へ移動や、アクション先から別ページへの遷移もできるようだが、今回は参考にした記事と同じように、 xhr指定でフォーム入力を処理をしたら元のページに戻す形で作成を行った。なお、XHRエンドポイントは、CORSセキュリティの要件を実装する必要があるそうだ。

で、ここがポイントなのだが、アクション先のPHP でヘッダーに

AMP-Access-Control-Allow-Source-Origin: https://example.com

を加えれば自分のドメイン内であれば動くようになる。が、気をつけなければならないのが、AMPcacheページからフォームを動かす場合これでは動かない。

cacheページのURLはamp用のGoogleドメインなので、アクセス元が異なる。なので、このケースの場合は、ヘッダーに必要な情報を追加して、AMPcacheページからもテストしないといけない。この辺の詳しい説明は、

の記事が細かく説明してくれているので分かりやすい。

amp-formでは、指定されたtypeによって入力のチェックを行ってくれる。たとえば、type="email" に指定していれば、入力された値がemailでないと送信できない。
とは言え、それでチェックが完璧にできるわけではないので、アクション先でチェックを行う必要がある。

サブミットが、成功した際はsubmit-success 、失敗した際は、submit-error にメッセージを表示することができる。今回は使っていないが、submitting verify-error なども使い分けることができるみたい。


<div submit-success class="result">
<template type="amp-mustache">
<div class='{{tag_back}}'>
</div>
<div class='{{tag}}'>
<h3>{{title}}</h3>
<p>{{message}}</p>
<p class='{{sentence}}'><a href='{{link}}'>【demoページに戻る】</a></p>
</div>
</template>
</div>

<div submit-error class="result">
<template type="amp-mustache">
<p>送信に失敗しました</p>
</template>
</div>

submit-success には、JSONデータを入れ込むように記述してある。なお、idやclassの箇所もJSONで名前を変えることでCSSも切り替えることができるのでそれを利用して、成功時と失敗時ではそれぞれ処理を変えることにした。

失敗時にはフォームの下にエラーを表示させ、成功した場合はサブミットボタンを連続で押せないように、黒背景のレイヤーをz-indexで上に表示させ、その上に成功時のメッセージを表示するようにした。


「失敗時のJSON」
$ms = ['title'=>'内容に問題があります',
 'message'=>'メールアドレスが空です',
 'sentence'=>'no',
 'link'=>'/',
 'tag_back'=>'error_back',
 'tag'=>'error_message'
];


「成功時のJSON」
$ms = ['title'=>'成功です',
'message'=>'フォームは正常に処理されました',
'sentence'=>'yes',
'link'=>'/demo/ampform.html',
'tag_back'=>'success_back',
'tag'=>'success_message'
];

それぞれを、echo json_encode($ms, true);  でJSONエンコードして元のページに返している。それをamp-mustache を使って表示。

JSONにすると難しいことしてそうだが、sentenceや、tag_backやtagはただのクラス名なだけ。たとえば、


<div class='{{tag_back}}'>
が成功時には、
<div class='success_back'>
失敗時には、
<div class='error_back'>

で、error_backの時はcss でdisplay:none;にして、success_backはdisplay:block になっているだけ。これを使うと色々とできるようになると思う。

なお。デモページにあるチェックボックスは、同意ボタンを見立てて用意してある。CSSの隣接兄弟セレクタを使用して、チェックボックスにチェックが入ったら次の要素である.btn-submitを表示するようにしてある。


input:checked +.btn-submit{
		display: block;
	}

まぁ、これもチェックボックスが入っているかはアクション先でしっかりチェックを行ったほうがいいとおもう。