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

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

新規登録して質問してみよう
ただいま回答率
85.35%
jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

438閲覧

非同期処理でコメントを1件投稿すると口コミに対するコメントを1件表示させたい jquery ajax

amakuma

総合スコア13

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2020/05/08 07:20

編集2020/05/08 15:09

実現したいこと

現状1ページに口コミは2件あります。
例えば1件目の口コミがone_review、2件目の口コミがのtwo_reviewとすると
one_reviewに対してコメントを投稿しても、one_reviewとtwo_review両方にコメントが表示されてしまいます。
リロード(更新)すると正常に表示されている為、DBにajaxから送信したデータは入っていると思われます。
ajax(非同期処理)を利用して、口コミに対するコメントをそれぞれ画面遷移せずに表示させたいです。

DBには口コミテーブルと口コミに対するコメントテーブルがあり、ajaxを使わない(画面遷移する)状態であればこの機能は実装できております。

jquery(ajax)を使っています。

現状とソースコード

・口コミの投稿フォームもあり、投稿する度に口コミも増え続けます。
・ページネーションしており、1ページには2件ずつ口コミが表示される。
・その口コミに対するコメントをコメントフォームから投稿すると口コミの下部にコメントが表示される。
・1ページに口コミの投稿フォーム、口コミの表示、コメントの投稿フォーム、コメントの表示があります。

コメント投稿ボタンがあるHTML

<form onsubmit="return false;"> <input type="text" name="name"> <textarea name="comment"></textarea> <button class="koment">投稿する</button> </form>

口コミに対するコメントを表示させたいHTML

<div class="replyList"> <ul class="komlist"> <php foreach($comment as $c) { ?> <li> <p><?= $c['name'] ?></p> <p><?= $c['comment'] ?></p> </li> <?php } ?> </ul> </div>

ajax(jquery)のソースコード

