ushidayの日記

主に「IBMi」のメモに・・・

Zend_Mailでチョット

Zend FrameworkのZend_Mailを使っている時に、チョコチョコ忘れそうな事が有ったのでメモしておきます。

ファイルの添付

ファイルの添付で以下の様な方法の解説をよく見かけたのでやってみたが、添付された中身がどうも巧くないです。

$filePath = './temp/test.pdf';
$handle = fopen($filePath, "rb");
$data = fread($handle, filesize($filePath));
fclose($handle);

結局こっちで巧くいきました。

$data=file_get_contents($filePath);
MIME TYPE

添付ファイルのMIMEタイプの設定にPEAR::MIME_TYPEを使いました。(Zend Frameworkで統一したいが...あるんかな?)

    • pearコマンド「pear install mime_type」でインストール
    • 実装は、「mime_content_type($hogefile)」と「exec("file -bi" . $hogefile)」のどちらかが動いている模様。”mime_content_type”は非推奨、「PECL 拡張モジュール Fileinfo」を使うのが良いようです。Zend Core i5にはビルドされていないので、今回は諦めます。
制限時間

ローカルのZend Serverで試した時は問題なかったが、IBM i(AS/400)上のZend Coreで添付ファイル付きメールを実行するとエラーが発生しました。

PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /usr/local/Zend/ZendFramework-1.10.0/library/Zend/Mail/Protocol/Abstract.php on line 340

どうも、添付ファイルのサイズが大きい(500k程度)と、時間が掛かる様です。30秒ルールに引っ掛りました。

  • 対応策
    • set_time_limit(60);(実行スクリプトのみ有効)
    • php.iniの「max_execution_time」を変更する

AS/400だと、インターネットに繋いだ時に、少し(だいぶ?)遅い気がします。

とりあえず。以上で巧くいきました。

Haskell読書会4th@三島 開催のお知らせ

第四回Haskell読書会を開催致します。
今回は、初の東部(三島)開催です。
東部のメンバーの方々も多いので、盛り上がって、今後定期的な開催が出来ればといいなぁと思っております。
懇親会は一次会の方は調整中ですが、二次会は雰囲気のイイBarを代表がリサーチしてくれてあるので楽しみです。と思ったが、車で行くから飲めないジャン!!(;_;)
本題の方ですが、スピーカーは静岡IT Pro代表のとなかさん(id:ftnkさん)がやってくれます。内容はリスト内包がメインです。おっと早く勉強しなきゃですが...。開催要項は以下の通りです。メンバーが固まりつつありますが、自分も含めHaskell未経験者も多いので、途中参加も歓迎致します。Haskellだけでなく静岡ITの開発系技術者が語れる場としていけたら良いと思ってます。

以下の要領で第四回Haskell読書会を開催いたします。

申し込みフォームリンク「http://bit.ly/dn6qRn
※こちら「http://bit.ly/d1Cte2」で登録状況の確認が出来ます。

●開催要領
・日 時 : 2010年4月24日(土) 13:00〜17:00
・場 所 : 三島商工会議所会館 4階会議室B
・地 図 : http://www.mishima-cci.or.jp/profile.html
・定 員 : 20名
・費 用 : 一般 1000円,学生・未成年:無料
・持ち物 : パソコン(練習問題をやるのに使用)、課題図書
・課題図書: プログラミングHaskellISBN:4274067815)※各自事前購入
・環境  : OS依存はしないが、GHC又はHugsを事前導入しておく事
・範 囲 : 5 章
・担 当 : となかさん
・懇親会 : 調整中
・懇親会費: 一般 4,000 円、学生・未成年 2,000 円 程度の予定

shizu-dev Haskell読書会最新情報「http://bit.ly/d8qca0

トランザクション分離レベル・省略値の違い

以前は、IBM i(AS/400)上のZend Coreにデプロイしてテストやリモートデバッグをしていたのですが、最近は、Windowsのローカル環境に立てた、Zend Server for Windowsでテストやデバッグをしてから、AS/400にデプロイしています。一人チーム開発なので、人のソースとマージしたりする事もないですし、この程度の事でも、実はソースコードのバックアップの代わりにもなったりします。(※ちゃんと正規のバックアップはしていますよ。モチロン...。)

Zend Server for Windowsを使っていて、気づいた違いについてメモを残しておきます。(「今頃、遅いよ!」と言うツッコミは無しの方向で...(-_-;)ゞ)

