これまで4つのNamePickerを見てきました。

(1) codestore Jake Howlett(1)

(2) OpenNTF Jeff Crossett

(3) codestore Jake Howlett(2)

(4) OpenNTF Steve McDoagh


複数のノーツDBで、これらを使うことを想定して、この機能を文書ライブラリDBのレビューア(ReviewerList)に組み込んでみました。

目標動作は、次のとおりです。

・ノーツユーザ名の姓または名の最初の3文字を入力

・公開アドレス帳で該当ユーザを検索、

・ヒットした候補リストをブラウザ表示、

・候補リストから一人をクリックで選択、

・その人のフルネームをレビュー担当者フィールドにセット


ユーザの利便性、コードの保守性を考えると、おすすめは、「(2) OpenNTF Jeff Crossett」です。

文書ライブラリに移植しフルネームで候補リストを表示した画面を下に示します。



a Lotus Notes 開発者 ブログ-namepick画面


「(2) OpenNTF Jeff Crossett」は、プログラムコードが短く、分析・改造が相対的にもっとも容易で、コード(22K)のダウンロードにも時間がかかりません。


「(4) OpenNTF Steve McDoagh」は、機能的に優れていますが、yahooのライブラリが重くコード(190K)のダウンロードに時間がかかります。 ブラウザを起動して、NamePicker機能を使うアプリケーションフォームを最初に開くとき待たされます。 基盤環境変化時の対応も難しくなりそうです。dominoでは、dojoのライブラリ使用が今後増えていくと思われるのでdojoとの競合が心配です。サーバエージェントの負荷も考慮しなければなりません。


「(3) codestore Jake Howlett(2)」は、コードがコンパクト(17K)ですが、難しい。なお、Domino6..Domino7用には、レスポンスを処理するプログラムの追加作成が必要です。


「(1) codestore Jake Howlett(1)」は、コードが78K。 コードはコンパクトですが、ボタンクリックで入力ウィンドウを開くことになり、利用ユーザは手間がひとつ多くなります。



移植は、次のパターンで実施しました。

1.コード管理用のノーツDBを用意し、そこにJavaScriptライブイラリ、CSSを配置

複数のNamepickerから共通して使用し、また、環境変化によって変更が必要となる可能性があるためです。

 (イメージファイルは、変更可能性が小さいので利用DB側に配置)

 例: (1)の場合

  namepick15.nsf(例)に、lib/prototype.js、util/scriptaculous.js、css/NamePick.css、js/NamePicker.jsを配置

2.利用DB側のフォームのHTML HEAD CONTENTにライブラリ、CSSを指定してロード

 例:(1)の場合

  "<script language=\"JavaScript\" type=\"text/javascript\"   src=\"/namepick15.nsf/lib/prototype.js\"></script>" + @NewLine +
  "<script language=\"JavaScript\" type=\"text/javascript\" src=\"/namepick15.nsf/util/scriptaculous.js\"></script>" + @NewLine +
  "<style type=\"text/css\" media=\"all\">@import \"/namepick15.nsf/css/NamePick.css\";</style>" + @NewLine +
  "<script language=\"JavaScript\" type=\"text/javascript\" src=\"/namepick15.nsf/js/NamePicker.js\"></script>"


3.フォームのonLoadでinit プログラムが実行されるように指定

 (JSライブラリのonLoadプログラムと競合して、これで動かない場合は、フォーム最下部に

 パススルーHTMLで<script>エレメントで記述)

 例:(1)の場合

   サブフォーム化されていたNamePickerのdiv、NamePicker.init をフォーム最下部に記述


4.レビュー担当者フィールドのID名をプログラムから利用可能なものに設定または、initでフィールド名指定

 例:(1)の場合

   ReviewerListフィールドのIDに、ReviewerList を指定

   ReviewerListフィールドの下に、候補リスト表示用の<div id="NamesList">を追加


 *利用側DBでのフォーム変更は、(1)が一番複雑で、他は、もっとシンプルです。


5.目標動作に合わせて、コードの一部を変更

  リクエストを送るDB, ビュー名の変更

  リクエストを送る条件を3文字以上に変更

  利用しない項目がレスポンスで戻らないように、使用ビュー、(4)のサーバーエージェントを変更

  readViewEntriesの結果の第二列を候補リストに表示するように変更



コード変更は、ロジカルな問題として対応可能ですが、環境により現れ方が異なる次の問題はやっかいです。

が、多数のDBでNamePickerを使うとなると、すぐに、あるいは、将来的に問題化する可能性があります。


(1) onLoad が動かない = JavaScriptライブラリ問題


今回、利用側DBにした文書ライブラリでは、名前入力フィールドの下方にリッチテキストフィールドがあります。

これが原因で、まず、onLoadのプログラムが動かない問題が発生しました。


HTMLのソースを見ると、プログラムした覚えのないdojoのスクリプトライブラリがロードされ、dojo.addOnLoadが動き、プログラムしたbodyのonLoadが動いていない。

(Domino8.5.では、リッチテキストフィールドがあると、自動的にJavaScriptライブラリのdojo、dojoのリッチテキスト入力モジュールがロードされます(ただし、Vista, IEでは、OS提供のモジュールが優先使用))


  HTMLの解析後に動くdojo.addOnLoadは、HTML <body>のonLoadを無効化する。

  dojo以外のJavaScriptライブラリにも、HTMLの解析後に動くプログラムがありえて、それが複数種のライブラリ共存に問題をおこすことがありうるとのことです。



 このため、onLoadプログラムは、フォーム下部での<script>エレメントに記述して回避しました。


