検索アプリケーション
以下では、前述した検索アプリケーションの問題にDojoの履歴機能を適用する方法を実例で示します。図1は、検索アプリケーションのディレクトリ構造を示しています。
ユーザーが検索をトリガするメインページ(searchMain.jsp、図2を参照)は、アプリケーションのルートフォルダに置かれています。「dojo」フォルダには、「dojo.js」などの標準Dojoファイルが含まれています。「script」フォルダには、検索アプリケーション用の特別なJavaScriptファイルとして、アプリケーション状態実装を定義する「HistoryTracker.js」と、body onload
ハンドラ関数や検索を開始する関数など、さまざまなJavaScriptユーティリティ関数を定義する「dojoUtility.js」が含まれています。
図2のフォームを表すHTMLの<form>
タグは次のように記述されています。
<form name="searchForm" action="#"> <input type="text" name="searchTextElement"></input> <input type="button" name="Search" value="Search" onclick="performSearch( this.form.searchTextElement.value);"></input> </form>
ここで、ボタンを表す<input>
タグのtype
属性に"submit"ではなく"button"を使用していることに注意してください。これは自動フォーム送信を避けるためです。今回のサンプルでは、非同期のバックグラウンドリクエストを送信して、検索結果を取得します。したがって、ボタンのonclick
イベントでperformSearch()
メソッドを呼び出し、このメソッドから検索操作をトリガします。
以下のperformSearch()
関数コードは独立した「dojoUtility.js」ファイルに入っています。
function performSearch(searchTxt, pageNumber) { var bindUrl = "/dojoapp/doSearch.jsp"; if(searchTxt) { bindUrl += "?searchTxt=" + searchTxt ; if(pageNumber) { bindUrl += "&pageNumber=" + pageNumber; } dojo.io.bind({ url: bindUrl, load: function(type, data, evt){ dojo.undo.browser.addToHistory( new HistoryTracker(data, searchTxt, pageNumber, "searchContent")); dojo.byId("searchContent").innerHTML = data; } }); } }
performSearch()
メソッドは、searchTxt
とpageNumber
という2つのパラメータをとります。前者はテキストボックスに入力された検索テキストを表し、後者は移動先となる検索ページを表します。performSearch()
は非同期のリクエストを「doSearch.jsp」に送り、「doSearch.jsp」は検索結果を取得します。検索結果のダミーを図3に示します。
以下は検索結果を生成するコードです(doSearch.js)。
You have searched for: <%= request.getParameter("searchTxt") %> <br/> Showing page number: <%= (request.getParameter( "pageNumber") == null) ? "1" : request.getParameter( "pageNumber") %> <br/> <a href="javascript:performSearch( '<%= request.getParameter("searchTxt") %>', '<%= (request.getParameter("pageNumber") == null) ? "2" : (Integer.parseInt(request.getParameter( "pageNumber") ) + 1) %>');">View next set of results</a>
これはページ番号と検索テキストのみを表示するダミーページです。このページには、次の検索結果セットを取得するためのアンカータグが含まれており、このタグのhref
属性の値としてjavascript:performSearch()
関数を指定しています。この関数はパラメータとして検索テキストと次のページ番号をとります。
performSearch()
関数はHistoryTracker
オブジェクトを使用します。アプリケーション状態変化の登録はdojo.undo.browser.addToHistory()
を呼び出すことによって行います。ただし、そのためにはアプリケーションの初期状態を登録しておく必要があります。通常、これはbody onload
イベントの中で行われます。
dojo.addOnLoad(handleBodyLoad);
handleBodyLoad()
関数の定義は次のようになっています。
function handleBodyLoad() { var state = new HistoryTracker(null, null, null, "searchContent"); dojo.undo.browser.setInitialState(state); handleUrlHash(); }
handleBodyLoad()
関数は、searchTxt
とpageNumber
の両方がnull値となる状態オブジェクトを作成します。その後、この状態オブジェクトをdojo.undo.browser.setInitialState()
に渡すことで、アプリケーションの初期状態を登録します。そして最後にhandleUrlHash()
を呼び出します。handleUrlHash()
はURLハッシュを解析し、ハッシュの値に応じてアプリケーションの状態を復元します。
function handleUrlHash() { var urlHash = location.hash.substring(1); var searchText, pageNumber; if(urlHash && urlHash != '') { var hashParams = urlHash.split(";"); for (i = 0; i < hashParams.length; i++) { var temp = hashParams[i].split("="); if(temp && temp.length > 0) { switch(temp[0]) { case 'searchTxt': searchText = temp[1]; break; case 'pageNumber': pageNumber = temp[1]; break; } } } } if(searchText) { if(pageNumber) { performSearch(searchText, pageNumber); } else { performSearch(searchText, 1); } } }
handleUrlHash()
メソッドはURLハッシュを解析して検索テキストとページ番号を取得し、解釈した検索テキストとページ番号を使ってperformSearch()
を呼び出します。前記のperformSearch()
メソッドには、検索を開始するという役目があります。このメソッドはパラメータとして受け取ったsearchText
とpageNmuber
を使用して「doSearch.jsp」を呼び出し、検索結果を表示します。
これで検索アプリケーションが完成しました。http://yourdomain/searchMain.jspというURLをブラウズすれば、検索ページを表示することができます。
メインフォームが表示されたところで検索テキスト(「What is Dojo」など)を入力すると、同じページに検索結果が表示されます(図4を参照)。
ページは変化しませんが、次のように、元のURLの末尾にURLハッシュが追加されていることがわかるでしょう。
http://localhost:8080/dojoapp/searchMain.jsp #searchTxt=What%20is%20Dojo;pageNumber=1
このURLハッシュには、searchTxtとpageNumberの値がセミコロンで区切られて含まれています。検索結果の「View next set of results」リンクをクリックすると、2番目の検索結果ページが表示されます。
ご覧のように、DojoはAJAXアプリケーションにブックマークおよび[戻る]ボタンと[進む]ボタンを考慮させることができます。サンプルアプリケーションで示したように、各ページに明確なURLハッシュを割り当てることにより、ブラウザの履歴が更新されます。このテクニックを使用すると[戻る]ボタンと[進む]ボタンが正しく機能するので、ユーザーは任意のページに簡単にブックマークを付けることができます。本稿のダウンロードサンプルにはサンプルアプリケーションのコードが収録されており、すぐに使用できる状態になっています。ここで紹介したアイデアを、読者自身のナビゲーション対応AJAXアプリケーションの基礎として利用してください。