普段AS/400をメインで使っていると、STRSQLやSQLRPGも省略のトランザクション分離レベルが「*NC(即時コミット)」です。Zend Core for i5を使っていても省略は即時コミットです。たまーに、VBやらでODBC使うときは、「*CS(コミットされていない読取)」と言うことを思い出して、ODBCドライバの設定を「*NC」にするか、ジャーナル処理を「STRJRNPF」で開始しておきます。そうしないと、追加更新時に、”ジャーナル処理されてないお。”エラーで怒られます。ちなみにADOだと意識しなくても追加更新できるので省略が「*NC」と言うことになってるのだと思います。
ODBCの省略

本題ですが、Zend Core i5からZend Server for Windowsに移しただけで、特に動作なども問題のないアプリだったので、何も考えずテストしていたら、エントリー系のレコード追加更新で何処かで見たようなメッセージで怒られました。こんな感じのメセージです。

 [IBM][CLI Driver][AS] SQL7008N REXX 変数 "TABLE NAME " に矛盾したデータが入っています。 SQLSTATE=55019 SQLCODE=-7008

「ジャーナル処理されてないよ。」というストレートなメッセージにして欲しいのですが、どうやらこのメッセージが”ジャーナル処理されてないよ”という事みたいで、DB2 ConnectのCLI接続もODBCと同様に省略が「*NC」ではなく「*CS」の様です。

  • トランザクション分離レベルの設定で考えられそうな対処方法
    1. ジャーナル処理を開始(STRJRNPF)する。
    2. DB2 Connectの「C:\Program Files\IBM\SQLLIB\db2cli.ini」で分離レベルを指定する。
    3. SQLの「SET TRANSACTION ISOLATION LEVEL NO COMMIT」で分離レベルを指定する。
    4. SQLの「WITH句」を使って「WITH NC」で分離レベルを指定する。

まず(1)の方法ですが、対処としはジャーナルを作る事も、それはそれでアリですが、通常それ程クリティカルな要件で無い場合に、ジャーナル処理はレシーバーのオモリやリソースの消費も含めて考えると、必要では無いケースもあります。方法としては「CRTJRNRCV」→「CRTJRN」→「STRJRNPF」でジャーナルを開始します。確かにジャーナルがあると、万が一の時に、ある時点に戻る事が出来るので、トラブル時には威力を発揮してくれる事は確かでしょうが...。
■STRJRNPF

次に(2)の「db2cli.ini」でオプションを追加して、データベースカタログ単位で、分離レベルの省略を設定する事が可能です。以下が設定例です。これが一番簡単で、i5とも同期が取れるので、今回はこれを採用しました。
■「db2cli.ini」

; TXNISOLATION=1|2|4|8|32(UR|CS|RS|RR|NC 省略はCS。32はDB2 for iの即時コミット。)
[カタログ名]
DBALIAS=カタログ別名
TXNISOLATION=32

テキストファイルを直接変えてもいいですし、DB2の構成アシスタントで、選択(S)メニューのCLI設定でも変更する事が出来そうです。(自分は調子悪くてDB2GUI画面は砂時計のまま動きませんでした。)

(3)と(4)は直接SQLの発行で、指定する方法ですが、(3)に関しては上手くいくかと思いきや、駄目でした。AS/400のSTRSQL等では勿論実行できますし、i5版ですとそういった解説もあるので、もしかしたらWindows版のDB2 Connectを使っているなど、実行環境による差異が幾分ありそうです。ちなみに返されたメッセージは以下の通り、

[IBM][CLI Driver][AS] SQL0525N セクション = "1" パッケージ = "SYSSH200 " 整合性トークン = X"NULLID" のバインド時にエラーが発生したため、SQL ステートメントは実行できません。 SQLSTATE=51015 SQLCODE=-525

(4)は問題なく実行されました。ちなみに「php.ini」の”ibm_db2.i5_allow_commit ”は”0(no commit)”になっていますが、(※「i5_allow_commit」は、OS/400上のZend CoreやZend Serverにしか有効でない設定だからでした。)(2)も(4)でコミットもロールバックも出来ているので、DB2 ConnectのCLI設定が優先されている模様です。(トランザクション処理を使う場合は、autocommitオプションをOFFする必要があります。)
db2_connect()関数のオプションに”i5_commit=DB2_I5_TXN_NO_COMMIT”がありますが、これを指定してもジャーナルが開始されていないと、エラーが返されました。まだ色々と試す時間が無かったので、検証しきれていませんが、今後トライしてみて、さらに実態がつかめればと思います。

