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

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

ただいまの
回答率

89.12%

twigでjavascriptのajaxを使いたい

解決済

回答 2

投稿 編集

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

yuhei_seguchi

score 13

前提・実現したいこと

就職活動で提出するポートフォリオ製作のため、PHP(ViewはTwig)で簡単な画像投稿サイトを作っています。
投稿した画像を作品ごとに検索出来たら便利だなぁと思い、セレクトボックスで選択した作品を値としてajaxでプログラムファイル(PHP)に飛ばし、POSTで受け取るようにしたいです。

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

発生している問題というか疑問なのですが、
・ajaxでプログラムファイルに飛ばした(ここまでは確認できた)あと、どのようにしたらプログラムファイルが出した値を最初のtwigで利用できるのか
というものです。

該当のソースコード

//セレクトボックスを選択(Twig)
<input type="hidden" name="entry_url" value="{{constant('prototype\\Bootstrap::ENTRY_URL')}}" id="entry_url" >
<div id="selectImage">
  <select name="selectedImage" id="selectedImage">
    <option>-作品を選択できます-</option>
    <option value="ほしのこえ">ほしのこえ</option>
    <option value="雲のむこう、約束の場所">雲のむこう、約束の場所</option>
    <option value="秒速5センチメートル">秒速5センチメートル</option>
    <option value="星を追う子ども">星を追う子ども</option>
    <option value="言の葉の庭">言の葉の庭</option>
    <option value="君の名は。">君の名は。</option>
    <option value="天気の子">天気の子</option>
  </select>
</div>
<div id="ajax">
  <p>{{ajax}}</p>
</div>
//下でセレクトボックスで受け取った作品名の画像を表示
<div id="display">
  <table>
    <tr>
      <th>&nbsp;</th>
      <th>作品名</th>
      <th>ユーザー名</th>
      <th>画像</th>
    </tr>
  {% if selectedArr | length > 0 %}
    {% for value in selectedArr %}
      <tr>
        <td>&nbsp;</td>
        <td>{{item_name}}</td>
        <td>{{user_name}}</td>
        <td><img src="{{constant('prototype\\Bootstrap::ENTRY_URL')}}{{image}}" alt="{{item_name}}" width="193" height="130"/></td>
    {% endfor %}
      </tr>
//セレクトボックスのバリュー値を受け入れてajax.phpに飛ばす(ajax)
$(function(){
  var entry_url = $("#entry_url").val();
    $('#selectedImage').on('change', function () {
        var selectedImage = $('#selectedImage').val();
        $("#ajax").text("データの取得中です");
        $.ajax({
            type: 'GET',
            url: entry_url + "ajax.php?selectedImage=",//entry_urlはローカルのurl
            data: selectedImage
        }).done(function(){
            $("#ajax").text("complete");
        });
    });
});
//ajax.php
require_once dirname(__FILE__) . '/Bootstrap.class.php';

use prototype\Bootstrap;

$db=new PDODatabase(Bootstrap::DB_HOST, Bootstrap::DB_USER,Bootstrap::DB_PASS,Bootstrap::DB_NAME,Bootstrap::DB_TYPE);

//選択された作品を取得
if(isset($_GET['selectedImage']) === true){
    $selectedImage = (isset($_GET['selectedImage']) === true) ? $_GET['selectedImage'] : '';
    $table = " image ";
    $column = " item_name, image, regist_date, user_name ";
    $where = ' item_name = ? ';
    $arrVal = [$selectedImage];
    $res = $this->db->select($table, $column, $where, $arrVal);
}
echo $res;

最終的に出てきた$resを最初のtwigに渡して、非同期的に表示させたいのですがやり方がわからないのです。
どのようにすればよいのかわからず困っています。
もしくは不可能なのでしょうか、、

ちなみに、javascriptは動いているのは確認できました。
どなたか、ご教授お願いします。m(-_-)m

追記

$(function(){
    $('#selectedImage').on('change', function () {
        var selectedImage = $('#selectedImage').val();
        $("#ajax").text("データの取得中です");
        $.ajax({
            type: 'GET',
            url: entry_url + 'ajax.php?selectedImage=' + selectedImage,
            dataType:'JSON',
            data: selectedImage
        }).done(function(data){
            console.log(data);
        });
    });
});
<?php
namespace prototype;

require_once dirname(__FILE__) . '/Bootstrap.class.php';

use prototype\Bootstrap;
use prototype\lib\PDODatabase;
use prototype\lib\Session;
use prototype\lib\Item;
use prototype\lib\Method;

