[Notes/Domino] 行数可変の入力フォームを作る
従来の Notes 開発になく、XPages にある便利なコントロールといえば、繰り返しコントロール(or データ表コントロール)がまず挙げられるかと思います。行数可変の表を作る場合、非表示式や行数分のフィールドを作る必要がなくなったのは、感涙ものですね。(まあ、今までが不便すぎたのかもしれませんが(^^;)
ただ、繰り返しコントロール内で、入力用の子コントロールを作る場合、バインドをどうやってするのか、ちょっとわかりづらいかと思います。
実現方法はいくつかあると思いますが、ここでは前回の Tips を応用した方法をご紹介します。以下は実際に動作するサンプルです。
(ここではデータ表コントロールを使用していますが、繰り返しコントロールでも基本は同じです。)
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core"> <xp:this.data> <xp:dominoDocument var="document1" formName="test"> </xp:dominoDocument> </xp:this.data> <xp:comboBox id="comboBox1" value="#{document1.No}" defaultValue="1"> <xp:selectItems> <xp:this.value><![CDATA[ #{javascript:var ary = []; for (var i = 1; i <= 30; i++) { ary.push(i.toString()); } return ary;}]]></xp:this.value> </xp:selectItems> <xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="dataTable1" disableValidators="true"> </xp:eventHandler> </xp:comboBox> <xp:dataTable id="dataTable1" rows="30" first="0" var="fld" style="width:300px"> <xp:this.value><![CDATA[ #{javascript:var no = document1.getItemValueString('No'); no = no === '' ? 1 : parseInt(no, 10); var fldAry = []; for (var i = 1; i <= no; i++) { var obj = {}; obj.Test1 = 'Test1_' + i; obj.Test2 = 'Test2_' + i; fldAry.push(obj); } return fldAry;}]]></xp:this.value> <xp:column id="column1"> <xp:this.facets> <xp:span xp:key="header">テスト1</xp:span> </xp:this.facets> <xp:inputText id="inputText1"> <xp:this.value> <![CDATA[#{document1[fld.Test1]}]]> </xp:this.value> </xp:inputText> </xp:column> <xp:column id="column2"> <xp:this.facets> <xp:span xp:key="header">テスト2</xp:span> </xp:this.facets> <xp:inputText id="inputText2"> <xp:this.value> <![CDATA[#{document1[fld.Test2]}]]> </xp:this.value> </xp:inputText> </xp:column> </xp:dataTable> <xp:button value="保存" id="button1"> <xp:eventHandler event="onclick" submit="true" refreshMode="complete"> <xp:this.action> <xp:saveDocument var="document1"></xp:saveDocument> </xp:this.action> </xp:eventHandler> </xp:button> </xp:view>
これを実行すると、以下のような画面になります。(コンボボックスの値を変更すると、行数が変わります。)
ポイントは赤字の部分で、バインド対象のフィールド名のリストをあらかじめ作っていることです。たとえば、コンボボックスが「3」の値だとすると、以下のようなデータとなります。
[ {Test1: 'Test1_1', Test2: 'Test2_1'}, {Test1: 'Test1_2', Test2: 'Test2_2'}, {Test1: 'Test1_3', Test2: 'Test2_3'} ]
fld 変数には、上記配列内のオブジェクトが順番にセットされますので、青字部分、たとえば「document1[fld.Test1]」は「document1['Test1_1']」、「document1['Test1_2']」、「document1['Test1_3']」が順にセットされることになります。これでバインドができるというわけです。
本当なら、繰り返しコントロールのデータは「['1', '2', '3']」だけにして、「document1['Test1_' + i]」みたいにバインドしたいところですが、これは最新の JSF では可能なものの、XPages ではできません(「+」や「concat」がサポートされていないため)。おそらく、基になった JSF のバージョンが古すぎるためだと思われます。
最新の JSF に比べるとちょっと洗練されていませんが、フィールド名のリストを作る程度の手間であれば、全然アリではないかなと思います。
注意点としては、ストレージはあくまで Notes DB のため、調子にのってフィールドをいっぱい作りすぎると、文書全体の制限値(Summaryフィールドの合計が64KB)にひっかかる場合があるということです。これは従来のフォームの場合と全く同じです。
回避するには、保存時に Summary フラグをオフにしてください。(ビューには表示されなくなりますが。)
コメント
おぉ! 更新されていますね!
相変わらずの素晴らしい記事でございますね。色々と勉強になります。
11月からお仕事決定のようで、おめでございます。
Notesからまた一人いないくなりました (泣
Posted at 2017/10/28 12:12 AM by サイトウ
サイトウさん、コメントありがとうございます! 😀
記事書いてみたものの、あまりの反響のなさに凹んでいたところです(^^;
アクセス数なんて1桁ですし(涙
もうアクティブな Notes 開発者って、ほとんどいないんですかね……。
あと何本か記事を書く予定ではいますので、よろしければ引き続きご笑覧くださいませ 😆
Posted at 2017/10/28 8:45 AM by takenoff
※コメントは承認制となっております。管理者が承認するまで表示されません。申し訳ありませんが、投稿が表示されるまでしばらくお待ちください。