第三回Haskell読書会

第三回Haskell読書会が静岡市民文化会館で、開催され無事終了致しました。
スピーカーのid:kynbitさん、高校生という若さでLTをしてくれたSupakiくん、関係者並びにご参加頂いた皆様ありがとうございました。
ついつい話が脱線しがちな中、kynbitさん曰く、「今回の第四章のテーマは、あくまでも”関数の定義する方法を学ぶ”」という、かの名言で直ぐに軌道修正。前回よりも会場利用時間が、30分短いという中、ハンズオンを中心にまとめて頂き、充実していたのではと思います。

関連ブログ

本章の内容については、参加メンバーが既に、ブログで書かれているので、そちらで雰囲気を感じて頂けたらと。


おやつ

2開催連続で、代表のたかはしさんが、タマゴ型プリン&たまごボーロを、仕入れてきてくれました。ありがとうございます。そしてウマイ!頭使って糖分補給コレ基本です。たまごボーロも懐かしいです。口の中の水分みんな持っていかれる感じが何とも言えない。
(「eatたまごボーロ :: たまごボーロ → 口の中砂漠化」「drinkお茶 :: お茶 → 口の中オアシス」)


SupakiくんLT

最年少のSupaki君が、TwitterをテーマにLTをやってくれました。
Twitterのキモは”おやじギャグなんだ!”と教わりました。高校生にして、アラサーやアラフォーのオッサン相手に、OpenOfficeでスライド作るなんてすごい経験だよ。将来有望です。

練習問題1を2次会で「あーだこーだ」

本章の練習問題1は以下の様な内容でした。

要素数が偶数のリストを引数にとる関数「halve」は、要素数の真ん中で2分割したリストのタプルを返す。
つまり...
halve [1,2,3,4,5,6]
>([1,2,3],[4,5,6])
になれば良いと

kynbitさんから、追加の課題で「奇数の時は、リストを返さないでエラーを...」。しかし終了時間を迎え、急いで片付け、そのまま懇親会へ。そして2次会で、「奇数でエラーって型宣言しているから、空リストのタプル返すくらい?」みたいな話で、「まぁ、それだけでもやってみようYo!」とバーでPC引っ張り出してきて「あーだこーだ」。(何やってんだろ?)
Haskellとしては(関数型としては?)、当たり前の事が、やはりいざキーボード叩いてみると、上手くいかなかったり、面白い発見もあったり、とりあえずの結論が出たところで、2次会は解散。そんな中で、where節を改めて考えてみました。

バーで追加課題をやっていた時、まずこういう書き方で、Parseエラー

-- parse error on input `|'
halveBar::[a]->([a],[a])
halveBar xs | (length xs `mod` 2) == 0 = (take (myLen) xs ,drop (myLen) xs)
                where  myLen  =  length xs `div` 2
            | otherwise =  ([],[])

halveBar::[a]->([a],[a])
halveBar xs | (length xs `mod` 2) == 0 = (take (myLen) xs ,drop (myLen) xs)
            | otherwise =  ([],[])
                where  myLen  =  length xs `div` 2

こっちはOK。where節を細かくやっていないので、自分が語ると間違っていそうで、アレなのですが、調べてみると...。

    • where節は、直前の束縛の右辺に対して作用する。
    • where節は、直前の束縛より深いインデントでなければならない。

確かにガードは、「if then else if then else ...〜」のシンタックスシュガーみたいなモノだから、前の例だとthenとelseの間にイキナリwhereを入れている様なもので、よくよく考えればおかしい。つまりこうしているのと同じ

halveBar::[a]->([a],[a])
halveBar xs = if (length xs `mod` 2) == 0 
                    then  (take (myLen) xs ,drop (myLen) xs)
                            where  myLen  =  length xs `div` 2   -- if ならせんヤロ
                    else  ([],[])

halveBarの束縛に対して、whereで局所定義するなら、普通にこうなる。

halveBar::[a]->([a],[a])
halveBar xs = if (length xs `mod` 2) == 0 
                    then  (take (myLen) xs ,drop (myLen) xs)
                    else  ([],[])
                            where  myLen  =  length xs `div` 2

ifだと間違えない、それはそんな処にwhere入れたら、違和感を感じるから。でもガードみたいな見慣れない、シンタックスを拝んだりすると、変な錯覚をしてしまい、違和感を感じない。(そもそもガードの書き方に違和感を感じたり。見やすくて好きなんですけどね、^_^ガード。自分ガード派です。今のところ...)あーダメな自分を再認識しました。そして理解した上でまとめ。

halve::[a]->([a],[a])
halve xs | myEven = (take myHalfLen xs ,drop myHalfLen xs)
         | otherwise =  ([],[])
  where 
     myLen      =  length xs                     --リストの長さ
     myHalfLen  =  myLen `div` 2                 --リストの半分の長さ
     myEven     |  (myLen `mod` 2 ) == 0 = True  --要素数の偶数判定
                |  otherwise = False

whereは直前の束縛の右辺に対して作用とあるが、上の記述は正しく動いているので、同一where内の束縛に対しても有効みたい。(myLenはmyEvenなどでもスコープ出来ているので...。)これは、結果論なので、本当に正しいのかはチト不安な気もします。
スコープでダメな例は以下のような場合。

--     Not in scope: `myHalf'
--   Failed, modules loaded: none.