$(document).on('click','.koment',function(){ $.ajax({ url:'/comment/comment', type:'POST', data:{ name: $(this).closest('#kom').find('#komname').val(), comment: $(this).closest('#kom').find('#komtext').val(), review_id: $(this).closest('#kom').find('#review_id').val(), }, dataType: 'json' }) // Ajax通信が成功したら発動 .done(function(data, dataType){ $('.komlist').prepend( '<li>'+ '<p>'+ data['name'] +'</p>'+ '<p>'+ data['comment']+ '</p>'+ '</li>' ) }) });

で新しいコメント順でコメントを表示させています。
しかし、これだと1件コメントを投稿すると、1ページに2件口コミがあるので、そのどちらにもコメントが表示されてしまいます。

試したこと

現状は('.komlist')でprependするセレクタを指定しているのですが、class="komlist"には2件ずつ口コミがあるため、そのどちらにも投稿したコメントが1件ずつ表示されてると考えました。

コメント投稿した箇所にだけコメントを表示させたいため、クリックした要素のthisを使って

$(this).closest('.replyList').find('.komlist').prepend()

$(this).parents().find('.komlist').prepend()

を試してみましたが、こうすると動かなくなります。更新すると正常表示になります。

this以下の書き方が違うと思いますが、どこが違うのかわからないでいます。

=====[追記]===================================
.komentは投稿ボタン<button>に付与されているclass="koment"になります。
.komlistはコメントを表示する際の<ul>に付与されているclass="komlist"になります。
.komentと.komilistはhtml構造上では、親が同じの兄弟要素です。

<li> <div class="replyList box"> <p class="replyTitle">コメント表示</p> <ul class="komlist"> <li class="r-list"> <div> <p><?= $c['name'] ?></p> <div> <?= $c['comment'] ?> </div> </div> </li> </ul> </div> <div class="replyForm"> <p class="replyFormTitle">コメント投稿</p> <form onsubmit="return false;"> <input type="text" id="komname" name="name"> <textarea name="comment" id="komtext"></textarea> <button class="koment">投稿する</button> </form> </div> </li>

複数ある場合は、どの様に複数なのか。例:仮に口コミが2つある場合。

<ul class="prepend"> //1つ目の口コミ <li> <div class="main">口コミ1</div> <div class="detail">Aさん コメント1</div> <div class="replyList box"> <p class="replyTitle">コメント表示</p> //1つ目の口コミに対するコメント1 <ul class="komlist"> <li class="r-list"> <div> <p><?= $c['name'] ?></p> <div> <?= $c['comment'] ?> </div> </div> </li> //1つ目の口コミに対するコメント2以降.. <li class="r-list"> <div> <p><?= $c['name'] ?></p> <div> <?= $c['comment'] ?> </div> </div> </li> //...と上記の様に<li>が増えていく感じです </ul> </div> <div class="replyForm"> <p class="replyFormTitle">コメント投稿</p> <form onsubmit="return false;"> <input type="text" id="komname" name="name"> <textarea name="comment" id="komtext"></textarea> <button class="koment">投稿する</button> </form> </div> </li> //2つ目の口コミ <li> <div class="main">口コミ2</div> <div class="detail">Bさん コメント2</div> <div class="replyList box"> <p class="replyTitle">コメント表示</p> //2つ目の口コミに対するコメント1 <ul class="komlist"> <li class="r-list"> <div> <p><?= $c['name'] ?></p> <div> <?= $c['comment'] ?> </div> </div> </li> //2つ目の口コミに対するコメント2以降 <li class="r-list"> <div> <p><?= $c['name'] ?></p> <div> <?= $c['comment'] ?> </div> </div> </li> </ul> </div> <div class="replyForm"> <p class="replyFormTitle">コメント投稿</p> <form onsubmit="return false;"> <input type="text" id="komname" name="name"> <textarea name="comment" id="komtext"></textarea> <button class="koment">投稿する</button> </form> </div> </li> //...口コミが増えていくたびに<ul class="prepend">以下の<li>要素が増えていきます。 </ul>

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2020/05/08 11:44

「this」はスコープによって変わるので、コードを省略せずに、「投稿ボタンを押す」から「done」まで提示してください。
amakuma

2020/05/08 12:15

ただいま掲載いたしました。 お手数おかけしますがご確認お願いいたします。
kei344

2020/05/08 14:56

「投稿ボタン<button>に付与されているclass="koment"になります」とありますが、提示のHTMLにはclass="koment"がありません。
guest

回答2

0

ベストアンサー

とりあえずこれで試してみてください。

js

1$(document).on('click','.koment',function(){ 2 var $_t = $( this ); // 変数に入れておく 3 $.ajax({ 4 url:'/comment/comment', 5 type:'POST', 6 data:{ // ここのthisは'.koment'なので置き換えてもどっちでもいい 7 name: $(this).closest('#kom').find('#komname').val(), 8 comment: $(this).closest('#kom').find('#komtext').val(), 9 review_id: $(this).closest('#kom').find('#review_id').val(), 10 }, 11 dataType: 'json' 12 }) 13 // Ajax通信が成功したら発動 14 .done(function(data, dataType){ 15 $_t.prepend( // ここのthisは'.koment'じゃないので変数に入れておいたものを使う 16 '<li>'+ 17 '<p>'+ data['name'] +'</p>'+ 18 '<p>'+ data['comment']+ '</p>'+ 19 '</li>' 20 ) 21 }) 22});

投稿2020/05/08 12:18

kei344

総合スコア69606

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amakuma

2020/05/08 12:39 編集

$(document).on('click','.koment',function(){ var $_t = $( this ); // 変数に入れておく $.ajax({ url:'/comment/comment', type:'POST', data:{ // ここのthisは'.koment'なので置き換えてもどっちでもいい name: $(this).closest('#kom').find('#komname').val(), comment: $(this).closest('#kom').find('#komtext').val(), review_id: $(this).closest('#kom').find('#review_id').val(), }, dataType: 'json' }) // Ajax通信が成功したら発動 .done(function(data, dataType){ $_t.prepend( // 1のパターン $_t.closest('.replyList').find('.komlist').prepend( //2のパターン '<li>'+ '<p>'+ data['name'] +'</p>'+ '<p>'+ data['comment']+ '</p>'+ '</li>' ) }) }); 1と2のパターンを試しましたができませんでした。 1のパターンでは、投稿ボタンの下に表示が現れました。(this)class="koment"のところですぐprependしてるからですかね。 2のパターンは動かなくなり、エラーも出ず、ページ更新すると反映されます。(DBの中身が表示されてる)
kei344

2020/05/08 13:45

.koment と .komlist の位置関係(HTML構文上の親子兄弟)および「複数ある場合はどのように複数か」が提示されていないので、何が問題になっているかがわかりません。
amakuma

2020/05/08 14:54

ありがとうございます。 質問にて、追記をいたしました。お手すきの際にご確認くだされば幸いです。
kei344

2020/05/08 15:01

修正依頼をかけていますが、ボタンについているのがidでなくclassだと仮定して、 $_t.closest('li').find('.komlist').prepend(/*略*/); です。
amakuma

2020/05/08 15:13

ありがとうございます!!! $_t.closest('li').find('.komlist').prepend()で正常に表示されましたー! なぜ、$_tで$(this)を変数に入れなければいけなかったのでしょうか?やってることが$(this)と同じだと考えたのですが。
kei344

2020/05/08 15:17

done(functionの中のthisは外側のthisと違うと思いますよ。(JavaScriptのthisはけっこう難解です)
amakuma

2020/05/08 15:31

そうなのですか。 あと、自分closestの使い方も間違ってました。 closestは開始要素から一番近い親要素を選択するものなのに、兄弟要素であるreplyListを選択してました。 この度は回答ありがとうございました。!!
guest

0

$('.komlist:first')

とか

$('button:eq(0)')

でprepend()しては?

投稿2020/05/08 09:06

yhasegawa55

総合スコア189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amakuma

2020/05/08 09:30

コメントありがとうございます。 自分の言葉足りず説明不足で申し訳ございません。 提供してくださったソースコードだと、2件目の口コミにコメントをしても1件目の口コミにコメントが表示されてしまいました。 1件目の口コミにだけコメントを表示させたいのではなく、1件目の口コミにコメントすると1件目に表示、 2件目の口コミにコメントすると2件目に表示とさせたいです。 口コミに対するコメントのフォームは、口コミの数だけあります。
mari.rinn

2020/05/08 10:22

>1件目の口コミにコメントすると1件目に表示、 2件目の口コミにコメントすると2件目に表示とさせたいです つまり、返信機能つき掲示板みたいなものですよね? その場合は、DBでグループ化してクチコミを親として、コメントはそのグループの子供という風にしないとダメなので、カラムを増やして紐づけさせないと、表示だけをどうこうしても思うようにはならないと思います。
amakuma

2020/05/08 11:19

回答ありがとうございます。 そうですね。返信機能つき掲示板の様なものです。 はい、DBでは、口コミテーブルと口コミに対するコメントテーブルがあって、画面遷移するのであれば機能自体はできている状態です。 こちらも情報を掲載しておらずすみません。 非同期処理で画面遷移せずにこの様なコメント機能を実装するのは厳しいのでしょうか。
mari.rinn

2020/05/08 12:11

すみません、基本的な質問なのですが、1つのクチコミに対して、コメントは複数つく場合もあるのですよね? もしそうなら、他の、つまり以前についてるコメントも表示し、なおかつ最新のコメントも表示しないといけないと思うのですが、そうなると最新のだけを非同期でっていうのはどうなんでしょうか?
amakuma

2020/05/08 12:20

はい。1つの口コミに対してコメント複数つく場合あります。 コメントの投稿ボタンを押して反映されるまでを非同期処理でできればと考えております。 もちろん以前のコメントの投稿もDBに保存されてるので表示するつもりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問