質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.55%

GASのJSONPを返す処理でフォーム送信後にページ遷移して画面に「undefined({"work":"success"})が表示される

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 815

cube_3110

score 17

前提・実現したいこと

お問い合わせフォームのsubmitボタン押下してフォーム送信後、JSONPを返してお問い合わせフォームの画面に戻ること。

発生している問題・エラーメッセージ

お問い合わせフォームのsubmitボタン押下してフォーム送信後、ページ遷移して画面にundefined({"work":"success"})が表示される

該当のソースコード

<template>
<div id="contact">
  <section class="contact_section">
    <div class="container">
      <form action="GASのウェブアプリケーションのURL" class="form-box">
        <input name="SPREADSHEET_ID" type="hidden" value="-スプレッドシートのID">
        <input name="SHEET_NAME" type="hidden" value="フォームデータ">
        <h2 class="contact_h2">Contact</h2>
        <div class="form-item-box">
          <label class="control-label">Name</label>
          <div class="">
            <input type="text" class="form-control" name="your-name" placeholder="Name">
          </div>
        </div>
        <div class="form-item-box">
          <label class="control-label">Email</label>
          <div class="">
            <input type="email" class="form-control" name="your-email" placeholder="example@email.com">
          </div>
        </div>
        <div class="form-item-box">
          <label class="control-label">Message<span class="label-required">必須</span></label>
          <div class="">
            <textarea class="form-control" name="your-message" placeholder="Message" rows="8" required id="message"></textarea>
          </div>
        </div>
        <div class="form-item-box">
          <div class="form-button-box">
            <button class="form-button" type="submit" v-on:click="sendMessage()">Submit</button>
          </div>
        </div>
      </form>
    </div>
  </section>
</div>
</template>

<script>
  export default {
    title: 'Contact',
    description: 'contact_pages',
    methods: {
      sendMessage() {
        var form = $('form');
        var submitBtn = form.find('button[type=submit]');
        if(getElementById('message') === '') {
          alert('メッセージを入力してください');
          return false;
        }
         $.ajax({
           url: form.attr('action'),
           dataType: 'jsonp',
           data: form.serialize(),
           beforeSend: function() {
             return submitBtn.prop('disabled', true);
           },
           complete: function() {
             return submitBtn.prop('disabled', false);
           },
           jsonpCallback: 'console.log',
           error: function(response) {
             return console.log(response);
           }
         });
      }
    }
  }
</script>
function doGet(e){
  // フォームから受け取った値を使って必要な変数を作っていきます --------
  var sheet = SpreadsheetApp.openById(e.parameter.SPREADSHEET_ID).getSheetByName(e.parameter.SHEET_NAME)
  var last_row = sheet.getLastRow()

  // スプレッドシートに追加したくない値を「ignore_array」で指定して、
  // 必要なデータだけを「form_data」に入れていきます。
  var ignore_array = ['メールアドレス', 'SPREADSHEET_ID', 'SHEET_NAME', 'callback', '_']
  var form_data = {}
  for(var key in e.parameter){
    if(ignore_array.indexOf(key) === -1){
      form_data[key] = e.parameter[key]
    }
  }

  // スプレッドシートの初期設定 --------
  // スプレッドシートに何も値が入っていないと以降の処理で問題が起きる+フォームの送信日時を挿入する為に、
  // A1に「タイムスタンプ」を挿入します。
  if(last_row === 0 && sheet.getLastColumn() === 0){
    sheet.getRange(1, 1).setValue("タイムスタンプ")
    last_row++
  }

  // Spreadsheetにフォームのデータを挿入 --------
  // スプレッドシートの1行目をヘッダーとして取得します。
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
  // 「form_data」に「for in」を使ってループ処理を行います。
  for(var key in form_data){
    for(var i = 0; i < headers.length; i++){
      if(headers[i] === key){
        // ヘッダーとkeyが一致した時に、そのヘッダーの列の新しい行(最後にデータが入ってる行の次の行)に
        // フォームの値を挿入します。
        sheet.getRange(last_row + 1, i + 1).setValue(form_data[key])
        break
      } else if(headers.length === i + 1){
        // ヘッダーとkeyが最後まで一致なかった時は、そのkeyを新しいヘッダーとして追加して、
        // そのヘッダーの列の新しい行にフォームの値を挿入します。
        var new_column = sheet.getLastColumn() + 1
        sheet.getRange(1, new_column).setValue(key)
        sheet.getRange(last_row + 1, new_column).setValue(form_data[key])
      }
    }
  }

  // フォーム以外のデータ挿入と個別処理 --------
  // 今回はタイムスタンプだけですが、例えば個別の「お問い合わせ番号」が要るとか、
  // セルの最後に「進捗状態」を入れる等用の処理です。
  headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
  for(var i = 0; i < headers.length; i++){
    switch(headers[i]){
      case 'タイムスタンプ':
        // 「タイムスタンプ」の場所に日時のデータを挿入。
        sheet.getRange(last_row + 1, i + 1).setValue(new Date())
        break
    }
  }

  // フォームのデータにメールアドレスが有ればメールを送信 --------
  if(e.parameter.メールアドレス){
    send_mail(e.parameter.メールアドレス, headers, form_data)
  }

  // JSONPを返す処理 --------
  // 今回は単純なデータしか返していませんが、頑張れば色々出来そうですねー。
  var return_json = JSON.stringify({work:'success'})
  return ContentService.createTextOutput(e.parameter.callback + '(' + return_json + ')').setMimeType(ContentService.MimeType.JAVASCRIPT)
}

function send_mail(mail_address, headers, form_data){
  // HTMLメールとテキストメールのテンプレートを準備します。
  var html_mail = HtmlService.createTemplateFromFile('html_mail')
  html_mail.headers = headers
  html_mail.form_data = form_data

  var text_mail = HtmlService.createTemplateFromFile('text_mail')
  text_mail.headers = headers
  text_mail.form_data = form_data

  // メール送る際のオプションを設定します。
  var options = {}
  options.noReply = true
  // 「evaluate()」を行う事でテンプレート内のスクリプトを実行する事が出来ます。
  options.htmlBody = html_mail.evaluate().getContent()

  // テキストメールとオプションを設定してメールを送信。
  GmailApp.sendEmail(mail_address, '自動返信メール - 【GAS】 スプレッドシートと連携したAjaxフォーム', text_mail.evaluate().getContent(), options)
}

試したこと

スプレッドシートにデータが挿入されていることは確認しました。

補足情報(FW/ツールのバージョンなど)

JSONPを返す処理が怪しい気がしてます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

jQueryの設定が有効になっていませんでした。
Submitボタン押下時の動作をデベロッパーツールのconsoleで確認したら$ is not foundとエラーログが一瞬表示された為、設定を見直して再度試してみたら問題なく通りました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.55%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる