JSON-RPCのまとめjqGridのTreeGridでJSON-RPCTreeGridのtreeReader.expand_fieldが動作しないコメントjqGrid使用メモjqGridを使った際のメモを残しておきます。opt)でページャーを追加するときのoptで以下のようなオプションを追加できる模様。Addボタンを押されたときの動作。通常のフォームエディットの代わりに、実行したいFunctionを設定可能。(プラグインが一つのファイルにまとめられているので)いろいろ調べてみたのですが、解決策を書いたページが見つからなかったのでメモ。4にしたところ、以下のようなエラーが出ました。functionこれはjQueryの$()関数中でjqGridプラグインにアクセスした際に発生することがあるようです。4のHTMLパーサに関して以下のような資料がありました。Firefox4では<script>タグは並列して解析される、と(たぶん)。そのため、HTMLファイルのインラインJavaScript中、$()部分(jQueryのonloadですね)がjqGridの外部ファイルを読み込む前に実行されてしまっていると推測されます(どうやらHTML5の仕様らしいです)。jqGridのjquery.jqGrid.jsの動作jqGridがくせ者なのはjquery.jqGrid.jsの存在であり、これを<script>タグで読み込んだ場合、解釈され、必要なファイルが読み込まれますが、Firefox4ではこれが問題になるようです。丁寧に<script>タグでjs/grid.*.jsを読み込んでいる場合は問題が起こらない・・・はず(試してません)。4jquery.jqGrid.jsが読み込まれるjquery.jqGrid.jsのloadedイベント発生インラインの<script>の$()が実行されるjs/grid.*.jsが読み込まれる(非同期処理のためタイミング不定)Firefox4では、js/grid.*.jsを読み込む処理がブロックされないため、実際に読み込みが完了していないのにloadedイベントが発生してしまう状態になると推測されます。そのため、環境によってはエラーが再現しないという状況になるようです。解決方法これを解消するためには上のサイトのSolutionsの1つめの方法、document.write()を使います。document.write()を使うと以下のタイミングになるようです。4によると以下のように解説されています。parallel.ここに示されているdocument.write()による方法を使うと以下のように処理されると考えられます。ここでは<の代わりに\u003Cを使っていますが、私が確認したところ通常の<でも問題ないようでした。jquery.jqGrid.jsが読み込まれるdocument.write()でjs/grid.*.jsのタグ書き込み、解釈(同期処理になる)jquery.jqGrid.jsのloadedイベント発生インラインの$()が実行される具体的にはjquery.jqGrid.js中の以下の部分を修正します(これは3.8.2ですが4.0.0でも同様の箇所があるはず)。IncludeJavaScript()でDOMを使って外部ファイルを読み込むようにしていますが、IEではdocument.write()を使っています。そこで、Firefox4でもdocument.write()を使うように修正します。34行目のif文を以下のように修正します。4.0.1では$.browserは{mozilla=true,version="2.0.1"}でした。そのため、この条件によりFirefox4でもdocument.write()が使われ、問題が解消しました。loadErrorが使われる。ajaxGridOptionsが結合されるため、ajaxGridOptionで設定すれば任意のオプションを上書きすることができる(おそらく高度な使い方だろうが)。処理リクエストが送信される前にbeforeSendハンドラがコールされ、jqGrid#loadBeforeSendが設定されていればbeforeSendハンドラ内でjqGrid#loadBeforeSend(xhr)がコールされる。送られるデータはjqGrid#serializeGridDataが定義されていればjqGrid#serializeGridData(postData)の戻り値が送信される。定義されていなければjqGrid#postDataの内容が送信される。ts.p.postData,成功時は通常のjqGridのsuccessハンドラ(1593行目)、エラー時はloadErrorが定義されていればloadError(xhr,textStatus,errorThrown)が、されていなければerrorハンドラ(1602行目)がそれぞれコールされる。jqGridのデータ取得でJSON-RPCここでは、jqGridを使う際にJSON-RPCを用いる方法を模索していきます。2.0提案(proposal)に則ったメッセージパッシングを試してみます。jqGridのデータ取得リクエストデータ取得リクエストは最後にjqGrid#serializeGridData()がコールされるので、ここで与えられるデータをJSON-RPCリクエストのJSON文字列に変換します。#ID}というオブジェクトを返します。#IDはGLOBAL.jsonで保持しているランダムなID番号。返されたオブジェクトをJSON文字列に変換すればそれがjqGridにより送信されます。Arguments,id:#ID}がURLエンコードされた文字列で送られます応答時のエラー処理フックする部分が見つからず、送信よりも応答時の処理の方が難しく感じました。500などのHTTPエラーではなく、あくまでJSON-RPCのエラーです。従って、HTTP通信は正常に完了しているというところに留意してください。そのため、AJAX処理内ではsuccessハンドラがコールされます。JSON-RPCエラーオブジェクトの処理はjqGridのsuccessハンドラ内(1593-1601行目)で行うことがスマートだと思いますが、successハンドラ内ではフックされるメソッドがありません。そのため、jqGrid#ajaxGridOptionsでいっそのことsuccessハンドラを上書きするかjqGrid#jsonReaderを使った少々トリッキーな方法をとることにします。jsonReaderはデータ構造を定義するパラメータで、関数としてコールされるのでその中に処理を書くことでJSON-RPCエラー処理を行うことができます。jsonReader.root()がrecordsの配列データを返さなければ(空配列やundefined、null)、データは追加されないことを利用します。recordsが処理されるのでこの段階でobject#resultを使うとundefinedエラーになるのでその辺りは適宜処理します。この例ではrecords()で0を返し、root()で空配列[]を返すようにしています。rootどちらで行っても問題ないようです。インライン編集でのJSON-RPCインライン編集の場合もグリッドデータ取得とほぼ同じような手順で行います。APIのeditRowを使用します。...});ここのポイントはeditRowの第4引数のrpcOnSuccessです。JSON-RPCメッセージで応答が返ってくるので、後述するようにレスポンスを処理しなければなりません。そのためにrpcOnSuccessメソッドで処理します。RPCリクエストは後述のjqGrid#serializeRowDataプロパティで処理を行います。リクエスト送信先は第5引数urlで指定しますが、省略はできないようです。ここでは第2引数のkeysがtrueになっているのでEnterを押すことでリクエストが発行されます。リクエストリクエスト時の処理は、jqGrid#serializeRowDataをセットします。以下のようにコードすると送信前にrow_dataをシリアライズすることが可能になります。serializeRowDataは送信文字列を戻すようにします。応答時の処理で問題となるのはグリッドデータと同様JSON-RPCのエラーオブジェクトの扱いです。HTTP成功後の処理をフックするときはeditRowの第4引数successFuncに関数で行うことができます。この関数で真を返せば編集処理成功、偽なら失敗と判定することが可能です。"JSONRPCService");これでリクエストが成功すればonSuccess(XMLHttpRequest)がコールされます。真を返せば編集がデータグリッドに反映され、偽なら編集処理が失敗とみなされ、データグリッド内の対象データが元のデータに戻ります。ここで反映されるというのはデータグリッドに表示されているデータが書き換えられるということを示します。ダイアログ編集でのJSON-RPCフォームエディットでのJSON-RPCの方法を解説します。フォームエディットではjqGrid#editGridRow()で行います。properties)ここのpropertiesで値をセットすることで挙動を制御します。...});インライン編集とは書式が異なっているので注意。編集するレコードのIDと対するプロパティを指定することで編集します。後述のようにリクエストを発行する際にはserializeEditDataプロパティによる処理、レスポンスはafterSubmitプロパティで処理します。afterSubmitは必須です。closeAfterEditプロパティを真にすると編集終了後にダイアログを閉じます。フォームからのリクエストpropertiesのserializeEditDataに送信前のデータを処理する関数を定義します。戻り値はJSON文字列になるようにします。GLOBAL.json.objToJson(obj);},戻り値の処理レスポンスもインライン編集と同じように処理しますが、ここではpropertiesのafterSubmitに受信後の処理をセットします。引数はXMLHttpRequestとpostDataです。res.result.loid];}afterSubmit()はmixed配列を返し、[ステータス、メッセージ、新規レコードのID]となります。ステータスは真偽値で真なら成功です。ステータスに偽を返した場合、メッセージが表示され、操作が取り消されます。成功した場合は新規レコードのIDをセットすることでレコードに新たなIDが与えられます。JSON-RPCのまとめこれらをまとめると以下の表のようになります。afterSubmitレスポンスの扱いがややこしいですね。別の方法としてはレスポンス時にHTTPエラーステータスを返すのも一つの手ですが、それはそれで弊害がありそうな・・・jqGridのTreeGridでJSON-RPCTreeGridでツリーが追加される際にJSON-RPCにしたい場合、reloadGridイベントをあらかじめセットしておく。バブリングにより、jqGrid本体のreloadGridが実行される前にここでセットしたreloadGridハンドラが実行される。ajaxアクセスが起こる前の処理...});$("#treegrid").jqGrid({パラメータ...});なお、bindは自分を返すのでカスケード可能。$("#treegrid").bind("reloadGrid",...).gqGrid({...});こんな感じ。修正するなら以下のようにする。