過去にASP.NET MVCの部分ビューとJavaScriptの実行に関して質問されていた方がいらっしゃったので、私からも質問させていただきます。
現在MVCを使ったポータルサイトの開発で、サイトにログインやその他の操作を行ったときのアクセスログをデータベースに残しており、そのログデータを閲覧するページを作成しております。
初期表示では以下のように、先頭からいくつかのログデータだけを表示させます。
日時 | ユーザー名 | 内容 |
---|---|---|
19/12/10 09:00 | ユーザーA | ログイン |
19/12/10 09:30 | ユーザーA | ユーザー追加 |
19/12/10 09:32 | ユーザーB | ログイン |
1 Next
下にある「1」や「Next」は該当のページを開くためのリンクで、例えば「Next」をクリックすることで次のレコードからまたいくつかのデータが表示されます。
日時 | ユーザー名 | 内容 |
---|---|---|
19/12/10 09:54 | ユーザーA | ログアウト |
19/12/10 10:08 | ユーザーB | ログアウト |
19/12/10 10:11 | ユーザーC | ログイン |
PREV 1 2 Next
太字になっているところは現在のページを表し、それ以外が該当のページに飛ぶためのリンクになっています。
今回困っているのは、このリンクを用いて該当するデータを表示させる処理が上手くいっていないことです。
###ログページの概要
ビュースクリプトLog.cshtml:今回のログデータを表示させるページ。ログの期間やログ内容などの条件を指定する検索フォームがある。またsection scritpsを用いてコントローラーのログ検索アクションを呼び出す関数をJavaScriptで記述。
cshtml
1<table align="center"> 2 <tr> 3 <th>期間</th> 4 <td> 5 <input type="date" id="startdate" name="startdate" /> ~ <input type="date" id="enddate" name="endate" /> 6 </td> 7 </tr> 8 <tr> 9 <th>その他条件</th> 10 <td> 11 <label><input type="checkbox" name="chk1" value="login" /> ログインログを検索</label> 12 <label><input type="checkbox" name="chk1" value="userinfo" /> ユーザー情報ログを検索</label> 13 </td> 14 </tr> 15 <tr> 16 <td colspan="2"> 17 <input type="submit" value="検索" onclick="getlog(1);" /> 18 </td> 19 </tr> 20</table> 21<div id="logtable"></div> 22 23@section scripts{ 24 <script> 25 function getlog(pno) { 26 var search = []; 27 var chk1 = document.getElementsByName('chk1'); 28 for (let i = 0; i < chk1.length; i++) { 29 if (chk1[i].checked) { 30 search.push(chk1[i].value); 31 } 32 } 33 34 var sdate = document.getElementById('startdate').value; 35 var edate = document.getElementById('enddate').value; 36 37 $.ajax({ 38 url: "/Log/GetLog", 39 type: 'POST', 40 data: { 'StartDate': sdate, 'EndDate': edate, 'Search': search, 'Page': pno }, 41 datatype: 'html', 42 async: true 43 }).done(function (data) { 44 $('#logtable').html(data); // GetLogから返送された部分ビューのHTMLデータを差し込み 45 }); 46 } 47 </script> 48}
部分ビュー_Log.cshtml:実際のログデータの表示部分を担当。
cshtml
1@model IEnumerable<Project.Models.LogData> 2<table align="center" border="1"> 3 <tr> 4 <th>日時</th><th>ユーザー名</th><th>内容</th> 5 </tr> 6 @foreach (var item in Model) { 7 <tr> 8 <td>@Html.DisplayFor(modelItem => item.Date)</td> 9 <td>@Html.DisplayFor(modelItem => item.UserName)</td> 10 <td>@Html.DisplayFor(modelItem => item.Log)</td> 11 </tr> 12 } 13</table>
コントローラーLogController.cs:アクションGetlogはajax経由で呼び出され、ページ数に応じデータベースから取得したログデータを部分ビューに組み込んで返送します。
C#
1public ActionResult GetLog(DateTime StartDate, DateTime EndDate, string[] Search, int Page) 2{ 3 var loglist = (from a in db.AccessLogs 4 where a.Date >= StartDate && a.Date <= EndDate && Search.contains(a.Log) // 期間や条件によるデータの絞り込み 5 orderby a.Date ascending select a).Skip((Page - 1) * 3).Take(3).ToList(); 6 7 ViewBag.Flg == true; 8 return PartialView("_Log", loglist); 9}
###これまでに試したこと
●_Log.cshtmlのテーブル内にリンク用のカラムを追加し、そこからJavaScriptを呼び出す
cshtml
1@model IEnumerable<Project.Models.LogData> 2<table align="center" border="1"> 3 // 省略 4 <tr> 5 <tr colspan="3"> // 実際には自作ビューヘルパーを呼び出して現在のページ数に応じここに表示させるリンクを変えている 6 <a href="#" onclick="getlog(1);">1</a> 7 <a href="#" onclick="getlog(2);">NEXT</a> 8 </tr> 9 </tr> 10</table>
リンク自体はちゃんと表示されましたが、getlog(pno)を呼び出すリンクが_Log.cshtml、getlog(pno)の記述がLog.cshtmlと分かれているせいかリンクによるgetlog(pno)の呼び出しが上手く利きませんでした。
●先程のリンクをLog.cshtmlに記述し、JavaScriptの呼び出しが利くようにする
cshtml
1// 省略 2<div id="logtable"></div> 3@if ((bool)ViewBag.Flg == true) // アクションメソッドの中でViewBag.Flgを設定 4{ 5 <div> // 実際には自作ビューヘルパーを呼び出して現在のページ数に応じここに表示させるリンクを変えている 6 <a href="#" onclick="getlog(1);">1</a> 7 <a href="#" onclick="getlog(2);">NEXT</a> 8 </div> 9} 10// 省略
リンクがそもそも表示されませんでした。あくまでも自分の推測ですが、アクションメソッドが<div id="logtable"></div>
の部分だけを更新して、Log.cshtmlそのものを更新していないからだと思われます。
###質問
以上のように検索フォームは本体のビュー、検索結果のログデータ表示には部分ビューを使用している状態で、レコード遷移用のリンクをどこかに表示し、押されたリンクに応じて該当するレコードを検索し再度部分ビューにデータを表示させるにはどのような記述を行えばいいでしょうか?リンクには特にこだわっていないので、例えばリンクを全てボタンに変えてしまっても大丈夫です。
ご教授のほどよろしくお願いいたします。
####追記:開発環境
開発ツール:Visual Studio 2017
フレームワーク:.NET Framwork 4.6.1
また「部分ビューでのonclickイベントによるJavaScriptの実行」とタイトルにはありますが、他の手段で実現が可能であればそれでも構いません。
回答1件
あなたの回答
tips
プレビュー