2021年4月27日火曜日

Googleフォームをカスタマイズしてなわとび記録アプリを作る

先日からなわとびを始めたんですが

何回飛べたか記録するアプリにいいのがなくて、

自作してみました。


まだ動くだけなので見た目がアレなんですが、

こんなのです。













Googleフォームをカスタマイズして作りました。

ネットで調べるとみんな簡単と言ってますが

なかなか苦労したので、メモを残しておきます。


【アプリ概要】

・iPhoneから使うアプリ(Webページ)。

・飛んだ日、跳び方の種類、飛んだ回数を入力し、送信ボタンを押すと記録できる。

・入力した内容はGoogleスプレッドシートに追記される。

・追記のみ。編集や削除はGoogleスプレッドシートで行う。(いずれ改修予定)

・日付はカレンダで入力。

・種類はプルダウンで入力。

・回数はキーボードで入力。

・日付、種類、回数はすべて文字列形式。日時や数値形式ではない。

 (↑残念ポイント。日付の扱い方がわからなかったため諦めて文字列にしました。)

・カレンダ入力やプルダウン、必須制御はWebページ側で行う。

・iPhoneで使うことしか考えていないので、PCではレイアウトが崩れる

 (↑こちらも残念ポイントです。)


(1)下準備

GoogleAppsScriptをGoogle Driveに追加

GoogleAppsScriptの説明と簡単にWebサイトを作る方法

上記のページを参考にGoogleAppsScriptをGoogle Driveに

インストールしました。実は私これを見落としてまして、

後述のhtmlページを作ったときの

「スクリプト関数が見つかりませんdoGet()」

というエラーに引っかかってしまい、3時間くらいハマりました。


(2)Googleフォームの作成










こんな感じですべて記述形式で質問を作成。

本当はこの時点で日付形式とか選択形式にしたかったんだけど

後述の手順で詰まってしまい諦めました。


(3)Googleフォームとスプレッドシートを連携

Googleフォームの標準機能でスプレッドシートに回答を出力するよう設定。

「回答」タブのこの辺から設定できます。






ちなみに、僕のはこんな感じに記録されていきます。








(4)入力フォームの作成

Googleフォームを自在にカスタマイズする

GoogleAppsScriptの説明と簡単にWebサイトを作る方法

こちらのページを参考にさせて頂きました。


たぶんGoogle側の仕様が変わったんでしょうが、

スクリプトエディタは画面左の↓から開くのが今の仕様のようです。













ちなみにご参考まで、私のソースも載せておきますね。

【コード.gs】

//URLをたたいたときに呼ばれる

function doGet(req) {

  const template = 'form';

  return HtmlService.createTemplateFromFile(template).evaluate();

}

// CSSを読み込む関数

function include(filename) {

  return HtmlService.createHtmlOutputFromFile(filename).getContent();

}

これはこちらのページのまんまですね。



【form.html】
<!DOCTYPE html>

<html>

  <head>

    <base target="_top">

    <meta charset="utf-8">

    <!-- form.cssの読み込みはコード.gsに作成した関数で行う -->

    <?!=include('form.css');?>

    <title>なわとび記録</title>

    <meta name="viewport" content="width=device-width">

  </head>

  <body>

    <main>

      <form action="https://docs.google.com/forms/u/0/d/e/123x123x123x123x123x123x123x123x123x123x123x123x123x123x/formResponse" method="post" target="hidden_iframe" onsubmit="submitted=true;">

        <p>

          <span class="title">日付</span>

        </P>

        <P>

          <input class="CalIphone" id="date" type="date" name="entry.123456789" required>

        </P>

        <P>

          <span class="title">種類</span>

        </P>

        <P>

          <select class="SelIPhone" id="type" name="entry.123456789" required>

          <option value="前跳び" selected>前跳び</option>

          <option value="後ろ跳び">後ろ跳び</option>

          <option value="前二重跳び">前二重跳び</option>

          <option value="後ろ二重跳び">後ろ二重跳び</option>

          </select>

        </P>

        <P>

          <span class="title">回数</span>

        </P>

        <P>

          <input class="NumIphone" type="number" value="80" name="entry.123456789" required>

        </P>

        <P>

          <input class="BtnIphone" type="submit" name="button" value="送信"></button>

        </P>

      </form>

  </main>

    <!-- jQueryのCDNを読み込んで使えるようにする -->

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script type="text/javascript">

        //今日の日時を表示

            window.onload = function () {

                //今日の日時を表示

                var date = new Date()

                var year = date.getFullYear()

                var month = date.getMonth() + 1

                var day = date.getDate()

              

                var toTwoDigits = function (num, digit) {

                  num += ''

                  if (num.length < digit) {

                    num = '0' + num

                  }

                  return num

                }

                

                var yyyy = toTwoDigits(year, 4)

                var mm = toTwoDigits(month, 2)

                var dd = toTwoDigits(day, 2)

                var ymd = yyyy + "-" + mm + "-" + dd;

                

                document.getElementById("date").value = ymd;

            }

    </script>

    <script type="text/javascript">var submitted = false;</script>

    <iframe name="hidden_iframe" id="hidden_iframe" style="display:none;" onload="if(submitted){window.location='https://docs.google.com/spreadsheets/d/123x123x123x123x123x123x123x123x123x123x123x/edit#gid=123456789';}"></iframe>

  </body>

</html>


※IDなどはてきとうな文字列にしています。

日付形式の制御がよくわからなかったのでGoogleフォームは
全部記述形式にして、Webページの方でカレンダ入力や
プルダウン入力を実装したところがミソです。
ミソであり、イケてない点です…。
Webページ側でカレンダを使って入力しますので、
回答結果はすべてyyyy-mm-dd形式で飛んでいきます。
きれいな形式で文字列が飛んでいくので結果の編集は
スプレッドシートなりExcelなりでなんなりと成形してくれ…
がこのアプリの設計ポリシー(笑)です。

記録ボタンを押したあとは、とりあえず記録内容を溜め込んでる
Googleスプレッドシートに画面遷移するようにしました。
(何も制御しないと、Googleフォームの画面に飛んでいってしまいます)
飛ばす記述は下記のページの「7. サンクスページへの遷移について」を
参考にさせて頂きました。

日付の初期値を当日にするコードは以下の
「input type = 'date'に現在日付を設定する」
を参考にさせて頂きました。


【form.css.html】
<style>
* {
    font-family: 'Montserrat', Arial, Helvetica, sans-serif;
}

main {
    width: 100vw;
    margin: auto;
    color: #000;
}

span.title {
    font-size: 90px; 
}

select.SelIPhone {
    font-size: 60px; 
}

input.NumIphone {
    font-size: 60px;
}

input.CalIphone {
    font-size: 60px;
}

input.BtnIphone {
    font-size: 60px;
}

</style>
こちらのページを参考にしつつ、ネットで調べて自力で書いた感じです。
今はまともなデザインになっていないので、このcssをいじくって
もう少し見栄えを良くしていこうと思います。


ちなみにform.htmlの
<meta name="viewport" content="width=device-width">
がまったく効いてないんですが、
Googleフォームのページの仕様のような気がします。
画面上部の
「このアプリケーションは、Google ではなく、別のユーザーによって作成されたものです。」
というグレーの部分を眺めていると、どうもグーグルフォームの
ページ自体がPC表示しかできないような気がして…違うんだろうか…。

あ、iPhoneのアイコンですが、ショートカットを
ホーム画面に配置して、こんな感じにしています。




















iOS標準の「ショートカット」を作成し、ホーム画面に
配置することで、アイコンをオリジナルのものに
できますよ。