いいね!数

1

閲覧数
558
こんにちは、

viewPanelの中のviewColumnで"showCheckbox"をtrueにすると、各行にチェックボックスが表示されると思います。

そしてチェックされた値は以下のようにして取得できるようなのですが、


var viewcontrol = getComponent("viewPanel1");
var ids = viewcontrol.getSelectedIds();


getSelectedIds()は基本的に文書IDの配列を返す仕様になっているようです。

ここで、getSelectedIds()を使って文書IDの代わりにカスタム値を返すようにすることは出来ないでしょうか?

もしくはチェックされたチェックボックスに対応する各行のカスタム値をうまく取得する方法はないでしょうか?

<xp:viewColumn id="viewColumn1" showCheckbox="true">
<xp:this.facets>
<xp:viewColumnHeader xp:key="header"
id="viewColumnHeader1" showCheckbox="true">
</xp:viewColumnHeader>
</xp:this.facets>
<xp:this.value><![CDATA[#{javascript:"aaa|bbb"}]]></xp:this.value>
</xp:viewColumn>

とかすると行けないかとおもい試してみたのですがうまく行きませんでした。

出来たらSSJSで対応したいと考えています。


getSelectedIds()関数自体はXPagesが生成するチェックボックス INPUTフィールドのvalueの値を返しているだけのようなので、
このvalueの値を変更出来たら完璧なのですが・・・

サーバー情報: | クライアント情報: | 
カテゴリ:アプリ開発 - XPages | タグ:
  | 質問日時:Apr 2, 2014, 4:22:08 PM

回答・コメント

いいね!数

1

こんばんは。

私もいろいろ試してみたのですが、viewPanel(ビューコントロール)の中の viewColumn(ビューの列)が持っているチェックボックスの挙動をカスタマイズするのは難しいように思います。試しにクライアントサイド JavaScript で viewColumn のチェックボックス INPUT フィールドの value 値を無理やり変更してみたのですが、無理やり値を変更したチェックボックスのある行は選択しても選択したと認識されず、getSelectedIds() 関数の戻り値に含まれなくなってしまいました。

 

もし、getSelectedIds() 関数の戻り値の NoteID 配列に対してループをまわして Notes 文書をそれぞれ取得し値を再計算する、という重い処理を避けたいという意図でしたら、例えば viewPanel の viewColumn の計算時に、行を選択したときに戻して欲しい値をあらかじめ計算しておき、セッションスコープなどに保持しておくというのはいかがでしょうか?

以下コード例です。まず beforePageLoad などのイベントで、セッションスコープに checkboxValueMap という値保持用のオブジェクトを作っておきます。(すでにある場合は再利用)


    <xp:this.beforePageLoad>
        <![CDATA[#{javascript:sessionScope.checkboxValueMap = sessionScope.checkboxValueMap || {};}]]>
    </xp:this.beforePageLoad>
 

次に、viewPanel のチェックボックスのある viewColumn の value の計算時に、行を選択したときに戻して欲しい値を計算し、セッションスコープの checkboxValueMap に NoteID と紐付けて保存しておきます。この例では LastName 列と FirstName 列の値を元に FullName 値を計算して保持しています。(またこの例では、チェックボックスの viewColumn には何も値を表示しないようにするために、最後に return で空文字を返しています。)


    <xp:viewPanel rows="30" id="viewPanel1" showColumnHeader="true" var="viewEntry">
        <xp:viewColumn id="viewColumn1" showCheckbox="true">
            <xp:this.facets>
                <xp:viewColumnHeader xp:key="header"
                    id="viewColumnHeader1" showCheckbox="true">
                </xp:viewColumnHeader>
            </xp:this.facets>
            <xp:this.value><![CDATA[#{javascript:var noteId = viewEntry.getNoteID();
sessionScope.checkboxValueMap[noteId] = viewEntry.getColumnValue("LastName") + " " + viewEntry.getColumnValue("FirstName");
return "";
}]]></xp:this.value>
        </xp:viewColumn>
 

そして最後に、ボタンなどを押した際などの eventHandler の中で、getSelectedIds() 関数の戻り値の NoteID 配列からループをまわすのですが、NoteID を元に文書を取得して、、、という処理をおこなう代わりに、セッションスコープの checkboxValueMap からあらかじめ計算しておいた値を取得するようにします。(ここでは print() で値をコンソールに出力しているだけです)


    <xp:button value="Submit" id="button1">
        <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
            <xp:this.action><![CDATA[#{javascript:var ids = getComponent("viewPanel1").getSelectedIds();
for(var i=0; i<ids.length; i++){
    print(ids[i] + ": " + sessionScope.checkboxValueMap[ids[i]]);
}
}]]></xp:this.action>
        </xp:eventHandler>
    </xp:button>
 

こうすることで、getSelectedIds() の戻り値の NoteID を元に getDocumentByID() をしてそれぞれ Notes 文書を取得して値を計算しなおす、という処理は不要になるので、少し処理は軽くおさえることができるかもしれません。(メモリ消費は若干増えますが)

回答日時:Apr 3, 2014, 11:48:03 AM

いいね!数

0

onoat さん、ありがとうございます!

Mapを使うことでスマートに解決することができました!

実は、ややこしくなると思い触れなかったのですが、今回のViewPanelではRDBへアクセスして、引っ張ってきたレコードを表示させていました。すると、そもそもノーツ文書ではないため、NoteIDの部分が只の行番号(0スタート)になってしまい、getSelectedIds() でもその行番号を返すのみでした。そこで今回のような対応がどうしても必要であった、という経緯になります。

されに、もうちょっと掘り下げると、

このRDB レコードを表示させたViewPanelの場合、クライアントサイド JavaScript で viewColumn のチェックボックス INPUT フィールドの value 値を無理やり変更したら、その変更は反映され、getSelectedIds() でも取得が可能という、onoat さんのテスト頂いたものとは違うという面白い動作になりました。

そこで、試しに以下のように、

                <xp:viewColumn id="viewColumn7" style="width:14px"
                    showCheckbox="true">
                    <xp:this.facets>
                        <xp:viewColumnHeader xp:key="header"
                            id="viewColumnHeader7" showCheckbox="true">
                        </xp:viewColumnHeader>
                    </xp:this.facets>
                    <xp:text id="pkey" styleClass="pkey" style="display:none;">
                        <xp:this.value><![CDATA[#{javascript:viewEntry.getColumnValue("pkey")}]]></xp:this.value>
                    </xp:text>

                </xp:viewColumn>

viewColumnに隠しタグを用意して、以下のCSJSで

  
    <xp:scriptBlock id="custom_js">
        <xp:this.value><![CDATA[
dojo.addOnLoad(function(){
    dojo.require("dojo.NodeList-traverse");
       var chkObjs = dojo.query('input.xspCheckBoxViewColumn');
       dojo.forEach(chkObjs, function(entry, i){
           var pkey = dojo.query(entry).siblings(".pkey");
           entry.value = pkey[0].innerHTML;
       });
});
        ]]></xp:this.value>
    </xp:scriptBlock>

とし、全てのチェックボックスのValueを無理やり書き換えてやるとgetSelectedIds() が変更された値を返してきました。

ただ、やはりSSJSで処理をさせたかったのと、上記のCSJSはDomino 9のDojo 1.7以上の環境では動かないため、onoat の方に変更するようにしました。

余談なんですが、

sessionScope.checkboxValueMap = sessionScope.checkboxValueMap || {};

で変数定義、あれば再利用、という書式になるんですね!?便利すぎです! 変数がnull の場合、"真" でないため、論理演算子 "||" のもう片方を見に行く・・う~ん? この書式を解説しているサイトとかありますか?

 

回答日時:Apr 3, 2014, 3:23:01 PM

いいね!数

0

なるほど、データソースは RDB だったのですね。 Notes ビューをデータソースとしているものだと思い込んでいたのですが、RDB がデータソースの場合は勝手が違うかもしれません。もしかしたら改造の余地もあるかもしれませんので、なにか分かったら追加でコメントさせていただきます。

 

|| を使った初期化の書き方は JavaScript でよく目にする書き方で、dojo のソースの中でもいろいろなところで使われています。解説サイトはあまり見つけられなかったのですが、以下のブログ記事が分かりやすく解説してくれていました。

http://blog.kyosuke.jp/2008/07/07/57

回答日時:Apr 3, 2014, 4:12:04 PM

いいね!数

0

|| を使った初期化、URLありがとうございます。大変よく分かりました。これから使う機会が増えそうです。

左側の式がtrueの場合は左側の式をそのまま返す

という動作だったのを、

左側の式がtrueか調べる

という理解で止まっていました。まだまだこのレベルのことを学ぶことがあるとは、、、日々お勉強です。。。 ありがとうございました。

 

 

回答日時:Apr 3, 2014, 4:40:43 PM