halveNG::[a]->([a],[a])
halveNG xs | myEven = (take myHalfLen xs ,drop myHalfLen xs)
           | otherwise =  ([],[])
  where 
     myLen      =  length xs
     myHalfLen  =  myLen `div` myHalf  -- myHalfはスコープできない。
     myEven     |  (myLen `mod` myHalf ) == 0 = True
                |  otherwise = False
        where myHalf = 2

この場合は、それぞれwhere節が下のように、必要になる。

halveNG::[a]->([a],[a])
halveNG xs | myEven = (take myHalfLen xs ,drop myHalfLen xs)
           | otherwise =  ([],[])
  where 
     myLen      =  length xs
     myHalfLen  =  myLen `div` myHalf
        where myHalf = 2
     myEven     |  (myLen `mod` myHalf ) == 0 = True
                |  otherwise = False
        where myHalf = 2

今回はひょんなことから、where節の理解が少し深まりました。次回の第4回は三島で行うことに決定しました。また正式に決まり次第告知させて頂きます。
2010.7.24(土)のグランシップ開催だけは、リアルガンダム東静岡に初お披露目とあって、早速会場をキープしました。;-)

SigmaGridを使ってみた(その3)

SigmaGridには、サーバーサイドページングとサーバーサイドソーティングの機能もあるので、そっちを使ってみました。今回はページングです。

サーバーサイドページング

gridオプションの「remotePaging」を”true”にします。PHPのサンプルは”デモディレクトリ/export_php/testRemotePaging.php”に入ってるので、それを参考にします。
サーバーサイドページングのカラクリは、MySQLで言うところの”offset limit”を使って必要なレコードを取得するというやり方と、全件取得したレコードセットを”array_sliceで切出す”の2パターンありそうです。但し、DB2は前述の様な”offset limit”に該当するものがないので"rownumber() over "を使い自前でオフセットする必要があります。
巨大トランザクションを相手にページングするわけでもないので、とりあえず実装が単純な”array_slice”でページングします。(デモサンプルはこっち)以前からの流れで、Zend MVCを使っているので、JSONレスポンスもZend Controllerに任せる形で、以下の様なアクションを追加します。

■アクションコントローラのメソッド

<?php
require_once 'Zend/Controller/Action.php';
require_once 'dao/SearchModel.php';

//ユーティリティのインクルード
require_once('GridServerHandler.php');

class OrderController extends Zend_Controller_Action{
    public function getjsonAction()
    {
    $gridHandler = new GridServerHandler();

    //サンプルには記載されているが、未定義エラーになる。
    //$type = getParameter('exportType');

    //開始行
    $start = $gridHandler->pageInfo["startRowNum"] - 1;
    //1ページあたりの表示行数
    $pageSize = $gridHandler->pageInfo["pageSize"];
    
    $model = new SearchModel();       //DAO
    $result = $model->getList();      //データ取得
    $rows = $result["data"];
    
    // ページング
    $data = array_slice($rows, $start, $pageSize);
    
    //ハンドラーに渡す。
    header('Content-type:text/javascript;charset=UTF-8');
    $gridHandler->setData($data);
    $gridHandler->setTotalRowNum(count($rows));
    $gridHandler->printLoadResponseText();
        
    }
}
?>

