LoginSignup
22
15

More than 3 years have passed since last update.

【旧情報】 作ったWebサイトにフォームくらいは欲しいよねって時。

Last updated at Posted at 2020-06-22

2020-02-19追記

現時点ではGoogleForm側の仕様変更により、下記手順では出来なくなっています。

そもそもGoogleが推奨しているやり方ではない(と私は認識しています)ので、告知なく仕様の変更が行われ、機能しなくなる恐れがあります。
Googleの推奨する、GoogleAPIを利用したSpreadSheetへのレコード追加や、NetlifyFormなど、その他の手段を利用してフォームを作ることをオススメいたします!

やりたいこと

コーポレートやLPなどの案件の時、たまにこういう時あります。

Next.js & Nowや、Nuxt.js & Netlifyなどの構成で、サーバーレスで構築してね
あ、でもなんらかの形でFormは作ってね!

うーん、なんか簡単にできないかな
色々実現方法はあると思います

  • Netlify Form
    • Netlify利用ならあっという間にできます。
    • こちらの記事にめっちゃ詳しく乗ってます。今回は取り扱いません。
  • GoogleForm
    • 単純にリンク貼るだけでも、機能としては必要十分ですね。

「ただちょっとコーポレートとかで使うには、ザ GoogleFormって見た目がねえ。。」

:thinking:

やったこと

フォーム機能はGoogleFormに乗っかりつつ、フロントは作ってPOSTで通信する

はじめに

TypeScriptを一部入れてます。実際は.tsxです。Snippetが対応していないのか赤線出てるので.jsxにしてます。

1. GoogleFormの用意

普通にGoogleFormを使ってフォームを作りましょう。
問い合わせフォーム_-_Google_フォーム.png

2. POST通信に必要なパラメーターを確認

  • プレビューを利用して、実際のフォーム入力画面を表示しましょう。
    問い合わせフォーム_-_Google_フォーム.png

  • DevelomentToolsなどでソースを表示し、各フォームの値がどのようなparamでやりとりしているか確認しましょう。

    • 今回は、GoogleChromeにて⌘ + Shift + Cなどで開けるDevelimentToolsで説明します。 問い合わせフォーム_と_コンタクトページの追加_by_wataboru_·_Pull_Request__10_·_mediful_corporate.png
  • ラジオボタンなどhiddenで見つけにくい物は、ソース検索でentryと入力して探しましょう!
    問い合わせフォーム.png

  • 最後に、ActionURLを探しましょう。<formとか検索すれば見つけられます。
    問い合わせフォーム.png

3. 集めた情報をソースにまとめておく

オブジェクトとして、一つのファイル(.js.tsxなど)にまとめておきしょう。

constants/ContactGoogleForm.tsx
export const ContactGoogleForm = {
  action:
    'https://docs.google.com/forms/u/0/d/e/1FAIpQLSdCgDgog4LTBHSwuSliZwa9Q7mEt7dSZypREwDEJXVFmQvOvg/formResponse',
  name: 'entry.1902046290',
  gender: 'entry.1524608684',
  inquiry: 'entry.1741685192',
}

4. フロントコーディング

ここは楽しいところですね。いい感じに仕上げましょう必要ならUIフレームワークなども利用しましょう。
image.png

components/ContactForm/index.jsx
import React from 'react'
import styled from 'styled-components'

const StyledTable = styled.table`
  width: 100%;
  table-layout: fixed;
`

const TextArea = styled.textarea`
  margin-top: 10px;
  width: 100%;
  height: 100px;
`

const Th = styled.th`
  padding-top: 10px;
`

const StyledSubmit = styled.button`
  border: 1px solid #000;
  display: block;
  padding: 18px 90px;
  font-size: 16px;
  margin: 10px auto 0;
  color: #000;
`

const StyledInput = styled.input`
  width: 100%;
  border: solid 1px #000;
  padding: 4px;
  box-sizing: border-box;
  font-size: 16px;
`

const options: string[] = ['男性', '女性', '回答しない']

