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

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

ただいまの
回答率

88.10%

ajaxを使った "コメント表示" と "コメント書き込み"をループさせて機能させたい

解決済

回答 2

投稿

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

score 18

前提・実現したいこと

インスタグラムのように複数の投稿が下へ連なっている各投稿に対して、"コメント表示" と "コメント書き込み"をajaxをループさせながら即時実行したい。

発生している問題

"コメント表示" と "コメント書き込み"が一番下(table_3のみ)の投稿に対してしか反映されない。
イメージ説明

該当のソースコード

<?php

echo'<!doctype html>';
echo'<html lang="en">';

//ユーザーコードNo.100, 男性のユーザーを想定。
$code=100;
$sex='男性';

//今回は3テーブルを用意
$table[0]='table_1';
$table[1]='table_2';
$table[2]='table_3';


echo'<body>';

//テーブルの数だけループをまわす。
foreach($table as $key => $value)
{
    //jqueryで自動的に各テーブルからメッセージと性別をselectして表示される。
    echo'<div class="all_show_result_'.$value.'"></div>';

    //メッセージフォーム
    echo'<input class="messages_'.$value.'">';

    //コメントボタンが押されたらinputで記入された内容がjqueryで即時各テーブルにinsertされる。
    echo'<button class="ajax_add_'.$value.'">コメント</button>';
}

echo'</body>';
echo'</html>';

?>


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

<script>

$(function(){
// レコードを全件表示する
function getAllData(){
    $.ajax({
        type: "POST",
        url: "teratail_ajax_show_all.php",
        data:{table: "<?php echo$value; ?>"},

        success: function(data) {
            // 取得したレコードをeachで順次取り出す
            $.each(data, function(key, value)
            {
                // #all_show_result内にappendで追記していく
                $(".all_show_result_<?php echo$value;?>").append(
                "<div>" + value.sex + "</div>" + 
                "<div>" + value.messages + "</div>");
            });
        },
    });
}

// 関数を実行
getAllData();





// .ajax_add_'.$value.'がクリックされた時の処理
$(".ajax_add_<?php echo$value;?>").on('click',function(){
        $.ajax({
            type: "POST",
            url: "teratail_ajax_add.php",
            datatype: "json",
            data: {
                "messages"        : $(".messages_<?php echo$value;?>").val(),
                "table"            : "<?php echo$value; ?>",
                "code"            : "<?php echo$code; ?>",
                "sex"            : "<?php echo$sex; ?>"
            },

            // 通信が成功した時
            success: function(data) {
                $.each(data, function(key, value)
                {
                    $(".all_show_result_<?php echo$value;?>").append(
                    "<div>" + value.sex + "</div>" + 
                    "<div>" + value.messages + "</div>");
                });
            },
        });

    return false;
});
});

</script>

//https://qiita.com/yukibe/items/7105563701a707ee7747を参考にしました。
◆teratail_ajax_show_all.php コメント表示実行phpファイル

<?php

// データベース接続
$host = 'localhost';
// データベース名
$dbname = 'XXX';
// ユーザー名
$dbuser = 'YYY';
// パスワード
$dbpass = 'ZZZ';

// データベース接続クラスPDOのインスタンス$dbhを作成する
$dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);

// データ取得用SQL
$sql = "SELECT sex, messages FROM `".$_POST['table']."` WHERE 1";

// SQLをセット
$stmt = $dbh->prepare($sql);
// SQLを実行
$stmt->execute();

// あらかじめ配列$productListを作成する
// 受け取ったデータを配列に代入する
// 最終的にhtmlへ渡される
$productList = array();

// fetchメソッドでSQLの結果を取得
// 定数をPDO::FETCH_ASSOC:に指定すると連想配列で結果を取得できる
// 取得したデータを$productListへ代入する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    $productList[] = array(
        'sex'       => $row['sex'],
        'messages'  => $row['messages']
    );
}

// ヘッダーを指定することによりjsonの動作を安定させる
header('Content-type: application/json');
// htmlへ渡す配列$productListをjsonに変換する
echo json_encode($productList);

//https://qiita.com/yukibe/items/7105563701a707ee7747を参考にしました。
◆teratail_ajax_add.php コメント追加実行phpファイル

<?php

// データベース接続
$host = 'localhost';
// データベース名
$dbname = 'XXX';
// ユーザー名
$dbuser = 'YYY';
// パスワード
$dbpass = 'ZZZ';


// データ追加用SQL
$dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);