”GridServerHandler”ですが、これはSigmaGridのサンプルの中(export_phpディレクトリ)にあります。SigmaGridとプログラム間でのやり取りを簡略化してくれるユーティリティクラスで、引数の受け取りや、データを渡す際にJSONへの変換を提供してくれます。これを使うためには、必要なユーティリティを”include_path”に通しておくか、プロジェクトの”library”に配置しておく必要があります。
サンプルには記載がある「getParameter('exportType');」のステップは未定義でエラーになりました。エクセルやPDFへのエクスポートも出来るので、そっちで関係有るのかと...。
$gridHandler->pageInfo[名前]で、SigmaGridの現在のステータスを取得出来ます。これは「$_POST["_gt_json"]」でPOSTされた引数をGridハンドラーのプロパティとしてラップしてあります。開始行(startRowNum)と1ページあたりの行数(pageSize)プロパティを取得して、”array_slice”で切り出します。
setDataメソッドで切り出した連想配列とsetTotalRowNumメソッドで合計のレコード件数を渡して、レスポンス(printLoadResponseText)すれば、ページング完了です。

Zend Projectでサービスって

Zend MVC で使うときは、コントローラーアクションと同名のダミーのViewが必要なのか?(CoCで考えれば当たり前に必要かとも..)Viewが無くても出来るのかは?まだZend MVCを深く掘り下げていないので、わかりませんでした。
とりあえず、Viewがないとエラーになったのでダミーのビューを作りましたが、むしろこれはMVCでは無くて、サービスだと思いますが、Zend Projectのapplicationにサービスと定義されたディレクトリは無いので、パブリックなディレクトリに適当に作るのが一般的なのか?どういう流儀なのかは、正直よくわかっておりません。

SigmaGridを使ってみた(その2)

普通にSigmaGridとjQuery uiを使いますと、表示の階層で少し手入れが必要になります。

例えば普通にjQuery uiの”autocomplete”や”datepicker”を使うとこうなります。
■autocomplete

■datepicker

調べると、SigmaGridは「gt_grid.cssの”.gt-head-div”」でz-indexが2、autocompleteとdatepickerはstyle埋込みで、z-indexが1でした。
■datepickerの埋込スタイル

autocompleteでの対応

autocompleteの場合は、”openイベント”で、z-indexの調整を行います。ただこの場合は、固定になってしまい、ダイアログuiなどが、もっと大きな値のケースがあるので、その場合は”maxZIndex”などのユーティリティで、最大z-indexを動的に取得、設定するか、適宜変える必要があります。

        // サジェストのz-indexを調整
        $('.ui-autocomplete-input').autocomplete('option', {open:
            function(event,ui){ 
                //静的設定
                $('ul.ui-autocomplete').css('z-index',5) ;
            }
        });
datepickerでの対応

datepickerは”beforeShowイベント”でやろうと思ったのですが(以前のバージョンでその様に解説しているサイトもありましたが...)、どうもdatepickerのz-indexの設定が、イベント後のようで、うまくいきませんでした。
jQuery uiの中では、”zIndex”というメソッドで最大値を取得してやっていそうなのですが、jQuery uiのインスタンスで最大の値を取得するだけなのかもしれません。(追ってないので詳細は不明ですが、属性はzIndexを調べていたので...。以前のuiだとダイアログとのz-indexを手動で調整していたのが、この辺りで改善されているのカモ。)
”afterShowイベント”的なものは無さそうなので、あきらめて暫定で、”jquery.ui.datepicker.js”の645ステップあたりを以下の様に修正しました。

         //inst.dpDiv.zIndex($(input).zIndex()+1);
         inst.dpDiv.zIndex($(input).zIndex()+5);

■修正後

余談

datepickerを日本語にすると、デフォルトcssだと、年月のセレクタが縦に並んでしまうので、以下のクラスを調整して横に並べます。
■任意のcssに以下を追加

/* カレンダー年月の幅調整  */
/* 元のテーマ「jquery-ui-1.8rc3.custom.css」 */
.ui-datepicker select.ui-datepicker-month, 
.ui-datepicker select.ui-datepicker-year { width: 45%;}  /* 49%; */

