XCITE Autumn 2014

来る2014/9/12、XCITE Autumn 2014 セッション(K-2)で講演致します

XCITE Autumn 2014

XCITE Autumn 2014 セッション(K-2)で講演

2014年、春に開催され大盛況だった日本IBMのイベントXCITE

今回、秋のイベント XCITE Autumn 2014のセッション「XPagesで革新!これからのNotes/Dominoアプリケーションの新常識」(K-2)IBM 佐藤 淳様と一緒に講演をさせて頂きます。

当日は、弊社のソリューションよりNotes/DominoとXPagesを用いたBtoC、BtoB によるコラボーレーション事例をご紹介致します。

皆様、是非ご参加ください。

日時:
    Business Partner Day  -  2014年 9月11日(木) 13:00-18:00    (受付開始:12:00)
    XCITE Autumn 2014  -   2014年 9月12日(金) 10:00-18:45    (受付開始:9:00)

場所:
    ザ・プリンス パークタワー東京
    (東京都港区芝公園4-8-1)

主催:
    日本アイ・ビー・エム株式会社

参加費:
    無料 / 事前登録制

詳細、申込みはこちらから » https://ibm-xcite.jp/

 


リッチテキストエディタのカスタマイズ

XPagesリッチテキスト CKEditorツールバーをカスタマイズ

XPages リッチテキスト コントロール

XPagesのリッチテキストコントロールはDomino 8.5.2からCKEditorが採用されるようになりました。

デフォルトでのリッチテキスト コントロールは以下の様なレイアウトになります。

デフォルトのXPages リッチテキストコントロール

デフォルトでは文字の修飾など基本的なことしか出来ないようになっています。

今回はこのCKEditorをカスタマイズする方法をご紹介します。

toolbarTypeを指定してカスタマイズ

以下の用にDojo属性を追加し、名前を「toolbarType」にし値を指定します。

値には

  • Slim
  • Medium
  • Large

を指定することができます。

リッチテキスト コントロールのプロパティ
リッチテキスト コントロールのプロパティ

それぞれのレイアウト

XPages リッチテキストコントロール Slim
「Slim」を指定
XPages リッチテキストコントロールMedium
「Medium」を指定
XPages リッチテキストコントロール Large
「Large」を指定

Javascriptを使ってフルカスタマイズ

dojo属性に「toolbar」を作り、ツールバーの項目をJavascriptの配列で指定することでリッチテキストコントロールのツールバーをフルカスタマイズすることが可能になります。

XPages リッチテキストコントロールをtoolbar属性でカスタマイズ
リッチテキストコントロールのプロパティ

値の部分にサーバーサイドJavascriptでツールバーの項目を以下のようにセットします。

全てのツールバーの項目を表示させたい場合、

のようになります。

このように、フルカスタマイズすることで、今までになかったHTMLソースコードでの編集等も可能になります。

XPages リッチテキストコントロール ツールバーのフル機能を表示
XPages リッチテキストコントロール ツールバーのフル機能を表示

CKEditor 3.X Developer's Guide も参考にしてください。

 


【XPages】 xe:jsonRpcService の使い方と考察

xe:jsonRpcServiceってなにやつ?

今回はExtension Libraryに搭載されている xe:jsonRpcServiceに関して日本語で解説がほとんど見当たらなかったのでブログに書いてみます。

xe:jsonRpcServiceはDomino Designerの右コントロールの「データアクセス」 →「リモートサービス」をXPagesにドラッグしてやることで作成することが出来るコントロールです。

jsonRpcService

とても軽量、シンプルな通信プロトコル JSON-RPC

でも使い道がいまいちよく分からないDomino技術者の方も多いと思います。そしてよく分かっていない内の1人だった自分が今回、jsonRpcServiceについて調べてみました。

まず、jsonRpcServiceはRPCの名が入っている通り、クライアントとサーバー間でリモート処理を実行したりするんだろう、と推測できます(RPC=リモートプロシージャコールの略)

