Takenoff Labs

Lotus Notes/Domino に関する Tips や、クラシックの名曲などを紹介します

[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 フラグをオフにしてください。(ビューには表示されなくなりますが。)

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
読み込み中...

トラックバック

トラックバックはありません

コメント

おぉ! 更新されていますね!
相変わらずの素晴らしい記事でございますね。色々と勉強になります。
11月からお仕事決定のようで、おめでございます。
Notesからまた一人いないくなりました (泣

サイトウさん、コメントありがとうございます! 😀

記事書いてみたものの、あまりの反響のなさに凹んでいたところです(^^;
アクセス数なんて1桁ですし(涙
もうアクティブな Notes 開発者って、ほとんどいないんですかね……。

あと何本か記事を書く予定ではいますので、よろしければ引き続きご笑覧くださいませ 😆

※コメントは承認制となっております。管理者が承認するまで表示されません。申し訳ありませんが、投稿が表示されるまでしばらくお待ちください。





(以下のタグが使えます)
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

For spam filtering purposes, please copy the number 2681 to the field below:

^
×