SigmaGridを使ってみた(その1)

今ゴショゴショやっている案件で、AJAXライブラリは、jQueryを使っておりまして、uiのプラグインjQuery uiを使っております。グリッドコンポーネントは、”jqGrid”というプラグインがあるのですが、JSONデータを渡す際に、独自のフォーマット(idとcellのHashMapでCellに個々のフィールドを入れる)にしなければいけないようで、「そのままのJSONを使って何とかしてくれて、高機能なGridは何かない?」と思い。jQueryじゃ無いのですど、「もうこれで十分。HTML上でテーブルを表示するなら「Sigma Grid」」というキャッチを見て、使ってみたので、少しメモをしておきます。

Sigma Gridを入手

Sigma Gridの公式サイトから、SigmaGridを入手します。PHP,C#,VB.NET,JSPのサンプルもあるので、そっちもついでに入手します。Sigma Visual GUI Builderという、AjaxコンポーネントGUIツールもあるようです。(こちらは今回パス)

Sigma Gridを使ってみる

htmlのヘッダー部のインクルードは以下の様な感じです

<!-- 基本 -->
<script type="text/javascript" src="./sigmagrid/2.2/grid/gt_grid_all.js"></script>

<!-- グリッドの基本CSS -->
<link rel="stylesheet" type="text/css" href="./sigmagrid/2.2/grid/gt_grid.css" />

<!-- グリッドのスキン -->
<link rel="stylesheet" type="text/css" href="./sigmagrid/2.2/grid/skin/vista/skinstyle.css" />
<link rel="stylesheet" type="text/css" href="./sigmagrid/2.2/grid/skin/mac/skinstyle.css" />
<link rel="stylesheet" type="text/css" href="./sigmagrid/2.2/grid/skin/china/skinstyle.css" />

<!-- メッセージのローケル  -->
<!--  <script type="text/javascript" src="./sigmagrid/2.2/grid/gt_msg_en.js"></script>  -->
<script type="text/javascript" src="./sigmagrid/2.2/grid/gt_msg_ja.js"></script>

<!-- このページのCSS -->
<style type="text/css" media="all">@import "./doc_no_left.css";</style>
  

スキンが、”vista、china、mac、緑系デフォルト”の3つが用意されいます。メッセージは英語(gt_msg_en.js)と中国語(gt_msg_cn.js)が用意されているので、とりあえずコピペして”ja”を作ります。下の様にメッセージを日本語に変えていきます。

■「gt_msg_ja.js」

