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

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

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

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

Q&A

解決済

1回答

2761閲覧

jQueryでforeach内に「さらに表示する」機能をつけたい

miyu94

総合スコア18

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

0グッド

0クリップ

投稿2019/01/19 09:25

編集2019/01/19 11:21

前提・実現したいこと

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

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

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

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

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

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

kei344

2019/01/19 10:17

出力されたHTML(ブラウザで「ページのソースを表示」)を質問文に追記ください。
miyu94

2019/01/19 12:03

追記に出力されたHTMLを記載しました。ご覧いただけると幸いです。
guest

回答1

0

ベストアンサー

まず、HTMLは同一idが使えません。ページ内のidは一意である必要があります。
提示の内容ならclassでよいと思います。
次に、イベントの中でイベントを定義しない。クリックするたび関数が追加登録され、何度も同じコードが走ることになります。

HTML

1<div id="comments_1" class="comments"> 2 <div class="list">1</div> 3 <div class="list">2</div> 4 <div class="list">3</div> 5 <div class="list">4</div> 6 <div class="list">5</div> 7 <div class="list">6</div> 8 <div class="list">7</div> 9 <div class="more_btn">さらに表示</div> 10 <div class="close_btn">戻す</div> 11</div> 12<div id="comments_2" class="comments"> 13 <div class="list">A</div> 14 <div class="list">B</div> 15 <div class="list">C</div> 16 <div class="more_btn">さらに表示</div> 17 <div class="close_btn">戻す</div> 18</div>

JavaScript

1$( '.comments' ).each( function() { 2 var $_t = $( this ); 3 var comments_count = $_t.find( '.list' ).length; 4 5 //現在表示中のコメント数 6 var display_num = 3; 7 8 $_t.find( '.more_btn' ).show(); 9 $_t.find( '.close_btn' ).hide(); 10 11 //2より大きいインデックスのlistを隠す = 3件表示 12 $_t.find( '.list:gt(2)' ).hide(); 13 14 $_t.find( '.more_btn' ).on( 'click', function() { 15 display_num += 3; 16 $_t.find( '.list:lt(' + display_num + ')' ).slideDown(); 17 //コメント数より表示数が多ければ 18 if ( comments_count <= display_num ) { 19 $_t.find( '.more_btn' ).hide(); 20 $_t.find( '.close_btn' ).show(); 21 22 } 23 } ); 24 $_t.find( '.close_btn' ).on( 'click', function() { 25 //インデックス番号3以上は隠す 26 $_t.find( '.list:gt(2)' ).slideUp(); 27 $( this ).hide(); 28 $_t.find( '.more_btn' ).show(); 29 } ); 30} ); 31```**動くサンプル:**[https://jsfiddle.net/y481earu/](https://jsfiddle.net/y481earu/)

投稿2019/01/19 14:33

kei344

総合スコア69407

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

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

miyu94

2019/01/19 20:33

できました!親切にサンプルまであげていただいてありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問