export const ContactForm: React.FC<any> = () => {
  return (
    <form>
      <StyledTable>
        <tbody>
          <tr>
            <Th>
              <p>お名前</p>
            </Th>
            <td>
              <StyledInput type={'text'} name={'name'} />
            </td>
          </tr>
          <tr>
            <Th>
              <p>性別</p>
            </Th>
            <td>
              {options.map((option) => (
                <div key={option}>
                  <label>
                    <input type={'radio'} name={'gender'} value={option} />
                    {option}
                  </label>
                </div>
              ))}
            </td>
          </tr>
        </tbody>
      </StyledTable>
      <p>お問い合わせ内容</p>
      <TextArea name={'inquiry'} />
      <StyledSubmit type={'submit'}>送信する</StyledSubmit>
    </form>
  )
}

5. データ連携(ReactHookForm利用)

今回は、超簡単にFormを生成できるReactHookFormを利用しました。
色々と便利に利用できますが、今回は以下の通り最低限利用しました。

  • FormのonSubmithandleSubmitと関数を渡す
  • 各Inputにref={register()}を追加
components/ContactForm/index.jsx
import React from 'react'
import styled from 'styled-components'

// react-hook-form
import { useForm, Controller } from 'react-hook-form'

// 先ほど取得したGoogleForm関連データ
import { ContactGoogleForm } from '@/constants/ContactGoogleForm'

// axios
import axios from 'axios'

// ~~~ 中略 ~~~

export const ContactForm: React.FC<any> = () => {
  const { register, handleSubmit } = useForm({
    mode: 'onChange',
  })
  return (
    <>
      <form noValidate onSubmit={handleSubmit(submit)}>
        <StyledTable>
          <tbody>
            <tr>
              <Th>
                <p>お名前</p>
              </Th>
              <td>
                <StyledInput type={'text'} name={'name'} ref={register()} />
              </td>
            </tr>
            <tr>
              <Th>
                <p>性別</p>
              </Th>
              <td>
                {options.map((option) => (
                  <div key={option}>
                    <label>
                      <input
                        type={'radio'}
                        name={'gender'}
                        value={option}
                        ref={register()}
                      />
                      {option}
                    </label>
                  </div>
                ))}
              </td>
            </tr>
          </tbody>
        </StyledTable>
        <p>お問い合わせ内容</p>
        <TextArea name={'inquiry'} ref={register()} />
        <StyledSubmit type={'submit'}>送信する</StyledSubmit>
      </form>
    </>
  )
}


const submit = (values) => {
console.log(values)
}

6. axiosを使ってPOST通信

components/ContactForm/index.jsx
// axios
import axios from 'axios'

// 先ほど作成したGoogleFormの情報
import { ContactGoogleForm } from '@/constants/ContactGoogleForm'

// ~~~~ 中略 ~~~~

const submit = (values) => {
  // ReactHookFormは、hundleSubmitに渡した関数に、
  // registerを利用して登録した各Inputの値をObjectとして渡されてくる。
  // values.nameやvalues.genderと呼び出せる。便利ですね!

  const GOOGLE_FORM_ACTION = ContactGoogleForm.action
  // CORS対策は必須
  const CORS_PROXY = 'https://cors-anywhere.herokuapp.com/'

  // PostのParm生成
  const submitParams = new FormData()
  submitParams.append(ContactGoogleForm.name, values.name)
  submitParams.append(ContactGoogleForm.gender, values.gender)
  submitParams.append(ContactGoogleForm.inquiry, values.inquiry)

  // 実行
  axios
    .post(CORS_PROXY + GOOGLE_FORM_ACTION, submitParams)
    .then(() => {
      window.location.href = '/thanks' // 成功時
    })
    .catch((error) => {
      console.log(error) // 失敗時
    })
}

ちゃんと、GoogleFormに飛んでますね!

  • 実行
    image.png

  • 確認
    image.png

(参考) Slack通知を実現

感想

これはこれで簡単に見た目作れるので、ミニマムでいいですよね。
Formとしての機能はGoogleFormで今回の用途としては必要十分でした。

参照

22
15
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
22
15