はじめに
前回の記事「jQueryでWeb Formsアプリケーションのフィルタリングユーザーインターフェースを作成する(前編)」では、ASP.NET Web FormsアプリケーションでjQueryを使って折りたたみ式のフィルタリングユーザーインターフェースを作成する方法を説明しました。ユーザーのブラウザにページがロードされるとき、フィルタリングインターフェースは折りたたまれた状態になっています。フィルタリングインターフェースのタイトルをクリックすると、インターフェースを折りたたみ状態と展開状態の間で切り替えることができます。展開状態では、DropDownList、TextBox、CheckBoxなどのフィルタリングコントロールを使用して、フィルタリングインターフェースの下のレポートに表示されている結果の絞り込みができます。
前編で作成したフィルタリングインターフェースも動作することはしますが、インターフェースの折りたたみ/展開の状態を記憶しません。そのため、展開状態であっても、ポストバックの後や、ユーザーがいったんページを離れて再び戻ってきた場合には、フィルタリングインターフェースは折りたたみ状態に戻ってしまいます。幸い、ちょっとしたAJAXの機能を利用すれば、ユーザーセッションの間じゅう、フィルタリングユーザーインターフェースの折りたたみ/展開状態を記憶できます。本稿では、この機能を追加する方法を説明します。
前編をまだ読んでいない読者は、後編にとりかかる前にぜひ前編をお読みください。
JavaScriptをプログラムで挿入する
前編のサンプルでは、JavaScriptコードをASP.NETページのマークアップ部分に直接記述していました(Demo.aspx)。
<script type="text/javascript"> $(document).ready(function() { $('#filterUI').hide(); $('#filterUItitle').click(function() { $('#filterUI').slideToggle(400); $('#filterUItitle').toggleClass('expandIcon'); $('#filterUItitle').toggleClass('collapseIcon'); }); }); </script>
このスクリプトは、Webページがブラウザにロードされるたびに、それがページへの初めての訪問であるかポストバックであるかに関係なく実行されます。document
のready
イベントハンドラの最初の行($('#filterUI').hide()
)では、フィルタリングユーザーインターフェースを非表示にしています。そのため、ページのロード時にもポストバック後にもインターフェースが折りたたまれます。
ページロード間でフィルタリングユーザーインターフェースの折りたたみ/展開状態を維持するには、次の2点を行う必要があります。
- 何らかの方法により、ユーザーごとの折りたたみ/展開状態を記憶する
- 上記1に基づいて、ページのロード時にフィルタリングユーザーインターフェースの表示/非表示を設定する
1を実装する方法はひとまず置いておき、先に2に着目します。フィルタリングインターフェースの表示/非表示を設定するには、適切なJavaScriptをプログラムで挿入する必要があります。フィルタリングインターフェースを非表示にする(折りたたむ)ときは$('#filterUI').hide()
、表示する(展開する)ときは$('#filterUI').show()
を挿入しなければなりません。
ASP.NETのClientScriptManagerクラスを使用すると、プログラムによってJavaScriptコードをページに挿入できます。このクラスにはPage.ClientScript
オブジェクトを介してアクセスでき、このクラスのRegisterClientScriptBlockメソッドやRegisterStartupScriptメソッドを使用して、適切なスクリプトを含むdocument
のready
イベントハンドラを挿入できます(本稿では、サーバーサイドのコードからクライアントサイドのスクリプトをASP.NETページに追加する際の問題については取り上げません。その詳細については、Xun Ding氏の記事「JavaScript With ASP.NET 2.0 Pages」を参照ください)。
本稿のダウンロード可能なサンプルプロジェクトには、BasePage
というカスタムのベースページクラスが含まれています。カスタムのベースページクラスを作成し、これをすべてのページの基本として使うようにすると、共通の機能をすべてのASP.NETページに反映させるときに便利です。ベースページクラスの使用方法と利点については、記事「Using a Custom Base Class for your ASP.NET Pages' Code-Behind Classes」を参照ください。
本稿のサンプルのBasePage
クラスには、jQUeryDocumentReadyStatements
という文字列リストのプロパティがあります。BasePage
クラスでは、OnPreRender
メソッドもオーバーライドしています。このメソッドは、ページのライフサイクルにおいて、クライアントサイドのスクリプトをASP.NETページに追加するのに最もふさわしいタイミングです。オーバーライドしたメソッドでは、jQUeryDocumentReadyStatements
リストの中に文字列があるかどうかをチェックし、文字列がある場合は、指定されたステートメントを含むdocument
のready
イベントハンドラのスクリプトブロックを挿入します。オーバーライド後のOnPreRender
を次に示します。
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) 'Add jQuery document ready function, if needed If jQueryDocumentReadyStatements.Count > 0 Then Dim jQueryScript As String = "$(document).ready(function() {" For Each stmt As String In jQueryDocumentReadyStatements jQueryScript &= String.Concat(vbCrLf, stmt, vbCrLf) Next jQueryScript &= "});" ClientScript.RegisterClientScriptBlock(Me.GetType, "jquery_DocumentReadyCode", jQueryScript, True) End If MyBase.OnPreRender(e) End Sub
サーバーサイドのコードからプログラムによってdocument
のready
イベントハンドラを作成するには、次の作業が必要です。
- (
System.Web.UI.Page
ではなく)BasePage
からASP.NETページを派生させる document
のready
イベントハンドラに入れるJavaScriptの各ステートメントを、次のようにjQUeryDocumentReadyStatements
コレクションに追加する
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUI').hide();")
または、
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUI').show();")
これにより、指定されたJavaScriptステートメントを含むdocument ready
イベントハンドラがページに挿入されます。