Sigma.Msg.Grid.en={
	LOCAL	: "ja-jp",
	ENCODING		: "UTF-8",
	NO_DATA : "データなし",


	GOTOPAGE_BUTTON_TEXT: 'Go to',

	FILTERCLEAR_TEXT: "全てのフィルタを除去",
	SORTASC_TEXT	: "昇順",
	SORTDESC_TEXT	: "降順",
======= 続く ===================================

カラムやデータ項目の定義はJavaScriptで以下の様にします。

■フィールド定義

// DataSetのフィールド定義
var dsOption= {

    fields :[
        {name : 'ordern' ,type:'int'  }
        ,{name : 'odate'  }
        ,{name : 'ldate'  }
        ,{name : 'sdate'  }
        ,{name : 'custn'  }
        ,{name : 'shipn'  }
        ,{name : 'empln'  }
        ,{name : 'transn'}
        
    ],

    recordType : 'object'  //JSON=object , Array=array
}

JSONとGridに使うデータ項目の定義をします。

    • ”name”: 渡すデータのHashMapのキー部分の名前。一般的にはフィールド名だと思います。
    • ”type”: データタイプを定義します。(省略がstringでint,date,floatがあるようです。)
    • ”recordType”: JSONを使う場合は、object。配列を使う場合は、arrayを設定します。
    • ”data”: JavaScript内部のデータを使う場合は、data:変数名とします。外部データの場合は必要ありません。

■グリッドカラムの定義

// カラムの設定
var colsOption = [  

     {id: 'ordern' , header: "受注No" , width :60  ,frozen:true}
       ,{id: 'odate' , header: "受注日" , width :70  }
       ,{id: 'ldate' , header: "納期" , width :70  }
       ,{id: 'sdate' , header: "出荷日" , width :70  }
       ,{id: 'custn' , header: "得意先" , width :200  }
       ,{id: 'shipn' , header: "出荷先" , width :200  }
       ,{id: 'sstate' , header: "都道府県" , width :60, hidden:true }
       ,{id: 'sadd1' , header: "住所1" , width :200, hidden:true  }
       ,{id: 'empln' , header: "営業担当" , width :100  }
       ,{id: 'transn' , header: "運送会社" , width :80  }
       
];

見れば想像がつきますが、

    • ”id”: JSONデータとバインドする、先ほどの”name”フィールドの名前。
    • ”header”: グリッドの見出し。
    • ”width”: 列の幅。
    • ”hidden” : 列の表示。true又はfalse。trueとしておくと、後に任意で表示させる事が出来ます。
// オプション設定
var gridOption={
	 id : "grid1"             //任意のid
	,container : "gridbox"   //Gridを表示するdivのid
	,loadURL : "search.php"  //外部Data(JSON)
	,replaceContainer : true 
	,dataset : dsOption      
	,columns : colsOption
	,encoding : "UTF-8"
	,pageSize:5             //ページのサイズ
	,pageSizeList : [5,10,15,20,25,30]  //表示単位
	,width: "680"  //"100%" // 700,
	,height: "150"  //"100%" // 330,
	,showGridMenu : true     //メニュ
	,allowCustomSkin : true  //スキンテーマの選択
	,skin:"mac"              //既定のスキン
	 // nav | pagesize | reload | add del save | print | filter chart | state
	,toolbarContent : " nav | goto | pagesize | reload | print | filter| state "
	,allowFreeze : true      //列の固定
	,allowGroup : true       //グループ表示
	,allowHide : true        //列の非表示
	//,autoLoad : false      //自動ロード
	,remotePaging : false    
        ,remoteSort : false
        ,remoteFilter : false
};

var mygrid=new Sigma.Grid(gridOption);     //gridインスタンス生成
Sigma.Util.onLoad(Sigma.Grid.render(mygrid));   //グリッドのロード

ポイントになるのは、

    • ”container”: グリッドを表示するDivタグのid。
    • ”loadURL”: JSONデータを返すurl。
    • ”remotePaging”: ページング処理をサーバーサイドで行うか?true又はfalse。

です。 ここで少しハマったのが、”remotePaging”なのですが、付属サンプルなどの例にある、JavaScripの内部データを使った場合は、”remotePaging”を特に設定しなくてもページングしてくれるのですが、外部データの場合?は、明示的に”false”を指定しないと、ページングをしてくれませんでした。他は付属的なオプションが沢山あるので、割愛します。オプションを設定したらSigma Gridのインスタンスを生成するだけす。

JSONを渡すsearch.php

<?php
class Model{
    
    private $dumyData = array(
                array("ordern"=>10001
                     ,"odate"=>20100301
                     ,"ldate"=>20100310
                     ,"sdate"=>20100309
                     ,"custn"=>"海猫商事"
                     ,"shipn"=>"海猫工業"
                     ,"sstate"=>"静岡県"
                     ,"sadd1"=>"XXXXXXXXXXX"
                     ,"empln"=>"鈴木太郎"
                     ,"transn"=>"アカネコ"
                     )
//===== ダミーデータ =====
               ,array("ordern"=>10007
                     ,"odate"=>20100303
                     ,"ldate"=>20100319
                     ,"sdate"=>20100317
                     ,"custn"=>"サンライトテクノロジー"
                     ,"shipn"=>"サンライトテクノロジー"
                     ,"sstate"=>"静岡県"
                     ,"sadd1"=>"XXXXXXXXXXX"
                     ,"empln"=>"楠正志"
                     ,"transn"=>"ペルカン"
                     )
                     );
                
    public function getList(){
        
        //戻り値
        $ret = array();
        //ダミーデータを返す。
        $ret["data"] = $this->dumyData;
        return $ret; 
           
    }
}

header('Content-type:text/javascript;charset=UTF-8');

$model = new Model();
$result = $model->getList();
$rows = $result["data"];

$data = json_encode($rows);
$ret = "{data:" . $data .",\n";
$ret .= "recordType : 'object'}";
echo $ret;

?>

出力JSONに、dataキーとrecordTypeキー(配列の場合はarray)を付加して、レスポンスすればOKです。

■こんなかんじ

■スキンの変更

■列の固定など