そしてJSON-RPCはそれ自体が新しい規格であり、そのデータの受け渡しにJSONを利用したプロトコル(現行バージョンは2.0)ということです。

実際にはJSON-RPCでは以下の様なデータがやり取りされます。

とてもシンプルで軽量なプロトコルというのも納得ですね。

XPagesのjsonRpcServiceコントロールも同様に、できる限り軽量な構成になるようにデザインされており、クライアント・サーバー間で呼び出されたデータのみを送信し、返信されたデータのみを受信するといった軽量な処理が行えるコントロール、ということです。

ただ正直なところ、XPagesには部分更新イベントという便利な機能があるので、結果だけを見ると同等な実装が出来てしまうと思います。ではなぜjsonRpcServiceが必要になるのか?恐らくリモート処理がとても軽量に作られているということが一番の特徴だと思います。

例えば、株価の値を刻一刻と自動更新するようなアプリケーションを作りたいといった場合、XPagesの部分更新イベントを一分おきに発生させるというのはちょっと大掛かりな気がするのでもっと軽量な処理で実装したい、といったケースで役に立つのではないでしょうか。

 実際に使ってみた

jsonRpcService を使ったとってもシンプルなサンプルはこんな感じです。

6~10行目でJSON-RPCの関数を定義しています。ここではgetUserName()。処理内容はサーバーサイドJavascriptで記述できます。
そして13行目にボタンを配置してonclickイベントでクライアントJavascriptを書いていますが、service.getUserName();とすることでJSON-RPCのリモート関数を呼び出しを行っています。

このようにxe:jsonRpcServiceでリモート関数を定義すると自動でクライアントJavascipt関数が用意されているというところが肝ですね。

上記のサンプルでは関数の引数は使っていませんが、もちろん引数を持たせることも可能です。
引数を持たせて足し算の計算をさせたサンプルがこちらです。

ハイライトしている7,9,10,18行目を見て頂くとわかると思います。

 

どれだけ軽量なの?

それでは、実際にjsonRpcServiceがどれほど軽量か上記のコードをFirefox Firebugを使って確認してみます。jsonRPCService_add

上記のXPagesをFirefoxで読込み、Firebugを起動、「Net」のタブを開いておきます。そして「足し算」ボタンを押した時に追加される通信データを確認します。

 

 

 

以下の画像がその時のFirebugの表示結果です。

jsonRPCService Firebug

おぉ、データサイズわずか44バイト!! 軽っ!

実際にどのようなデータがやりとりされたのかもFirebugで確認してみます。

まずはPostデータ

jsonRpcSercie Post Param

ふむふむ、「"jsonrpc": "2.0"」 というようなプロトコル情報も省略されており本当に必要な情報のみがPostされています。

つぎにResponseデータ。

jsonRcpSercie Resqonse Param

やはり必要な結果のみがResponseデータとして返ってきています。

ちなみに同等の処理をXPages 部分更新で行いましたが、Postデータ、Responseデータ共にこれほど軽量な処理をさせることは出来ませんでした。また、XPagesの部分更新では”計算結果フィールド”のみを部分更新させるといった場合でも<span>タグ付きで値が返ってきたりと、クライアント側でのデータ再加工を行いたいというような場合、値だけを返すjsonRpcServiceのほうがプログラミングが楽になりそうです。

 jsonRpcServiceを利用する時の注意点

以下のサンプルコードをみてください。

上記のコードはこちらのStackoverflow で質問と一緒に公開されたコードです。
ハイライトされた9,10,20行目を見て頂くと、このコードの作成者はjsonRpcServiceのリモート関数を使ってXPagesで読み込んでいる文書を保存、返り値にTrueを返す、という処理を行いたいのだろうと推測できます。

ただ、このコードは意図した動きをしません。

今回の記事をここまで呼んで頂いた方々にはすでに察しが付いていると思いますが、jsonRpcSerivceはあくまでJSONによってデータをやり取りしていますので、9行目のgetComponent("inputText1").getValue() というのは解決が出来ない情報になってしまいます。

