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

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

ただいまの
回答率

88.92%

[Ajax] <form>データをFormDataオブジェクトに格納できない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,725

teradog

score 19

お世話になります。 
WordPressでサイトを構築しています。
archive(記事の一覧)ページにフィルター(検索)機能を作っています。
Ajaxを用いて、フィルター結果を表示させたいのですが、データの授受が思い通りにいかず悩んでおります。

些細なことでも構いません。ご助言いただきたく何卒よろしくお願いいたします。

前提

Ajax(JavaScript,jQuery)の知識、経験はほぼ0です。用語や概念に誤りがあるかもしれません。ご了承ください。
素人の語彙力でネット情報を漁りながらコーディングしています。
WordPressでのサイト構築も初めてで、PHPやCSSなども同程度です。

目標

記事のフィルタリングは、タクソノミー(一般的なブログで、カテゴリーやタグと呼ばれるもの)を<form>で選択させ、画面遷移を伴わずにAjaxでフィルタリングした記事一覧を表示する仕組みを実現したいです。

<form>データをFormDataオブジェクトに格納し、Ajaxでサーバに送信し、PHPで条件に応じた記事を取得しようと考えています。

現実

formデータをFormDataオブジェクトに格納して送信していますが、送信できていないように見えます。
(実際には送信していて、私が取り出せていないだけかもしれません。)

やったこと

HTML,javaScript,PHPをそれぞれ以下のようにコーディングしました。

<form id="search-form" action="[自身のURL]" method="POST">
  <ul id="dropdown-filter" class="collapsible" data-collapsible="accordion">
    <li>
      <div class="collapsible-header font-base back-sub-l5">
        <div class="container">
          <i class="fa fa-book fa-fw" title="filter-Status" aria-hidden="true"></i>Status
        </div>
      </div>
      <div class="collapsible-body font-base back-sub-a15">
        <div class="container">
          <dl>
            <dt>DATA 1</dt>
            <dd>
              <div class="row flex">
                <div class="col s12 m4 l3 margin-clear">
                  <input type="checkbox" class="filled-in" id="parameter" name="Status[]" value="parameter" checked="checked">
                  <label for="parameter">parameter</label>
                </div>
              </div>
            </dd>
            <dt>DATA 2</dt>
            <dd>
              <div class="row flex">
                <div class="col s12 m4 l3 margin-clear">
                  <input type="checkbox" class="filled-in" id="parameter2" name="Status[]" value="parameter2" checked="checked">
                  <label for="parameter2">parameter2</label>
                </div>
                <div class="col s12 m4 l3 margin-clear">
                  <input type="checkbox" class="filled-in" id="parameter3" name="Status[]" value="parameter3" checked="checked">
                  <label for="parameter3">parameter3</label>
                </div>
              </div>
            </dd>>
          </dl>
        </div> 
      </div>
    </li>
    <li>
      <div class="collapsible-header font-base back-sub-l5">  
        <div class="container">
          <i class="fa fa-flask fw" title="filter-Status2" aria-hidden="true"></i>Status2
        </div>  
      </div> 
      <div class="collapsible-body font-base back-sub-a15"> 
        <div class="container">
          <div class="row flex">
            <div class="col s6 m3 l3 margin-clear">
              <input type="checkbox" class="filled-in" id="fact" name="Status2[]" value="fact" checked="checked">
              <label for="fact">fact</label>
            </div>
            <div class="col s6 m3 l3 margin-clear">
              <input type="checkbox" class="filled-in" id="fact2" name="Status2[]" value="fact2" checked="checked">
              <label for="fact2">fact2</label>
            </div>
            <div class="col s6 m3 l3 margin-clear">
              <input type="checkbox" class="filled-in" id="fact3" name="Status2[]" value="fact3" checked="checked">
              <label for="fact3">fact3</label>
            </div>
          </div>
        </div>  
      </div>
    </li>
    <li class="active"> 
      <div class="collapsible-header font-base back-sub-l5 active">   
        <div class="container">       
          <div class="row">
            <div class="col s12 m4 l4">  
              <input type="reset" value="reset" class="btn w100">   
            </div>
            <div class="col s12 m4 l4">
              <input type="submit" value="search" class="btn w100">
            </div>
          </div>
        </div>
      </div>
    </li>
  </ul>
</form>
  • <form>タグの中は<ul>,<dl>,<div>などがいろいろ入っています。
  • cssはMaterializeというフレームワークを使っています。調整のために独自のクラスも追加してます。
  • 質問用に一部を抜粋しています。

特別なことはやってません。
<form>タグの中がわちゃわちゃしていて、ここが悪さの原因なのかも?ということを気にしています。

$('form#search-form').on('submit', function(event) {
    event.preventDefault(); //従来のPOSTイベントを解除

    var fd = new FormData($(this)); //FormDataオブジェクトを生成
    fd.append('action',ajax_arg.action);
    fd.append('_ajax_nonce',ajax_arg.nonce); 

   // ajax_arg.*** は、function.phpで定義(wp_localized_scriptでJavaScript渡している)

    $.ajax({
      type: 'POST',
      url: ajax_arg.url,
      data:fd,
      processData: false,
      contentType: false,
      success: function( response ){
        $("div#search-result").html( response.data );
      }
    });
  });
  • FormDataを生成して、ajaxのdataとして送信します。
  • fd.append('action',ajax_arg.action);でサーバ側で実行する関数を指定しています。
function myAction(){
  check_ajax_referer( 'myAction' ); //CSRF対策
  $query_args = get_form_post('lg_archive_filter'); //POSTデータを整形する関数
  $result = '';

 /*ここで、サブクエリを発行して、フィルタリングの結果を返す */

  wp_send_json_success($result);
}
add_action('wp_ajax_myAction','myAction');
add_action('wp_ajax_nopriv_myAction','myAction');
  • サーバ側では、受け取ったPOSTデータを整形して、サブクエリを発行し、その結果を返します。

確認できたこと

JavaScriptでは、FormDataの中身がどうなっているか確認しました。

console.log(fd);

では、何が格納されているのかわからず。

for(item of fd) console.log(item);

で、確認しました。
結果は、次の通りで、appendしたデータしかありません。

["action", "myAction"]
["_ajax_nonce", "**********"]

意図した、PHPの関数myActionは呼び出されています。
PHPでも$_POSTをコンソールに出力したところ、同様に2つのデータしか表示されません。

 Array
(
    [action] => myAction
    [_ajax_nonce] => **********
)

質問

AjaxによるPHP関数の実行と、応答を受け取ることはできましたが、そもそも<form>データが渡せていません。
FormDataオブジェクトを生成する際、<form>のデータを持たせるために何が間違っているのか分かりません。

ご助言いただければ幸いです。よろしくお願い致します。

補足事項

次の環境で確認しております。
OS X El Capitan 10.11.6
サーバ : Apache
PHP のバージョン : 5.6.19
FireFox 50.1.0
Chrome 55.0.2883.95 (64-bit)

jQuery CDN : code.jquery.com/jquery-2.1.1.min.js

FormDataの対応ブラザであるか「window.FormData)」で確認済みです。

MaterializeはCDNで利用しています。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+2

ざっとしか見ていませんが、FormDataの引き数にjQueryオブジェクト渡してしまっているのが問題なのでは?

var fd = new FormData( this ); //FormDataオブジェクトを生成

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/16 11:59

    早速のご回答ありがとうございます。
    ご指摘のとおり修正したところ、意図通りデータを送信することができました。
    DOMエレメント、jQueryオブジェクトの違いや、new FormDataにはDOMエレメントを渡すという基本的なことがわかっていませんでした。
    ありがとうございました。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る