How to set 'date only' or 'time only' values in fields through XPages

XPages always save date and time in a field

When a form has the fields with "date only" or "time only", then the stored data format are different between Notes Client and XPages.

For example, I prepared the field with "date only" named "Date" as following (sorry, screenshots are all Japanese) :

年月日のみをもつフィールド

And also field with "time only" named "Time":

時刻の表示のみをもつフィールド

Now I saved a new document with this form from Notes Client (9.0.1 FP3), then I got following fields' data.

Notesクライアントで日付フィールドを保存

Notesクライアントで日付フィールドを保存

As you see, "Date" field has "2015/03/02", and Time field has"14:35:00"

As the next, I created the simple XPage to save a new document with same form and fields so that I can compare the data between Notes Client and XPages.

XPagesで日付フィールドの保存

Below is the source code for Date field and Time field in XPages.

Date Field

Time Field

Each inputText specify date, time to the Type attribute of convertDateTime.

After saving a new document from this XPage, below is the screenshot of stored field data:

XPagesから保存された文書のDateフィールド

XPagesから保存された文書のTimeフィールド

So both of fields have "yyyy/MM/dd hh:mm:dd ZZ" format.

Why you need to save "date only" or "time only" data from XPages?

I just don't post this blog to argue which format is proper way and why XPages behaves differently.

In the real world, I think you or your customers already have the NSF apps and you may want to improve them as the web application by XPages. In that case, especially you decide to keep using the NSF from both Notes Client and XPages, then I recommend to adjust the field format to Notes Client one instead of XPages one so that all existing documents are supported both Notes Client and XPages without changing data.

Use setAnyTime()、setAnyDate() of NotesDateTime class

Maybe there are a lot of way to achieve what I want below. But one of easy way is using NotesDateTime class of SSJS.

The SSJS above converts the DateTime field format by using setAnyTime()、setAnyDate() in PostSaveDocument event after saving the XSP document .

 


Expand Specific View in XPages

XPages - How to expand a specific category in the view as default

Control Expand/Collapse of the category view

To control Expand/Collapse status of the view in XPages, you just have to use [ExpandLevel] in view data source.
For example, Set "0" to expand, "1" to collapse as default.

Then Is it possible if you want to collapse the view as default except the specific category like below?

Expand Specific View in XPages
Expand Specific View in XPages

Expand only the specific category as default by SSJS

Use the following Serverside Javascript code in afterPageLoad event to expand the specific category.


In the above case, the last line(L4) specifies the first category to expand.

Like this sample code, you can control more if you use SSJS. In this case, I use DominoViewDataModel object. If you are interested in this object, you can see more detail from this link.

You might be able to get more ideas to control view data source directly.


XPagesDay 2014 イベントの申込開始!

XPagesDay 2014

XPagesDayの熱い二日間が今年もやってきます!

2013年も大成功に終わったXPagesDayが今年もやってきました。

今回は全てオンラインセッションとなっているので日本全国どこからでも参加できるイベントになっています。

当日は、自分も若輩ながらセッションを一つ講演させていただきます。

【A-3】「SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門」

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

日時: 
    11 月 18 日(火)、19 日(水)の2日間

場所:
    すべてオンラインのセッション

主催:
    チームスタジオジャパン株式会社

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

詳細、申込みはこちらから » http://www.xpagesday.com/xpagesday.nsf/sessions.xsp

 


2014/10/3、ノーツコンソーシアム 大阪地区研究会にてXPages事例紹介をさせて頂きます。

弊社のソリューションよりNotes/DominoとXPagesを用いたBtoC、BtoB 事例を開発者の方向けにご紹介致します。

当日はご来場の皆様に弊社作成のXPagesサンプルアプリケーションの無料配布を予定しております。

日時: 10月3日(金) 13:00-17:30
場所: IBM大阪事業所

13:00-15:00 研究会メンバーの話 (困っていること、SKILLなど)
15:30-16:30 事例 XPages事例(ケートリック 田付氏)
16:30-17:00 EXCITE Autumn のフィードバック(IBM)
17:00-17:30 次回開催について討議(全員)

【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つとして覚えておいてもらえればと思います。

 

 


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