同様にXPages上に存在するdocument1というデータソースも取り扱うことができません。引き渡したいデータがあれば、xe:remoteMethodArg 引数を使って明示的にJSONデータに含めないといけないということです。

このように、jsonRpcServiceはXPagesで読み込んでいるデータソース文書を保存したりする処理には向いていないように思います。(出来ないことはないはずです)

jsonRpcServiceはデータの読み出し専用が得策?

このstackoverflowの回答者も言っていることですが、上記の理由からjsonRpcServiceはデータの読み出し専用として利用することが最良であるかもしれません。

以下、jsonRpcServiceを利用したらいいかもしれないシチュエーションとして

  • 会社の株価を定期的に自動更新するようなプログラム
  • 新しいユーザーを登録する際にすでに同じユーザー名、Emailがないかどうかを問い合わせるプログラム
  • サーバーからのレスポンスデータをクライアントサイドJavascriptで操作、加工したい場合

などに適していると思われます。

いかがでしたでしょうか?

jsonRpcSerivceの特徴を把握してXPages開発の選択肢の1つとして覚えておいてもらえればと思います。

 

 


2014年7月からノーツコンソーシアムに入会致しました

2014年7月から個人会員としてノーツコンソーシアムに入会させて頂きます。
色々な懇親会、研究会、テクニカルセミナーに参加することで沢山の情報交流とコミュニティーの活性化に繋がるよう努力してまいります。

7月、8月だけで以下のような沢山のイベントが予定されているんですね。
やはり弊社の一番の興味がある分野はXPagesですね。色んな技術者の方とお会いできるのが楽しみです。

2014/07/03  研究会  2014 IBM Notes/Domino DPP研究会 (7月3日)
2014/07/04  研究会  2014 大阪地区研究会 (7月4日)
2014/07/08  研究会  2014 XPages研究会 【機械実習あり】(7月8日)
2014/07/10  研究会  2014 ソーシャル研究会 【機械実習あり】(7月10日)
2014/07/18  研究会  2014 バージョンアップ研究会 (7月18日)
2014/07/31  研究会  2014 IBM Notes/Domino DPP研究会 (8月7日⇒7月31日に変更)
2014/08/07  研究会  2014 ソーシャル研究会 【機械実習あり】(8月7日)
2014/08/08  研究会  2014 バージョンアップ研究会 (8月8日)
2014/08/12  研究会  2014 XPages研究会 【日程変更】(8月12日⇒8月19日)
2014/08/22  研究会 【追加開催】2014 九州地区研究会 (8月22日)


liveness Portlet IC

XCITE 2014にて「liveness Portlet IC」が初お披露目されます!

liveness Portlet IC

2014年5月21,22日に開催される「IBM Software XCITE Spring 2014」にて、弊社のXPages開発パートナーである株式会社ライブネス様から
「liveness Portal」
「liveness Portlet」
「liveness Portlet IC」
がお披露目されます。

それぞれの位置づけは
liveness Portal   ・・・・・ IBM® Notes/Dominoベースの企業情報ポータル
liveness Portlet  ・・・・・ IBM® Notes/Domino アプリケーションをノンコーディングでWeb化をするポートレット
liveness Portlet IC ・・・ IBM® ConnectionsをDominoでノンコーディングで連携するためのポートレット

となっております。
どれもXPagesを使った革新的なソリューションになっておりますが、弊社ではXPages開発パートナーとして主に「liveness Portlet IC」の開発に携わってまいりました。

上記のようなソリューションをお探しでしたら、是非、株式会社ライブネスのブースまで足を運んでみてください。


XPagesでIEの互換表示ではなくIE8に強制表示する方法

ie日頃から”IEはこの世界から消えてなくなれ” と考えている私ですが、仕事ではやはりIEでのサポートが必須である場合がほとんどで、時に開発者として「IEさえなければ、IEさえなければ・・・」などとブツクサいいながらIEの下位バーションでテストを行っていたりします。