$sql = "INSERT INTO `".$_POST['table']."` (writer_code, sex, messages) VALUES(?,?,?)";
$stmt=$dbh->prepare($sql);

$data[]=$_POST['code'];
$data[]=$_POST['sex'];
$data[]=$_POST['messages'];

$stmt->execute($data);




// 先ほど追加したデータを取得
// idはlastInsertId()で取得できる
$last_id = $dbh->lastInsertId();
// データ追加用SQL
$sql = "SELECT sex, messages FROM `".$_POST['table']."` WHERE id = ?";

// SQLをセット
$stmt = ($dbh->prepare($sql));
// SQLを実行
$stmt->execute(array($last_id));

// あらかじめ配列$productListを作成する
// 受け取ったデータを配列に代入する
// 最終的にhtmlへ渡される
$productList = array();

// fetchメソッドでSQLの結果を取得
// 定数をPDO::FETCH_ASSOC:に指定すると連想配列で結果を取得できる
// 取得したデータを$productListへ代入する
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
    $productList[] = array(
        'sex'           => $row['sex'],
        'messages'      => $row['messages']
    );
}


// ヘッダーを指定することによりjsonの動作を安定させる
header('Content-type: application/json');
// htmlへ渡す配列$productListをjsonに変換する
echo json_encode($productList);

//https://qiita.com/yukibe/items/7105563701a707ee7747を参考にしました。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • m6u

    2020/04/06 21:31

    ソースをまるっと貼り付けたってことは、回答者に再現試験をさせて直させるの? 丸投げ? どこまでテストできてるとか、ここまでは大丈夫とか、そういう絞り込みができていますか?

    キャンセル

  • m.ts10806

    2020/04/06 21:38 編集

    $value をどういうつもりで使ってるのか説明してください。

    キャンセル

  • m.s.2000

    2020/04/06 22:09

    >m6uさん
    レスありがとうございます。
    確認出来ていることは画像でも出しているように、table_3のコメントのみが表示と書き込みが出来ていることです。
    また、table_1と_2の2つに減らしても、table_2しか表示と書き込みはできませんでした。
    もちろんtable_1のみならば素直に表示と書き込みはできます。
    何かが足らずループ毎でajaxが働かないのではと思うので、何卒御指摘頂けましたら幸いです。

    キャンセル

  • m.s.2000

    2020/04/06 22:17

    >m.ts10806さん
    質問ありがとうございます。
    $valueを使っている理由としては、ajaxを動かすキッカケとなるclassに$valueをつけて固有のclassにすればajaxもループ毎にキチンと動いてくれるのではと考えたからです。
    事実$vlaueを付けない状態でもループ毎でajaxが効かなかったです。

    例) class="all_show_result" ⇒ class="all_show_result_'.$value.'"

    キャンセル

回答 2

checkベストアンサー

+1

回答と言えるレベルではないですが、ひとまず。

table_1やtable_2のあたりのwebブラウザ側で把握できるソースコード上で
意図した通りのhtmlやjsになっているかをまず確認してください。
ループを噛まして3つ表示させているけど、
ちゃんと適切に必要なパラメータが変化して出力されているかを確認します。

次に、
ajax送信周りがsuccessしか定義されていないのも気になります。
他の状態を捉えることができないため、
デバッグのためにも失敗したときなどalert()表示できるようにしたほうが
状況を把握しやすくなります。

それと、
SQL文で$_POST変数を直に文字列連結して作っているのは、
なんのためのプリペアドステートメントなのかってゆー話になります。
せめて、
テーブル名を直接やり取りせず別途1や2や3などとして
if()で1だったらtable_1のSQL文を実行、
みたいにしたほうが安全。

ajaxの応答用の処理であれば、
デバッグログをオリジナルで出力するような関数をこしらえて、
デバッグ中は今どこの処理を通ったかを逐一出力させれば、
if()の分岐のどこを通ったか把握できます。
やるべき。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/04/11 05:23

    御指摘、アドバイスありがとうございます。
    自分なりにパラメーターを確認してみましたが間違いは発見できませんでした。

    色々と調べていく中でAjaxのレスポンスを待たずしてループが先に回ってしまうことが原因なのかと仮定していますが、具体的に落とし込めていないので、頂いたアドバイスも含めさらに時間をかけて進めたいと思います。

    キャンセル

+1

ajaxを利用するならapiを用意するのですよね?
apiに送る→登録→呼び出し→受け取り→書き換え
の流れでやります。
ループの下りがなにをしたいかわかりません

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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