5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HTMXを活用して簡単に実装するHTMLお問い合わせフォーム

Last updated at Posted at 2024-02-25

はじめに

57歳で製造業からWeb開発企業に転職して、やっと2年目に突入したピータンと申します。

Web制作者の方が作るランディングページにはかならずといってお問い合わせフォーム(コンタクトフォーム)がありますが、これを最近、気になっているHTMXを使ったら、どのくらい簡単にできるのか実験してみました。

結果的には、HTMLに対して、3行ほど、HTMXに関する記述を追加、変更するだけでフロントエンド側が完了しました。とても簡潔で良いなと思いました。ただし、バックエンドをどうするかの問題はあります。CSSも少し必要です。

完成品

お問い合わせを内容をメールで通知したり、SlackやDiscordに流すこともできるのでしょうが、今回はGoogleスプレッドシートに格納する方式としました。

animation

HTMLのポイント

次のように追加、変更しました。

index.html
    <script src="https://unpkg.com/htmx.org@1.9.10"></script>

これを書くだけでHTMXが使えるようになります。

index.html
      <form
        id="contact"
        hx-post="/api/submit"
        hx-target="#submit-button"
        hx-swap="outerHTML"
      >

これにより、<form>のSubmitボタン(今回は[送信]ボタン)がクリックされたら、/api/submitという相対パス指定されたAPIのエンドポイントに、問い合わせ内容を送信(POST)し、返却されたHTMLで、[送信]ボタンを置き換えます。具体的には、[送信]が、「送信されました。ピータンさん。お問い合わせありがとうございます。」に変わり、ボタンが押せなくなります。

index.html
        <div class="htmx-indicator loader"></div>

上記の1行で、APIが処理を終えるまでの間にローディングアニメーションを表示します。今回はloaderというCSSクラスで定義したCSSのローディングアニメーションを使用していますが、SVGファイルなども指定可能です。

index.htmlの全体は次になります。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>お問い合わせフォーム</title>
    <link rel="stylesheet" href="/style.css" />
    <link rel="icon" type="image/svg+xml" href="/logo.svg" />
    <script src="https://unpkg.com/htmx.org@1.9.10"></script>
  </head>
  <body>
    <div class="container">
      <form
        id="contact"
        hx-post="/api/submit"
        hx-target="#submit-button"
        hx-swap="outerHTML"
      >
        <h3>お問い合わせフォーム</h3>
        <h4>ご意見・ご要望をお寄せください。</h4>
        <fieldset>
          <input
            placeholder="お名前"
            type="text"
            name="name"
            tabindex="1"
            required
            autofocus
          />
        </fieldset>
        <fieldset>
          <input
            placeholder="メールアドレス"
            type="email"
            name="email"
            tabindex="2"
            required
          />
        </fieldset>
        <fieldset>
          <input
            placeholder="電話番号(任意)"
            type="tel"
            name="tel"
            tabindex="3"
          />
        </fieldset>
        <fieldset>
          <input
            placeholder="会社名(任意)"
            type="text"
            name="company"
            tabindex="4"
          />
        </fieldset>
        <fieldset>
          <textarea
            placeholder="メッセージをこちらにどうぞ...."
            type="text"
            name="message"
            tabindex="5"
            required
          ></textarea>
        </fieldset>
        <button name="submit" type="submit" id="submit-button">送信</button>
        <div class="htmx-indicator loader"></div>
        <p class="copyright">
          Powered by
          <a
            href="https://over40web.club"
            target="_blank"
            title="Over 40 Web Club"
            >Over 40 Web Club</a
          >
        </p>
      </form>
    </div>
  </body>
</html>

追加の説明

今回の実装において、HTMXに関連してindex.htmlに3つのタグの追加、変更を追加することを説明しましたが、他にも留意することがあります。Googleスプレッドシートに結果を格納するバックエンドのコードはもちろん必要になりますが、フロント側についてまず説明します。

HTML側が気にすぺきポイントは、今回のバックエンドのコードに依存し、次になります。

バックエンドのコードは、index.htmlが以下のname属性を持つことを前提にしています。

  • name
  • email
  • tel
  • company
  • message

また、<form>タグで指定しているsubmit-buttonというid属性を持つ要素が必要です。

バックエンドのコードは、次のいずれかの形式のHTMLを返却します(正常時又はエラー時)

<button disabled id="api-success">送信されました。${name}さん、お問い合わせありがとうございます。</button>

又は

<button disabled id="api-error">エラーのため送信できませんでした。申し訳ございません。${error}</button>

このため、上記の2つのCSSクラスapi-successapi-errorに対して、CSS(エラーの場合は赤字にするなど)を書くことになります。

今回は、<form>タグでhx-post="/api/submit"と設定していますが、お問い合わせフォームと異なるドメインのAPIが、そのドメイン外からの使用を許可していれば、hx-post="https://abc.com/contact"みたいな感じで絶対パスを設定することも可能です。

バックエンドは、ExpressというNode.jsのWebフレームワークを用い、Google Sheets APIを使用して、Googleスプレッドシートに格納しています。

また、全体をVercelにデプロイし、APIはサーバレスファンクションで動かすために、/apiフォルダ以下に格納し、vercel.jsonというファイルを置いています。

コード全体は、GitHubを参照願います。また、よろしければ、次の関連記事も参照していただければと思います。

関連記事

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?