そんなIEですが、IE8ぐらいになってくるとかなりJavascriptやCSSのサポートが幾分マシになってきます。 しかしIE8から次に厄介な問題としてIEの互換表示という機能があります。

IE8で動作するように開発したページなのに、クライアントから「なんかレイアウトが崩れているんですけど・・・」なんて電話が、、、よくよく調べてみるとIE8互換表示モード(IE7)でブラウジングしていたのが原因だった、なんてケースです。 (消えてなくなれIE! )

IE8が出た当時は下位互換への救済措置だったりしたわけですが、IE11の今のご時世では混乱を招くもとになっているばかり。

前置きが長くなりましたが、今回の本題、

XPagesでIE8互換表示ではなくIE8に強制表示する方法

まず、状況の整理をすると、IE8で表示できるように開発したページであってもIE8互換表示で表示されることがあります。

[list_marked]

  • IISから指定されている
  • イントラのグループポリシーで設定されている
  • [/list_marked]

    というような場合です。 また嵌りやすいのがIE8はデフォルトで、”互換表示でイントラネットサイトを表示する”にチェックが入っているという点です。

     こういった場合、一般的にWEB開発者は

    [list_marked]

  • DOCTYPE宣言で指定
  • metaタグで指定
  • web.configなどのHTTPレスポンスヘッダーで指定
  • [/list_marked]

    という方法でIE8互換表示ではなくIE8に強制表示させるようです。

    ここではXPagesをつかってHTTPレスポンスヘッダ-を直接操作する方法を書いてみます。

    以下のコードをXPageのbeforeRenderResponse イベントに記載します。

    var exContext = facesContext.getExternalContext();
    var resp = exContext.getResponse();
    resp.setHeader("X-UA-Compatible", "IE=8");

    こうすることで描画をIE8で強制的に表示することが可能になります。

    xpagesのbeforeRenderResponse画面

    また、特定のIEのバージョンに限って制御を行いたい場合、以下のように context.getUserAgent() を使って制御文を書くことが出来ます。

    if (context.getUserAgent().isIE(8, 8)) {
      var exContext = facesContext.getExternalContext();
      var resp = exContext.getResponse();
      resp.setHeader("X-UA-Compatible", "IE=8");
    }

    ここでは、「IE8の場合からなず互換表示ではないIE8で動作させる」としています。

    なお、IE8でどのモードで描画しているのか確かめるためにはF12を押して開発者ツールを立ち上げて確認できます。

    IE8互換モードの切り替え画面

    IE互換表示の対応で苦戦している人は是非上のコードを試してみてください。


    XPagesでJSONをパースしよう、 fromJson関数の使い方

    今更聞けないJSONって何?

    JSON(ジェイソン、JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptにおけるオブジェクトの表記法をベースとしているが、JSONはJavaScript専用のデータ形式では決してなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しに使えるよう設計されている。

    引用:Wikipedia

    論より証拠。 JSONってこんな形式です。

    [
        {
            "勇者": [
                "隼の剣",
                "光の鎧"
            ]
        },
        {
            "格闘家": [
                "鉄の爪"
            ]
        },
        {
            "魔法使い": [
                "いかづちの杖",
                "水の羽衣"
            ]
        }
    ]

     Javascriptのオブジェクトの表記法と配列を組み合わせてとってもシンプルにデータ格納してしまおうということですね。正直、開発者にとってはXMLよりJSONのほうが好きな人のほうがおおいんじゃないでしょうか。

    さて、ここから本題です。

    XPagesのサーバーサイドJavascriptでJSONをパースするには

    SSJSってサーバーで動くJavascriptだよね、だったらJSONもJavascriptのフォーマットだし扱い得意だよね、と当然思う方も多いと思います。

    実際、XPagesではJSONをパースさせるのに幾つか方法があるようです。

    1. eval() 関数を使う。 XPagesの標準関数であるeval()を使ってお手軽にパースすることができます。こちらの例ではビューのカラムに表示させるコンテンツを文書毎にもつJSONのフィールドから一度パースして表示させています。 中々軽量でいいと思います。
    2. XPagesに標準で実装されているランタイムライブラリ、com.ibm.commons.util.io.json を使う。これはほぼJavaよりのソリューションになりますが、JsonJavaFactory、JsonParser、Iterator 等を使いパースしていきます。 より高度なJSONデータを扱う必要がある場合には適していると思います。例はこちら
    3. fromJson() 関数を使う。なんとXPagesには標準でfromJson() 関数なるものが存在していました。 これを使えば簡単にSSJSでJSONをあつかえるようになります。

    今回は(3)のfromJson() 関数の扱い方について書いてみます。

    Domino Designerのヘルプに乗ってない !?

    まずこの関数ですが、Domino Designer (バージョン9時点)のヘルプに載ってません。 もう一つJson形式のObjectを文字列に変えるtoJson() 関数も用意されていますが、どちらも載っていません。

    Domino DesignerのSSJSの補完機能を見る限り、

    fromJson(str:string) any

     となり、 strのパラメーターにJSONフォーマットに則した文字列を渡してやると、Javascript Object形式で値が帰ってきます。

    Objectから以下のように値を参照できます。

    var strJsonSimple:String = '{"name":"apple","color":"red","num":"10"}';
    var jsonObjSimple = fromJson(strJsonSimple);
    return jsonObjSimple.name;

    しかし、この場合(青文字の部分)はObjectに"name"という変数(属性?)があるということを前提にプログラミングされています。

    実際は、JSON文字列がObjectになった後、変数もその値もわからないこともあると思います。

    その場合、Javascriptでfor-in文による繰り返しで回してやれば値の取得が可能になります。

    例として、冒頭で上げたJSONをXPagesでパースして表示しているサンプルを掲載します。 Objectに配列を持つという組み合わされた構造のJSONを以下のようにパースしています。

    var strRet:String = "";
    var strJson:String = '[{"勇者": ["隼の剣","光の鎧"]},{"格闘家": ["鉄の爪"]},{"魔法使い": ["いかづちの杖","水の羽衣"]}]';
    var jsonObj = fromJson(strJson);
    
    for(var char_num in jsonObj){
    
    	var charEntry = jsonObj[char_num];
    	for(var char_name in charEntry){
    		strRet += "キャラクター"+char_num+": "+ char_name +"
    ";
    
    	    var charEquipment = charEntry[char_name];
    	    var equipments = @Explode(charEquipment, ",");
    		for (var k = 0; k < equipments.length; k++){
    			strRet += "  装備"+(k+1)+" = "+equipments[k]+"
    ";
    		}
    
    	}
    }
    return strRet;

    計算結果フィールドに入れた結果はこんな感じです。

     fromJson


    [XPages] クライアントJavascriptにサーバー側の値を埋め込む方法

    前回の続き

    前回、Radio Button Groupコントロールで生成されるラジオボタンの値をクライアントJavascriptで取得する方法を説明しました。(記事はこちら) その時に、

    var chkRadioMember = dojo.query("input[name$='#{id:radioGroupMember}']");

     というように#{id:hogehoge} というクライアントJavascriptではなさそうなソースコードが出てきました。

    前回のブログでは、この#{id:hogehoge}というフォーマットで記述されたコードはHTMLがブラウザに表示される前にサーバー側で ’view:_id1:radioGroupMember‘ といった値に動的に変換されることになっています、と解説しました。

    今回は、この#{id:hogehoge} の意味を紐解くと共に、ちょっとディープに利用方法を探ってみようと思います。

     

    実は知らない間に使っていた #{} のフォーマット

    #{} の形を色々と探してみると、XPagesでは以下のようなパターンが他にも存在するのを確認できました。

    #{document1.Firstname}
    #{view1}
    #{javascript:sessionScope.myName}
    #{id:firstname1}

    XPagesのソースを覗いた事がある方だったらどれも見た覚えがあるかと思います。

    それぞれ役割が違っていて、

    #{document1.Firstname}  ← Dominoドキュメントをバインドして、フィールドを表示させた時
    #{view1} ← バインドさせたDominoビューを利用する
    #{javascript:sessionScope.myName} ← SSJSで計算をさせたい時
    #{id:firstname1} ← XPagesのIDからCSJS用のIDに変換した値を取り出したい時
    

    というような用途で使いわけていきます。

    もしかしたら、データソースをバインドするような形式はドキュメントやビュー以外にもあるかもしれません。自分の環境では以下のようなデータソースが選択できましたがDocumentとView以外は試していません(汗)
    data-source-binding

     

    CSJSで使える#{} のフォーマット

    #{} はなにかしらサーバーサイドで計算させたい時に利用するものだということは分かったと思います。

    ここでは、どれがCSJSのソースコード中に埋め込む形で使えて、どれが使えないか検証してみました。

    試したコードは以下の種類です。

     <xp:this.script>
      <![CDATA[
        alert("[SSJS]sessionScope.myName は #{javascript:sessionScope.myName}"); ← 動いた
        alert("[SSJS]document1.Firstname は #{javascript:document1.getItemValueString("Firstname")}"); ← 動いた
        alert("[CSJS]firstname1 は "+dojo.byId("#{id:firstname1}").value); ← 動いた
        alert("[SSJS]document1.Firstname は #{document1.Firstname}"); ← エラーになった
      ]]>
    </xp:this.script>

    という具合で、#{document1.Firstname} というようなバインドしてあるDominoドキュメントのFirstnameのフィールドを取得する、という記述はCSJSで使えませんでした。

    しかし、#{javascript:document1.getItemValueString("Firstname")} を利用すると同じ値が取得できているのがわかると思います。

    結論として、CSJSでは

    #{id:hogehoge}

    #{javascript:hogehoge}

    の2つが使えるという結果になりました。

     

    実際、自分がXPagesを見てきて、CSJSに利用されているのは#{id:hogehoge} の記述ばかりです。

    #{javascript:hogehoge} もほとんど見ないです。(というか、実際この検証をするまで使えることを知りませんでした)

    使えるけど、ソースがグチャグチャになってしまうのでCSJSとSSJSを混ぜこぜで使うのは全くオススメできません。

    もしその必要性が出てきてしまったら設計から見なおしたほうがいいのかもしれませんね...


    XPages 開発事例 紹介1

    弊社提案のソリューションがIBMお客様導入事例として紹介されました

    XPagesとXWork Serverを使った新しいWEBアプリの開発・提案

    XPages 開発事例 紹介1弊社、ケートリック LLC と ドリームネットデザイン株式会社様でお客様に提案したソリューションがIBM お客様導入事例として紹介されました。

    導入事例はこちら → IBM お客様導入事例 - ジャンボフェリー株式会社

     

    特徴

    Notes/Domino、XPagesの技術とWEBアプリケーションに特化したXWork Serverライセンスを利用して低価格でより信頼あるシステムを構築しています。

    社内で利用するグループウェアとしてのNotes/Dominoではなく、XPagesの技術を利用して一般向けに公開されたWEBアプリを作ってしまおうというところが特徴的なところになります。

    また、XPagesがモダンなWEBアプリを作成するのに十分な機能を発揮し、OpenNTFに公開されているテンプレートを上手く使うことでより質の高いWEBアプリを短期間で作ることができた事例でもあると思います。

     

    抜粋

    以下、事例で取り上げて頂いている内容の抜粋になります。

    [blockquote] 「入力フォームのデザインを変えたい、乗船予約のオプションを増やしたいなど、開発途中にもどんどん生まれるお客様のアイデアに柔軟に対応できなくてはなりません。その点、IBM Notes/Dominoはアプリケーションの構造からしてほかのWebシステムとは異なります。すでに動いているシステムを止めることなく、機能追加や修正をPCのローカルで行ってテストし、即座にサーバーのシステムに反映できるのが理想です。そんなプロトタイピングを繰り返しながらシステムを完成させていくRAD(Rapid Application Development)開発を体現し、将来的な改善や拡張にもスムーズに対応できるという観点から、XPagesを使うことを提案しました」と田付氏は説明します。[/blockquote]

     

    [blockquote] 予約サイトのユーザビリティーを向上
    システムの開発プロセスにおいても、XPagesが多くのメリットをもたらしました。
    一例として田付氏が挙げるのが、セッション情報の保存機能です。予約システムを利用するお客様は、まず基本情報を入力し、次に予約内容を確認し、最後に確定するといった流れで操作します。Webアプリケーションは一般的に複数ページから構成されており、一連のやりとり(セッション)の情報を維持しながら処理が進みます。すなわち、遷移していくページ間で、確実にデータが引き継がれなければなりません。
    「XPagesはセッション管理を簡単な操作で実現できる機能を標準でサポートしており、開発のリードタイム短縮や品質向上に大きな貢献を果たしています」と田付氏。[/blockquote]

     

    [blockquote] またお客様に向けて、より快適なWebページを提供するという観点から、竹内氏はこのように話します。
    「特にハイシーズンには、お客様がWebページをご覧になっている最中にどんどん予約状況が変わります。最新の状況がどうなっているのか、いちいちページをリロードしなければならないのでは不便です。そこで、今回構築したシステムでは、予約状況の表示部分のみをリアルタイムに更新していく仕組みを取り入れました。こうした快適なWebページを提供できたことも、XPagesを活用したからこその成果です」。[/blockquote]

     

    [blockquote]XPagesは、特定領域のアップデートの指示をボタン一つで設定できるため、例えばその部分だけでも100行を超えるプログラミングの工数を省力化できます。単純な比較はできないと前置きをしつつも、田付氏は「他のプログラム言語を使用した場合と比較して、全体の開発工数は3分の1程度で済んだのではないか」と明かします。[/blockquote]

     

    謝辞

    今回のお客様導入事例を作成するにあたり、ご協力下さいました全ての方々にお礼申し上げます。 本当にありがとうございました。

     

    XPagesDay2013で使用した事例紹介のプレゼン資料


    XPagesDay 2013 【C-3】予約システムをXPagesで構築した提案事例のスライドとコードの公開

    XPagesDay 2013が無事に終わりましたね。

    参加された皆様、講師の皆様、そして運営の皆様、本当にお疲れ様でした。

    やはり、自分のプレゼンはかなり緊張していたようです。
    自宅で行ったリハでは「え~っと」の回数を30回以下まで減らすことができたんですが、本番はゆうに50回は超えていたようです。

    お聞き苦しく感じてしまった方すいません、次プレゼンをする機会があればその時はがんばります (^_^;)

    XPagesDayでの自分のプレゼンテーションのスライドをアップしました。

     

    リンク先はこちら:http://www.slideshare.net/KazunoriTatsuki/c3-xpages

     

    また、スライドの中で利用したDojo GridViewのXPagesコードを以下に貼り付けておきます。

    [toggle title="Dojo GridViewのXPagesコードを表示するにはここをクリック"]

    
    <?xml version="1.0" encoding="UTF-8"?>
    <xp:view xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    xmlns:xc="http://www.ibm.com/xsp/custom"> <xp:div id="div_Schedule_depart"
    styleClass="gridbox">
    <xe:restService
    id="restServiceDepartSche">
    <xe:this.service>
    <xe:viewJsonService
    viewName="[YOUR_VIEW_HERE]" defaultColumns="true"
    contentType="application/json" var="entry"
    formName="[YOUR_FORM_HERE]">
    <xe:this.columns>
    <xe:restViewColumn
    name="DSResvStat">
    <xp:this.value><![CDATA[#{javascript:""; /*予約状況の計算プログラムが入ります*/ }]]></xp:this.value>
    </xe:restViewColumn>
    </xe:this.columns>
    <xe:this.keys><![CDATA[#{javascript:""; /*Viewの絞込のキーワードを返すようにします*/ }]]></xe:this.keys>
    </xe:viewJsonService>
    </xe:this.service>
    </xe:restService>
    <xe:djxDataGrid id="djxDataGridDepart"
    style="width: 100%;height: auto; padding: 1px"
    storeComponentId="restServiceDepartSche" selectionMode="single"
    selectable="false" loadingMessage="検索しています" autoHeight="5"
    jsId="jsDataGridDepart"> <xe:djxDataGridColumn
    id="djxDataGridColumn1" label="ラベル1" field="DSName">
    </xe:djxDataGridColumn>
    <xe:djxDataGridColumn
    id="djxDataGridColumn2" label="ラベル2" field="DSDepartCity"
    width="50px">
    </xe:djxDataGridColumn>
    <xe:djxDataGridColumn
    id="djxDataGridColumn3" label="ラベル3" field="DSDepartTimeStr">
    </xe:djxDataGridColumn>
    <xe:djxDataGridColumn
    id="djxDataGridColumn4" label="ラベル4" field="DSArriveCity"
    width="50px">
    </xe:djxDataGridColumn>
    <xe:djxDataGridColumn
    id="djxDataGridColumn5" label="ラベル5" field="DSArriveTimeStr"
    width="50px">
    </xe:djxDataGridColumn>
    <xe:djxDataGridColumn
    id="djxDataGridColumn11" label="ラベル6" field="DSResvStat" width="auto">
    </xe:djxDataGridColumn>
    </xe:djxDataGrid>
    <xp:scriptBlock id="scriptBlock1">
    <xp:this.value><![CDATA[XSP.addOnLoad(function(){
    dojo.connect(dijit.byId("#{id:djxDataGridDepart}"), "_onFetchComplete",function()
    {
    // 画面遷移先から戻ってきた時に以前に選択された値を選択状態にしておくためのCSJS
    var selUnid = dojo.byId('#{id:scheDepartDSUnid}');
    var grid = dijit.byId("#{id:djxDataGridDepart}");
    if( selUnid && selUnid.value != ""){
    for (var i = 0; i < grid.rowCount; i++){
    theitem = grid.getItem(i);
    dojo.forEach(grid.store.getAttributes(theitem), function(attr){
    if(attr == '@unid'){
    var value = grid.store.getValues(theitem, attr);
    if( value == selUnid.value){
    grid.selection.setSelected(i,true);
    }
    }
    });
    }
    }
    grid.canSort = function(){return false};
    }); });]]></xp:this.value>
    </xp:scriptBlock>
    </xp:div> <!-- GridViewで選択された行のUNIDを格納する隠しフィールド -->
    <xp:inputText id="scheDepartDSUnid" style="display:none;"
    value="#{sessionScope.scheDepartDSUnid}">
    </xp:inputText>

    <!-- 次へ進むボタンを押下時にGridViewで選択された行のUNIDを取得して隠しフィールドに保存 -->
    <xp:div styleClass="enter">
    <xp:link escape="true" id="link2">
    <xp:image id="image15" url="/button-next.gif"
    alt="次へ進む">
    </xp:image>
    <xp:eventHandler event="onclick" submit="true"
    immediate="false" save="true">
    <xp:this.script><![CDATA[var grid = dijit.byId('#{id:djxDataGridDepart}');
    var bSelDept = false;
    var bSelDeptOF = false;
    var items = grid.selection.getSelected();
    if(items.length) {
    dojo.forEach(items, function(selectedItem) {
    if(selectedItem!==null) {
    dojo.forEach(grid.store.getAttributes(selectedItem), function(attribute){
    var value = grid.store.getValues(selectedItem, attribute);
    // alert('attribute: ' + attribute + ', value: ' + value);
    if(attribute == '@unid'){
    dojo.byId('#{id:scheDepartDSUnid}').value = value;
    bSelDept = true;
    }
    if(attribute == 'DSResvStat' && value == 'X'){
    bSelDeptOF = true;
    }
    });
    }
    });
    }

    ]]></xp:this.script>
    </xp:eventHandler>

    </xp:link>
    </xp:div>

    </xp:view>

    [/toggle]