(2) 候補リストがリッチテキストの裏に隠れる = OSの制御するアプレットはHTML要素の上じ表示される

 

これを回避するには、OSにより制御されるiFrameを用いるiFrame Sim という技法があります。 

動的に表示したい候補リストのdivと同じ位置、大きさをもつiFrameエレメントを作成し、候補リストdivz-Index1000などにして、iFrameエレメントz-Indexをそれより1小さくするというような手法です。




ブラウザ、OS、Javascriptコード、ノーツ設計リッチテキストフィールドのWEBアクセス時の表示設定の組み合わせによってこの問題が発生するしないが決まります。


Vista IE8 Domino8.5の場合、リッチテキストフィールドのWEBアクセス時の表示をJavaアプレットにしなければ、裏に隠れることなく表示されましたが、Vista FireFox3.0.15 では、裏に隠れます。


今回のNamePickerプログラムでは「(2) OpenNTF Jeff Crossett」が、iFrame Sim を組み込み済みです。FireFox3.0.15でも候補リストがリッチテキストの上に表示されます。 (1)(3)(4)は、利用環境によっては、iFrame Sim を追加で組み込む必要があります。


なお、同じURLリクエストを繰り返さないというキャッシュ機能面でも、(2) OpenNTF Jeff Crossettは問題ありません。


ユーザの利便性だけでなく、ネットワークに与える負荷から見ても、タイプアヘッドによるユーザ選択入力は優れているのではないでしょうか。



Project: AJAX Name Picker (Managed by Steve McDonagh)


"A JavaScript API that allows the developer to add NAB Name Picker Functionality to their forms "の提供を目標として、2007年11月のV1.0.0から2008年8月のV1.2.6まで改良・強化が続いたものです。



a Lotus Notes 開発者 ブログ-OpenNtfNPick

<動作>

1.2. 3文字以上の入力で次へ

3. リクエストURLに、?ReadViewEntriesでなく、?OpenAgentを使用しているのが特徴。ユーザ入力を引数に追加


 url = NP_url+"/NP_getNameLS?openagent&type=S&name="+fieldobj.value+"&pabs=";

 例NP_getNameLS?openagent&type=S&name="tes"&pabs="names.nsf"


4. URLがYahooのJavaScriptライブラリAjax処理に渡され実行


 var request=YAHOO.util.Connect.asyncRequest('GET', url, NP_callBack)


5.6. NP_getNameLSエージェントはHTTPリクエストのUL引数Query_String_DeCoded(0)またはPOSTの内容Request_Content(0)、を使い、LotusScript のGetAllDocumentsByKey処理によりNABの"($users)"ビューを検索


6.8. 結果をJavascriptコード(結果を追加するコードと結果データ)に整形


9.10. コールバック関数NP_callBackが戻りをevalして、配列NP_namesにpushしリスト表示



<DBへの適用>

 ノーツの標準テンプレートをもとに文書ライブラリDBを作成し、そのレビュー担当者が選択入力できるようにDBに適用してみました。



実行環境: Domino8.5、IE8、FireFox3.0.15 


適用手順:

(1) JavaScriptライブラリ5個、CSSファイル1個をdomino\htmlフォルダ以下に配置

(2) 入力フォーム(Document)のHTML HEADERで、それがロードされるように指定

(3) 入力フォームの onLoad に NP_createPopup();を追加

(4) 入力フォームの名前フィールド(ReviewerList)の onFocusに、次のコードを追加  

  NP_openPopup(this.id,"",this.name,'S',"");blur(); 

  (複数選択フィールドですが、まず’一人選択の'S'で確認

(5) NP_getNameLSエージェント、イメージファイル2個を移行先DBにコピー配置



a Lotus Notes 開発者 ブログ-文書ライブラリ


結果:

FireFox3.0.15 では、候補リストの下部が、リッチテキストフィールドの裏に隠れる問題が発生しました。

リッチテキストフィールドのプロパティ WEBアクセス時の表示を、デフォルトの「OSに合う位置を使用」から「JavaScriptコントロールを使用」に変えてみたら、裏に隠れる問題は回避されましたが、

さてこれを標準のNamePickerとして多数のDBに展開できるか、続けて見ていきたいと思います。


NamePicker は、ふたつの方向で工夫改善が進められます。

ひとつは、TypeAhead一般技術の改善の取り込み(フローの2,4,9,10,13)と、もうひとつは、Notes固有の改善(フローの3,6,7)です。


Jake Howlett氏のSimple, Yet Effective Tip - Type-Ahead Lookups Based on Any Word では、

  (1) より新しいTypeAhead技術 BrandSpaklingNewAjax Auto Suggest v.2 の採用

  (2) 「7.」検索対象のビュー変更による姓名検索の改善、[3,6」ReadViewEntriesでのJson使用を見ることができます。


デモサイトは、Any Word Match Typeahead  です。

車名入力でのタイプアヘッドですが、姓でも名でも検索でき、より実用的です。




a Lotus Notes 開発者 ブログ-AnyWordMatch図



このサンプルは、Domino8から追加された、?ReadViewEntriesのパラメータ「&Outputformat=JSON」を使用しています。
前に見たXML形式と異なり、ビューはJavaScript Object Notation (Json形式)で返されます。