フィルタリングユーザーインターフェースを折りたたむか展開するかを判断する
本稿のダウンロード可能なサンプルプロジェクトには、2つのサンプルページが含まれています。Demo.aspxは、ページロード時(ポストバックを含む)に必ず折りたたまれる「やや問題あり」のフィルタリングインターフェースです。DemoSmart.aspxは、ユーザーのセッション中は折りたたみ/展開状態を記憶するフィルタリングインターフェースです。コードビハインドクラスであるDemoSmart.aspxの中のShowHideFilterUIメソッドは、ページ訪問のたびにPage_Loadイベントハンドラから呼び出され、適切なJavaScriptを挿入します。次のコードに示すように、フィルタリングユーザーインターフェースを折りたたむか展開するかは、ShowFilterUIというセッション変数を参照することで判断します。セッション変数ShowFilterUIが設定されていないか、Falseが設定されている場合には、フィルタリングユーザーインターフェースを隠すスクリプトを挿入し、CSSクラスをexpandIcon(フィルタのタイトルに展開アイコンを表示)に設定します。セッション変数ShowFilterUIにTrueが設定されている場合には、フィルタリングユーザーインターフェースを表示するスクリプトを挿入し、CSSクラスをcollapseIcon(折りたたみアイコンを表示)に設定します。
Private Sub ShowHideFilterUI()
If Session("ShowFilterUI") Is Nothing OrElse Session("ShowFilterUI") = False Then
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUI').hide();")
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUItitle').addClass('expandIcon');")
Else
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUI').show();")
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUItitle').addClass('collapseIcon');")
End If
Dim toggleScript As String = _
"$('#filterUItitle').click(function() { " & vbCrLf & _
" $('#filterUI').slideToggle(400);" & vbCrLf & _
" $('#filterUItitle').toggleClass('expandIcon');" & vbCrLf & _
" $('#filterUItitle').toggleClass('collapseIcon');"
" ... More jQuery code coming here soon! ...
"});"
MyBase.jQueryDocumentReadyStatements.Add(toggleScript)
End Sub
Demo.aspxの中のfilterUItitle <div>では、<div id="filterUItitle" class="expandIcon">...</div>というように、class属性にexpandIconが明示的に設定されています。そのため、デフォルトでは必ず折りたたまれた状態になります。一方DemoSmart.aspxでは、これと同じ<div>要素にclass属性が明示的に設定されていません。class属性はShowHideFilterUIメソッドから挿入されるJavaScriptによって設定されます。
ShowHideFilterUIメソッドは、フィルタリングインターフェースを表示/非表示にするJavaScriptに加えて、filterUItitle <div>のクライアントサイドのclickイベント用のスクリプトも追加します。このためのコードは前編で使用したものとまったく同じです。後ほど、このclickイベントハンドラにもう1行追加したいと思います。
フィルタリングユーザーインターフェースの折りたたみ/展開時にセッション変数を切り替える
ShowHideFilterUIは、セッション変数ShowFilterUIの値によって、フィルタリングユーザーインターフェースを折りたたみ/展開状態のいずれかで表示します(このセッション変数が設定されていない場合は、フィルタリングインターフェースは折りたたまれます)。折りたたみ/展開状態を記憶するには、ユーザーがフィルタリングインターフェースを展開したり折りたたんだりしたときに、このセッション変数を切り替える必要があります。このセッション変数を切り替えるには、フィルタリングユーザーインターフェースの折りたたみ/展開時に、ブラウザにサーバをコールバックさせる必要があります。
jQueryを使用すると、非同期のクライアントサイドのHTTPリクエストを1行のJavaScriptで発行できます。しかしこのスクリプトを見る前にまず、セッション変数の切り替えを行うASP.NETの「ページ」を作成しましょう。呼び出されたときにセッション変数ShowFilterUIを切り替える、ASP.NETの「ページ」が必要です。ここでページという語をかぎかっこで囲んだのは、普通のページでも正しく動作しますが、HTTPハンドラを使用するほうが簡単だからです。Servicesフォルダに、ToggleFilterState.ashxという名前の汎用HTTPハンドラを作成しました。
HTTPハンドラの処理を行うのは、その中にあるProcessRequestメソッドです。このメソッドのコードは非常に簡単です。セッション変数ShowFilterUIがまだ設定されていないかFalseである場合は、それにTrueを設定し、それ以外の場合はFalseを設定します。このメソッドのコードは次のようになります。
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
'Toggle the Session variable ShowFilterUI
If context.Session("ShowFilterUI") Is Nothing OrElse context.Session("ShowFilterUI") = False Then
context.Session("ShowFilterUI") = True
Else
context.Session("ShowFilterUI") = False
End If
End Sub
最後の作業は、ユーザーがフィルタリングユーザーインターフェースを展開したり折りたたんだりしたときに、ブラウザからToggleFilterState.ashxへとHTTPリクエストを送信することです。1行のJavaScriptをクライアントサイドのclickイベントハンドラに追加します。先ほど説明したShowHideFilterUIメソッドに戻り、jQueryの$.get(url)関数を使用するJavaScriptステートメントを追加する必要があります。
Private Sub ShowHideFilterUI()
If Session("ShowFilterUI") Is Nothing OrElse Session("ShowFilterUI") = False Then
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUI').hide();")
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUItitle').addClass('expandIcon');")
Else
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUI').show();")
MyBase.jQueryDocumentReadyStatements.Add("$('#filterUItitle').addClass('collapseIcon');")
End If
Dim toggleScript As String = _
"$('#filterUItitle').click(function() { " & vbCrLf & _
" $('#filterUI').slideToggle(400);" & vbCrLf & _
" $('#filterUItitle').toggleClass('expandIcon');" & vbCrLf & _
" $('#filterUItitle').toggleClass('collapseIcon');" & vbCrLf & _
vbCrLf & _
String.Format("$.get('{0}');", Page.ResolveUrl("~/Services/ToggleFilterState.ashx")) & vbCrLf & _
"});"
MyBase.jQueryDocumentReadyStatements.Add(toggleScript)
End Sub
上のJavaScriptにより、フィルタリングユーザーインターフェースの展開/折りたたみ時に必ず、HTTPハンドラToggleFilterState.ashxへとHTTPリクエストが送信され、ToggleFilterState.ashxがセッション変数ShowFilterUIを切り替えます。
コードが完成したところで、レポートページを訪問するユーザーが体験する、典型的なイベントの流れを見てみましょう。
- ユーザーはブラウザを開き、レポートページにたどり着きます。そのサイトを開いたばかりなので、セッション変数
ShowFilterUIは存在しません。そのため、フィルタリングユーザーインターフェースはデフォルト設定(折りたたみ状態)で表示されます。 - ユーザーがフィルタリングユーザーインターフェースを展開すると、HTTPリクエストがToggleFilterState.ashxに送信されます。HTTPハンドラToggleFilterState.ashxは、セッション変数
ShowFilterUIを作成し、Trueを設定します。 - ユーザーは、フィルタリングコントロールにフィルタリング条件を入力し、[Filter]ボタンをクリックします。これによりポストバックが生じます。
- ポストバックが生じると、ページはセッション変数
ShowFilterUIがTrueであることを確認し、フィルタリングユーザーインターフェースを展開します。ユーザーには、フィルター結果とともに展開されたフィルタリングユーザーインターフェースが表示されます。 - ユーザーはレポートページを離れ、サイト上の他のページをいくつか閲覧します。
- 数分後、ユーザーはフィルタリングページに戻ります。ページはセッション変数
ShowFilterUIがTrueであることを確認し、フィルタリングユーザーインターフェースを展開します。 - ユーザーがフィルタリングインターフェースを折りたたむと、HTTPリクエストがToggleFilterState.ashxに送信されます。HTTPハンドラToggleFilterState.ashxは、セッション変数
ShowFilterUIにFalseを設定します。 - ユーザーはレポートページを離れ、サイト上の他のページをいくつか閲覧します。
- 数分後、ユーザーはフィルタリングページに戻ります。ページはセッション変数
ShowFilterUIがFalseであることを確認し、フィルタリングユーザーインターフェースを折りたたみます。
前編で作成したコードでは、フィルタリングインターフェースはステップ4と6でデフォルトの折りたたみ状態に戻ってしまっていました。しかし今回の変更により、フィルタリングインターフェースはユーザーのセッションを通して、最後の折りたたみ/展開状態を維持するようになります。
まとめ
jQueryは、無償で提供されるオープンソースの軽量かつ強力なJavaScriptライブラリであり、DOMの操作、アニメーションなどの効果の適用、クライアントサイドのAJAX機能の実装を非常に簡単にします。前編では、ASP.NET Web FormsアプリケーションでjQueryを使って折りたたみ式のフィルタリングユーザーインターフェースを作成する方法を説明しました。本稿では、その機能を拡張し、セッション変数とちょっとしたAJAXを使用して、ユーザーセッション中はフィルタリングインターフェースの折りたたみ/展開の状態が記憶されるようにする方法を説明しました。
では、ハッピープログラミング!
