前提・実現したいこと
jQueryを使って、ボタンを押すと追加で表示される仕組みを作りたいです。サーバーサイドはPHP(Laravel)を使用しています。
投稿(Post)に対して、複数のコメント(Comment)があります。
Postをforeachで回して投稿一覧を表示させます。
投稿一覧ページで、各々の投稿の下に紐づくコメントを表示します。
コメントはデフォルトで3件だけ表示し「さらに表示」ボタンを押すと追加で新たな3件が表示される仕組みです。全件表示したら「戻す」ボタンを表示し、押すとデフォルト状態に戻します。再び「さらに表示」を押すと、全件表示されます。
発生している問題
ループ回数に応じてコメント欄のidを変え、ループするごとにjQuery側を動作させたいのですが、うまくいきません。恐らくjQueryが読み込まれるのは一度だけなので、ループごとに処理を繰り返すことができない?のかと思います。
とりあえずjQuery側で var iteration=1; (Postのループ回数が1) としました。
最初の投稿のコメントのみ期待通りに動作します。
該当のソースコード
PHP
1@foreach($posts as $post) //投稿をforeachで回す 2 3 <div id="comments_{{ $loop->iteration }}"> //ループ回数に応じてidを変える 4 @foreach($post->comments as $comment) //コメントをforeachで回す 5 <div id="list">{{ $comment->message }}</div> 6 @endforeach 7 8 @if($post->comments->count() > 3) //コメントが4件以上あったら 9 <div id="more_btn">さらに表示</div> 10 <div id="close_btn">戻す</div> 11 @endif 12 </div> 13 14@endforeach
JavaScript
1//とりあえず1回目のループという前提 2var iteration = 1; 3//コメント数を取得 4var comments_count = $('#comments_' +iteration+ ' div#list').length; 5 6$('#comments_'+iteration).each(function(){ 7 8 //現在表示中のコメント数 9 var display_num = 3; 10 11 $(this).find('#more_btn').show(); 12 $(this).find('#close_btn').hide(); 13 14 //2より大きいインデックスのlistを隠す = 3件表示 15 $(this).find("div#list:gt(2)").hide(); 16 17 $('#more_btn').click(function(){ 18 display_num +=3; 19 $(this).parent().find("div#list:lt("+display_num+")").slideDown(); 20 //コメント数より表示数が多ければ 21 if(comments_count <= display_num){ 22 $('#more_btn').hide(); 23 $('#close_btn').show(); 24 25 $('#close_btn').click(function(){ 26 //インデックス番号3以上は隠す 27 $(this).parent().find("div#list:gt(2)").slideUp(); 28 $(this).hide(); 29 $('#more_btn').show(); 30 }); 31 } 32 }); 33});
試したこと
投稿をforeachした回数だけ、for文でjQueryの処理を回しました。
現在のループ回数を保持する配列を作り
PHP
1//@foreach($posts as $post)の内側 2 $iterations[] = $loop->iteration; 3 4//@foreach($posts as $post)の外側 5 $iterations = json_encode($iterations);
コメントのリストidも、ループ回数に応じて変わるようにしました。
PHP
1@foreach($post->comments as $comment) 2 <div id="list_{{ $loop->iteration }}">{{ $comment->message }}</div> 3@endforeach
ループ回数を保持する配列をjQueryに渡して、その回数だけfor文で回しました。
JavaScript
1let iterations = <?php echo $iterations; ?>; 2 3for(var i=0; i<iterations.length; i++){ 4 //この中に上と同じjQueryのコードを記述 5 //iteration → iterations[i] とする 6 //list → list_iterations[i] とする 7}
これで試しましたが、コメントがデフォルトで全件表示されてしまいます。
今回のように、どの投稿のコメントなのかをjQueryが判別し、投稿のループ内で逐一jQueryを実行したい場合、どうすればよいですか。
また別の方法で実現可能でしたら教えていただきたいです。
わかる方がいらっしゃいましたら、お教えください。よろしくお願いします。
追記
「該当のソースコード」を動かした場合のHTML
HTML
1<!--1~7までの数字をコメントした投稿--> 2<div id="comments_1"> 3 <div id="list">1</div> 4 <div id="list">2</div> 5 <div id="list">3</div> 6 <div id="list">4</div> 7 <div id="list">5</div> 8 <div id="list">6</div> 9 <div id="list">7</div> 10 <div id="more_btn">さらに表示</div> 11 <div id="close_btn">戻す</div> 12</div> 13 14<!--A, B, C とコメントした投稿--> 15<div id="comments_2"> 16 <div id="list">A</div> 17 <div id="list">B</div> 18 <div id="list">C</div> 19 <div id="more_btn">さらに表示</div> 20 <div id="close_btn">戻す</div> 21</div>
「試したこと」のコードを動かした場合
※「コメントのリストidも、ループ回数に応じて変わるようにした」と書きましたが、コードを間違えていました。$loop->parent->iteration とすれば Commentのループ回数ではなく、Postのループ回数にアクセスできますね。
PHP
1@foreach($post->comments as $comment) 2 <div id="list_{{ $loop->parent->iteration }}">{{ $comment->message }}</div> 3@endforeach
出力結果
HTML
1<!--1~7までの数字をコメントした投稿--> 2<div id="comments_1"> 3 <div id="list_1">1</div> 4 <div id="list_1">2</div> 5 <div id="list_1">3</div> 6 <div id="list_1">4</div> 7 <div id="list_1">5</div> 8 <div id="list_1">6</div> 9 <div id="list_1">7</div> 10 <div id="more_btn">さらに表示</div> 11 <div id="close_btn">戻す</div> 12</div> 13 14<!--A, B, C とコメントした投稿--> 15<div id="comments_2"> 16 <div id="list_2">A</div> 17 <div id="list_2">B</div> 18 <div id="list_2">C</div> 19 <div id="more_btn">さらに表示</div> 20 <div id="close_btn">戻す</div> 21</div> 22
回答1件
あなたの回答
tips
プレビュー