$db=new PDODatabase(Bootstrap::DB_HOST, Bootstrap::DB_USER,Bootstrap::DB_PASS,Bootstrap::DB_NAME,Bootstrap::DB_TYPE);
$ses=new Session($db);
$itm=new Item($db);
$meth=new Method($db);

echo 1;

追記2

$(function(){
    $('#selectedImage').on('change', function () {
        var selectedImage = $('#selectedImage').val();
        $("#ajax").text("データの取得中です");
        $.ajax({
            type: 'GET',
            url: entry_url + "ajax.php?selectedImage=",//entry_urlはローカルのurl
            data: selectedImage
        }).done(function(data){
            console.log(data);
        });
    });
});
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

Twigとは関係ないところでつまずいていると思います。

Ajaxの基本としては非同期でリクエストを渡してそのレスポンスを受け取ることです。
今のところ「リクエストを渡してそのレスポンスを受け取る」はできていると思います。

仮に下記のようにしてみてください。

        }).done(function(data){
            console.log(data);
        });
<?php
echo 1;

するとAjax実行結果がブラウザ開発ツールのコンソールに「1」と出ると思います。

つまり、PHP側で出力された情報がそのまま返ってくるわけです。
ただし「出力」なのでPHP側が出力できる内容は通常HTMLを出力する場合と同じく「文字列」です。

ただ、単に文字列だとデータを受け取った場合に処理がしづらいです。
そういう時に使われるのが「JSON」です。

Ajax実行するところも少し変えます。

        $.ajax({
            type: 'GET',
            url: entry_url + "ajax.php?selectedImage=",
            dataType: 'JSON',
            data: selectedImage
        }).done(function(data){
             console.log(data);
        });


※オプションについては右記を確認→jQuery.ajax()

$this->db->select()がどのような情報を返しているのか分かりませんが、
DB取得結果の配列としたらそのまま下記のようにします。

echo json_encode($res);

ここでブラウザ開発ツールのコンソールを確認するとおそらく取得しようとしていたデータが配列で表示されると思います。

あとはJavaScriptの操作によってその配列を好きなように加工するだけです。

コードを見た感じでしかないですが、検索処理結果を一覧にしようとしてるんでしょうか?
でしたらJavaScriptで一度tableで作っているリストをクリアし、JavaScriptでリストを作って埋め込みましょう。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/24 17:03

    1つ1つ段階を追っていくものなのでphp側はecho 1だけにしたほうが良いのと
    dataTypeはデフォルトのままで良いと思います。

    キャンセル

  • 2019/07/24 23:07

    ありがとうございます。。
    上手く動いたので、ここから自分の力で頑張ります。
    ありがとうございました!

    キャンセル

  • 2019/07/24 23:21

    理解につながったようで何よりです

    キャンセル

+2

もしくは不可能なのでしょうか、、

はい、TwigはPHPで実行されて、JavaScriptの実行時にはすでに動作完了しているので、「JavaScriptで取ってきた結果をTwigに投げ込む」ようなことは不可能です。

代替案としては、

  • Ajaxで呼ばれるPHPでTwigを利用してHTML断片を生成して、それをJavaScript側に返して、JavaScriptでは出来上がったHTMLだけを埋め込むようにする
  • Twigではなく、JavaScriptサイドでHTMLを構築する

といった方法が考えられます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/23 15:35

    >Twigを利用してHTML断片を生成
    あ、なるほど。リスト部分だけ切り出せば共有できますね。

    キャンセル

  • 2019/07/24 16:24

    ありがとうございます!
    >はい、TwigはPHPで実行されて、JavaScriptの実行時にはすでに動作完了しているので、「JavaScriptで取ってきた結果をTwigに投げ込む」ようなことは不可能です。
    勉強になりました。。

    >Ajaxで呼ばれるPHPでTwigを利用してHTML断片を生成して、それをJavaScript側に返して、JavaScriptでは出来上がったHTMLだけを埋め込むようにする
    こんな方法があったんですね。。ありがとうございます。
    javascriptで返す際のデータタイプはJSONになりますか?それともHTMLですかね?
    理解がおぼろげなので、教えていただけると嬉しいです。

    キャンセル

  • 2019/07/24 16:26

    追記、ajaxで送る際のデータタイプのことです。
    dataType: 'JSON'か
    dataType: 'HTML'か
    どちらになりますでしょうか。

    キャンセル

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

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