応募フォームをできるだけフロントエンドで作ってみた
今、弊社では日中交流プロジェクト「対話山東」に携わっているのですが、その中で応募フォームを作成する必要が出てきました。 サーバーを借りることは難しかったので、できるだけフロントエンドで完結するように作ってみました。 実際につくったもの
オンライン参加も受け付ける予定なので、奮ってお申し込みください!
以下、制作の記録と自戒メモです。
# 使ったライブラリ
- Vue.js
電氣羊のお気に入りフレームワークです。 これがないと話になりません。最初はhtmlに生のJavaScriptを書いていたのですが、規模が大きくなってきたので、TypeScriptを使ったWebアプリに書き換えました。 うん、最初からこっちにするべきだったかもしれません。
- Bulma
これまたお気に入りのCSSフレームワーク。 仮想DOMと相性がいいそうなので、愛用しています。 ~~ 最初からWebアプリで作るならVuetifyの方が ~~
色見やグリッドデザインなど、やっぱりすごい人の作ったものは楽ができますね。
- Airtable
集計したデータを可視化するためのLowCodeなデータベース。 GAS + Googleスプレッドシートも考えましたが、GASの6分/時間制限にひっかかりそうだったので、こちらを選択。 実験中にリクエストを投げすぎて30秒止まってしまったのは内緒。
@typeもあったはずですが、今回は面倒だったので @ts-ignore してしまいました。
- elastic email
応募フォームだと、受け付けた内容をメールで返すのが一般的ですが、フロントエンドだけだとどうしたものか…… そこで見つけたのがこれ。 elastice email は npm にも公式ライブラリがあったので、smtp.js自体は使いませんでしたが、勉強になりました。
- Dark
Airtableもelastic emailもAPI Keyで認証するのですが、ハードコーディングしていいものか、迷っていました。 せめてOrigin認証くらいはしようか、ということで
一旦TokenをDarkに送る → TokenとOriginを見て正しければ上記2つのAPI Keyを返す
という構造にしました。
これまでに使ったことのあるライブラリをメインに、欲張りセットで頑張ります。 作業日数は2日強! めぇ~~~~ん
# つくってみた
Vueアプリの土台づくり~ライブラリ導入です。
vue create myform
yarn add bulma sass-loader node-sass airtable elasticemail
簡単ですね。あ、VuexとTypeScriptを使う設定です。
上でも書いた通り、airtabelはType定義無しで使っちゃいました。
だってどうせ上手く使わないとRecordsってanyみたいなもんだし
あとは参加者情報、午前の部、午後の部、マッチング会とコンポーネントをガリガリ書いていきます。 情報はVuexがまとめて持ってくれるので楽です。 最後にDarkにFetch、Originが正しければAPI Keyを入手できるので、Airtableにレコードを作成し、elasitic email経由でメールを出すだけです。
# ハマったところ
Vueのstyleの初期設定に text-align: center と margin-top: 60px があるのをうっかり忘れて頭をかく。
Vueの開発用サーバーがポート番号8080なのを忘れていて、Origin認証に失敗する。
Vueアプリの置き場所がTOPではない場合の設定の書き方を忘れて、アップしてから焦る。 vue.config.jsのpublicPathでしたね。
VueのPublicPathを本番環境に合わせたところ、今度は開発用サーバーが立ち上がらない。 process.env.NODE_ENV === 'production' ? '/shandong/' : '/' だよ!
Form内のButtonタグのClickイベントで @click.prevent.stop を忘れる。
と、本当にVue使いか!と突っ込まれそうなうっかりミス多発でした。
fromとformをタイポ。そして気が付かない。
電話番号とFAX番号にバリデーションを付けてみた……ら、必須ではないはずのFAX番号が必須になっていた。 ちゃんと空白をはじいておきましょうね。
AirtableのSingle Selectの項目名を変更忘れ。Fetchが通らなくなった。 ちゃんとRecordの型定義をしましょう。
Airtableの負荷制限にひっかかる……
Darkから返ってくるStringは "\"string\"" とダブルクォーテーション付きの文字列だった!
res.text() にcatch()を書いてエラーがでる
実際に書いていたのはこんなスクリプト。
res.text().then((t) => {
// なぜかcatchブロックの後にthenブロックが実行される
if (t !== '"access_invalid"') {
dispatch('createRecords', t);
} else {
commit('raiseFetchError', 'access_invalid');
}
}).catch(() => {
// なぜかthenより先にここが実行される
commit('raiseFetchError', 'res.text()_failed');
})
MDNをよく見たら、Body.text()にはthen()しか定義されていない模様。 やっぱりドキュメントをちゃんと読まなきゃ。
# 新しく使った技術メモ
# elastic email
elastic email は初めて使ったけれど便利。 100通/日まではトライアルアカウントで送れるし、課金しても0.09$/1000通と破格。 クレジットカードで10$~
なお、npmの公式ページにはなかったような気がするけれど、 body_text を body_html にするとHTMLメールを送ることができた。 次はテンプレートにも挑戦したい。
const client = elasticemail.createClient({
username: 'USER_NAME',
apiKey: 'MY_API_KEY',
});
// 中略
const msg = {
from: 'abc@xyz.com',
from_name: 'NAME',
to: 'xyz@abc.com',
subject: 'お申込みありがとうございます',
// body_text: mailBody,
body_html: mailBody, // ここを変えた
};
client.mailer.send(msg, (err: any, result: any) => {
if (err) {
commit('raiseFetchError', 'mail_send_failed');
} else {
commit('mailOk', result);
}
});
# Dark
Darkは遊びでしか触っていなかったけれど、めちゃくちゃ楽しい。 Trail Drivenというのが素晴らしい。 とにかくやってみて、失敗したときの変数や記録を残してくれているのがすごい。 そしてプログラムを書き換えたときに、同じ条件でやり直してくれる。 可視化の程度がすごすぎる。Dark大好き。Dark Love。 まだベータ段階で将来的な料金設定がどうなるか分からないけれど、絶対に使い続けたい。
強いていえば、ググラビリティが低いのが難点。 Darkで調べているのに、 「もしかして Dart 」 と言われてしまう。 プログラミング言語同士、いっしょに検索する単語が似通っているのか、Darkと思って読んでいたらDartだったこともしばしば。 ここはDarkのこれからに期待。
# iframe
実はこれまであまり使っていなかった。 srcにv-bindできるのか、と思ってやってみたら成功したので、今回取り入れてみました。 データを別の静的HTMLにおいておけるから、便利かもしれない。
# 時間の都合で諦めたもの
# transition
Vueのtransitionを上手く使えたらもっとスムーズな挙動になったのですが、時間の都合で断念。 Vuetifyにしていれば、 y-transition とかですぐにできたのだけれど……
# Webフォントやアイコン
これも本当はこだわるべきなんだろうけど、手が回らず…… 次に機会があれば手を出したい。
# フォームのサイズやグループ
これも全くこだわれなかった部分。 どんな長さが想定される入力部分も、とりあえず一行分確保しているのでメリハリがない…… 本職の方々の力を思い知るところ。
# 最後に
突貫工事のため、いくつかうっかりミスがあったり、変なところで躓いたりしましたが、今は上手く動いてくれるのを祈るばかり。 あ、最後の最後に大量の静的サイトを作るのに、Jupyterを使ったのですが、やっぱりPythonは楽ですね。 {}でブロックを作らないのが見やすいし、同期/非同期をあまり意識しないので頭への負荷が低い気がします。 次はPython + Darkで何かしてみたいなぁ。
# PR
JavaScript 至極の入門書!すぐに動かして楽しめるVue/Nuxtもオススメ!

ゴールデンブリッジでは、
翻訳・通訳・インバウンドツアー・国際会議運営など
ご用命をお待ちしております!
また、翻訳に関わるツール・ソフトウェアの開発等についてもお気軽にお声掛けください。